Граф свойств кода: следующее поколение анализа кода

Эта технология позволяет видеть не только форму кода, но и его поведение: кто кого вызывает, как идут данные и к чему приведёт изменение в конкретном месте системы.

AST + CFG + PDG + DDG 33 аналитических прохода Анализ влияния 11 языков

Что такое граф свойств кода (CPG)

Разбираем технологию без лишнего академического жаргона: что хранится в графе и зачем это нужно на практике

AST — синтаксис

Абстрактное синтаксическое дерево отражает структуру кода: функции, вызовы, переменные, операторы. Это то, что видят SonarQube и Semgrep.

CFG — поток управления

Граф потока управления показывает порядок выполнения инструкций: ветвления, циклы, условия. Без CFG невозможен анализ достижимости.

PDG — зависимости

Граф зависимостей программы связывает данные с управлением: какая переменная от чего зависит, какие инструкции влияют друг на друга.

DDG — потоки данных

Граф зависимостей данных прослеживает, как значения переменных распространяются между инструкциями и функциями — основа для анализа потоков данных.

CPG объединяет все четыре графа в единую структуру. Это позволяет задавать вопросы, которые невозможны на уровне отдельных представлений: «Существует ли путь от пользовательского ввода до SQL-запроса без валидации?»

Почему CPG находит то, что AST пропускает

Сопоставление шаблонов видит форму конструкции. CPG помогает понять, что реально происходит в коде.

AST

Инструменты на основе шаблонов

Что видят Форму конструкции и локальный контекст внутри файла
Что теряют Связи между функциями, файлами и ветками исполнения
Почему ошибаются Не понимают, был ли ввод проверен, очищен и куда реально дошёл
Результат 80-91% ложных срабатываний
CPG

Анализ на основе графа свойств кода

Что видит Полный путь данных от источника до критической операции
Что учитывает Межпроцедурные вызовы, валидацию, санитизацию и приведение типов
Почему точнее Показывает не сигнал, а доказуемую цепочку через несколько файлов
Результат 12% ложных срабатываний

Пример: SQL-инъекция через три функции

Пользовательский ввод проходит через несколько файлов и только в конце попадает в SQL-запрос. На уровне отдельных шаблонов это выглядит безопасно, но граф свойств кода собирает путь целиком.

Источник get_input() Файл A
Передача process() Файл B
Сборка запроса query() Файл C
Критическая точка PQexec() SQL-вызов
AST Видит отдельные вызовы, но не доказывает общую цепочку. Уязвимость легко пропустить.
CPG Строит доказуемый путь get_input() → process() → query() → PQexec() и находит уязвимость за миллисекунды.

Архитектура CodeGraph

Практическая архитектура без тяжёлой JVM-инфраструктуры: нативный Go-бинарник, DuckDB и набор аналитических проходов.

Вход Исходники репозиторий и изменения
Разбор Фронтенд по файлам лексика, синтаксис, типы
Сборка DiffGraph инкрементальные изменения
Аналитика Конвейер проходов DAG из независимых стадий
Хранение DuckDB персистентный результат анализа

Оркестратор

Параллельно распределяет обработку по файлам и контролирует порядок аналитических стадий.

CPGGraph в памяти

Держит рабочее представление графа для быстрых проходов без SQL-запросов на каждом шаге.

Базовые проходы метаданные, файлы, пространства имён
Типы и объявления объявления, наследование, типы возврата
Поток управления CFG, доминаторы, постдоминаторы, CDG
Разрешение вызовов импорты, граф вызовов, связи между файлами
Потоки данных межпроцедурные зависимости и достигающие определения
Структурный поиск метрики, обогащение и 190 YAML-правил
33
аналитических проходов
11
языков программирования
2-3 мс
время запроса
~30 мин
индексация 1M строк

CodeGraph и Joern

Зрелая CPG-платформа без JVM

