Анализ потоков данных помогает ответить на вопрос: как входные данные доходят до операции, которая выполняет SQL, запускает команду или записывает файл? CodeGraph ищет пути в CPG от источника данных к приёмнику и показывает вызовы, места в коде и найденные функции очистки.
Используйте результат при ревью обработки входных данных, аудите безопасности и проверке исправления: пройдите по найденному пути, изучите преобразования данных и сопоставьте их с условиями выполнения приложения.
Выберите способ анализа
| Задача | Способ анализа | Что разбирать |
|---|---|---|
| Получить список замечаний по проекту | Общий аудит с профилем deep_security |
Отчёт нескольких проверок и сведения об их выполнении. |
| Исследовать конкретный метод | MCP-анализ по точному method_name |
Пути через метод, функции источника и приёмника. |
| Проверить обработку входных данных | Ревью найденного пути | Присваивания, вызовы, очистку данных и границы доверия. |
Выполните общий аудит проекта
Установите CLI по руководству. Выполняйте пример в PowerShell из корня репозитория CodeGraph. Нужен доступный сервис GoCPG и актуальный CPG зарегистрированного проекта. CodeGraph использует связь проекта, базы и исходников для проверки свежести. Выберите базу этого проекта и новый файл отчёта:
$env:CODEGRAPH_ALLOW_LOCAL_PYTHON_CLI = '1'
python -m src.cli audit --db 'C:/analysis/project.duckdb' `
--profile deep_security --skip-persistence --skip-llm-conclusion --language ru `
--format json --output 'dataflow-audit.json'
if ($LASTEXITCODE -ne 0) { throw 'Audit failed' }
$report = Get-Content -Raw 'dataflow-audit.json' | ConvertFrom-Json
Отчёт сохраняется в текущем каталоге и перезаписывает одноимённый файл. Проверьте сообщения
о свежести графа и полноте анализа. --skip-persistence отключает сохранение проекций аудита,
снимков панели и истории команд; он не уменьшает область анализа. Сам файл отчёта сохраняется.
--skip-llm-conclusion формирует отчёт без LLM-заключения. Для сводки с LLM
настройте провайдера и уберите этот параметр. Разберите результаты и сведения
о выполнении каждой проверки в отчёте.
При Could not resolve a configured project/source context выберите базу
зарегистрированного проекта по руководству импорта.
При устаревшем графе обновите CPG процессом проекта и повторите аудит.
Проверьте пути для метода через MCP
Для проекта с доменом python_generic текущий MCP-анализ возвращает пустой список
путей: определения источников и приёмников этого домена не загружаются в анализатор.
Для такого проекта используйте приведённый ниже пример SQLite и разбор исходников.
Следующий раздел описывает контракт вызова для доменов с загруженными определениями.
В активном профиле проверьте доступность и право вызова codegraph_security_taint_analysis_run.
Инструмент требует method_name; значения по умолчанию — source_category="user_input"
и sink_category="sql". Описанные категории источников: user_input, file_read, network, env;
приёмников: sql, command, file_write, xss, buffer.
Выберите sink_category по операции, которую исследуете: например, sql для
SQL-запросов или command для запуска команд. Эта категория определяет поиск;
при пустом sink_category используется source_category. Источники задаёт каталог
доменного плагина. source_category сохраняется в ответе как аргумент вызова.
Результат включает пути, в которых точное имя метода совпадает с функцией источника, приёмника или одной из промежуточных функций. Ограничения числа путей и времени действуют на общий поиск до отбора по методу. При продолжении исследования проверьте имя метода, выбранную категорию приёмников и сведения о лимитах.
Вызов использует текущий контекст проекта и GoCPG gRPC. Не передавайте путь хранилища.
Настройка описана в руководстве оператора MCP.
Выберите нужный проект и вызовите codegraph_security_taint_analysis_run со следующими аргументами:
{
"method_name": "<exact-method-name-from-your-CPG>",
"source_category": "user_input",
"sink_category": "sql"
}
Замените method_name точным именем из текущего графа. Это объект аргументов вызова MCP, а не REST-запрос или команда оболочки. Проверьте каждый возвращённый путь и его функции источника и приёмника. Используйте count как число возвращённых путей, а заключение по каждому пути
запишите после проверки условий выполнения.
Ответ содержит method, переданные категории, taint_paths и count. Переданные категории отражаются в ответе; выбор анализа описан выше.
При ответе Error: ... восстановите доступ к выбранному CPG по сообщению и повторите вызов.
Как читать путь
| Поле пути | Действие проверяющего |
|---|---|
source, sink |
Открыть указанные функции, файлы и строки; проверить вход и чувствительную операцию. |
path, functions_crossed |
Разобрать последовательность функций между источником и приёмником. |
sanitizers |
Проверить найденные функции очистки и применимость к данным приёмника. |
risk_score, risk_level, confidence |
Выбрать порядок ревью по оценкам анализатора. |
inter_procedural, tainted_fields |
Проверить переходы между функциями и отслеживаемые поля данных. |
Проверьте находку
Например, при разборе SQL-пути проследите, как параметр HTTP-запроса попадает в аргумент выполнения запроса к базе. Откройте промежуточные функции: где значение присваивается, проверяется и передаётся дальше? Затем изучите вызов приёмника: как сформирован SQL и как передано значение параметра? Если путь содержит функцию очистки, проверьте её действие на этих данных. Это учебный пример разбора, а не вывод анализатора для вашего проекта.
Пример: строка SQL и параметр запроса
Сохраните следующий код в dataflow-example.py и выполните python dataflow-example.py
в терминале с Python 3. Модуль sqlite3 входит в стандартную библиотеку Python.
Пример создаёт базу в памяти: файлы проекта и рабочая база не меняются.
import sqlite3
connection = sqlite3.connect(":memory:")
connection.execute("CREATE TABLE accounts (name TEXT)")
connection.executemany("INSERT INTO accounts VALUES (?)", [("alice",), ("bob",)])
user_input = "alice' OR '1'='1"
unsafe_sql = "SELECT name FROM accounts WHERE name = '" + user_input + "'"
unsafe_rows = connection.execute(unsafe_sql).fetchall()
safe_rows = connection.execute(
"SELECT name FROM accounts WHERE name = ?", (user_input,)
).fetchall()
print("concatenation:", unsafe_rows)
print("parameters:", safe_rows)
connection.close()
Ожидаемый вывод:
concatenation: [('alice',), ('bob',)]
parameters: []
В первом запросе входное значение становится частью текста SQL. Условие
OR '1'='1' выбирает обе записи. Во втором запросе тот же ввод передаётся
как значение параметра ?: SQLite ищет буквальное имя alice' OR '1'='1
и не находит его.
При ревью пути выделите источник (user_input), преобразование
(сборку unsafe_sql) и приёмник (connection.execute). Затем проверьте,
передаёт ли приложение ввод отдельным параметром или вставляет его в текст
запроса. Вариант с параметром сохраняет смысл запроса при этом вводе.
Это учебный пример поведения SQLite; найденный CodeGraph путь разбирайте
по исходникам своего приложения.
- Подтвердите, что источник контролируется атакующим в этих условиях выполнения.
- Проверьте каждый вызов и присваивание в найденном пути.
- Проверьте очистку и проверку данных, кодирование, авторизацию и границы доверия.
- Убедитесь, что приёмник достижим с указанной формой данных.
- Сохраните ревизию кода, категории, ссылки на доказательства и заключение проверяющего.
После разбора найденных путей продолжите ревью остальных источников, приёмников и границ среды исполнения приложения.
Справочные материалы
Параметры запуска общего аудита описаны в руководстве CLI.