Критерий Joern CodeGraph
Рантайм JVM (Scala) Нативный Go (без JVM)
Хранилище OverflowDB (in-memory) DuckDB (персистентный)
Языки 6 (C, C++, Java, JS, Python, PHP) 11 (+ Go, TS, Kotlin, C#, 1С)
Инкрементальные обновления Нет (полный перепарсинг) Да (git diff-based, секунды)
Структурный поиск Через Scala DSL YAML-правила (190 готовых)
CI/CD интеграция Ручная настройка Готовые GitHub Actions / GitLab CI
Enterprise (DLP, SIEM, RBAC) Нет Встроено
Производительность Базовая 30-60x быстрее (нативный Go, нет JVM)

Вопросы и ответы

Граф свойств кода нужен там, где AST уже не объясняет поведение системы. CodeGraph объединяет синтаксис, поток управления и зависимости по данным в один граф, поэтому команда видит цепочки вызовов, реальные пути данных и последствия изменений между модулями, а не только локальные совпадения по шаблону.

Граф свойств кода (CPG) — единая структура данных, объединяющая AST (синтаксис), CFG (поток управления), PDG (зависимости по управлению) и DDG (зависимости по данным) в один граф. Это позволяет анализировать код на глубинном уровне: отслеживать потоки данных между функциями, находить уязвимости через анализ потоков данных, выявлять архитектурные зависимости.

AST отражает только синтаксическую структуру кода — «что написано». CPG добавляет два критичных измерения: поток управления (CFG) — «как выполняется», и зависимости по данным (PDG/DDG) — «откуда что зависит». Без этих измерений невозможен межпроцедурный анализ: инструмент не может отследить, что пользовательский ввод из файла A проходит через функцию в файле B и попадает в SQL-запрос в файле C.

Joern — академический CPG-инструмент на JVM (Scala). CodeGraph — зрелое промышленное решение на Go: нативный бинарник без JVM, DuckDB вместо in-memory OverflowDB, 11 языков (против 6), инкрементальные обновления за секунды, 190 YAML-правил для структурного поиска, встроенные корпоративные функции (DLP, SIEM, RBAC). Производительность парсинга в 30-60 раз выше за счёт нативного Go без накладных расходов JVM.

11 языков на промышленном уровне: C, C++, Go, Python, JavaScript, TypeScript, Java, Kotlin, C#, PHP, 1С:Предприятие. Каждый фронтенд генерирует полный CPG с поддержкой межпроцедурного анализа.

Да. GoCPG имеет специальный FFIEdgePass, который детектирует вызовы между языками: Go→C через CGO, Python→C через ctypes/cffi. Это не побочная функция, а целевая фича. Кросс-языковые рёбра позволяют отслеживать потоки данных через языковые границы и находить уязвимости, невидимые для однопроцессных анализаторов.

GoCPG разрабатывался для больших кодовых баз. Архитектура: нативный Go-бинарник (не JVM), DuckDB для хранения (не Neo4j), Appender API для массовой загрузки. 1M строк — ~30 минут, 5M строк — утром запустил, к обеду готово. Joern на таких объёмах работает часами или не справляется вовсе (128GB RAM недостаточно для Linux kernel). Запросы после индексации — 2-3 мс. Инкрементальные обновления — секунды.

SonarQube проверяет как написан код — стиль, признаки плохого кода. CPG анализирует что код делает — потоки данных, граф вызовов, зависимости между модулями. SonarQube не покажет, что изменение в файле A сломает функцию в файле B через цепочку из 5 вызовов. CPG отследит весь путь: от пользовательского ввода через промежуточные функции до SQL-запроса — с файлами и строками.

Нет. CodeGraph не встраивается в каждый коммит как SAST. Индексация — одноразовое действие (~30 мин на 1 млн строк), потом инкрементальные обновления при каждом push занимают секунды. Запросы к графу — 2-3 мс. Пропускная способность — 50+ запросов в секунду, 100+ одновременных пользователей. Это не сканер в конвейере, а база знаний, которая всегда актуальна.

Разборы на Хабре про CPG-платформу

Материалы для архитекторов и техлидов, которые хотят понять технологию до разговора о внедрении.

Почему CPG даёт больше контекста, чем SAST на правилах

Статья про ограничение линейного просмотра кода и преимущества графового подхода хорошо подходит как вводный технический материал перед глубоким демо.

Читать на Хабре

Все статьи автора по теме CodeGraph

Если нужна не одна статья, а вся серия про CPG, онбординг и инженерную аналитику, переходите в профиль автора и читайте материалы подряд.

Открыть серию на Хабре

Получить техническое демо CPG и анализ влияния

Покажем на вашей кодовой базе, как CPG помогает с анализом влияния изменений, зависимостями, архитектурными вопросами и разбором потоков данных.

Обновлено: 7 апреля 2026