Руководство пользователя CodeGraph

Руководство пользователя CodeGraph

Комплексная документация по анализу кода с использованием графов свойств кода (CPG)


Содержание

  1. Быстрый старт
  2. Сценарии для разработчиков
  3. Сценарии для специалистов по информационной безопасности - Укрепление исходного кода по D3FEND
  4. Сценарии для технических писателей
  5. Справочник команд TUI
  6. Руководство по настройке
  7. Приложение: все 21 сценарий
  8. Отчёты по аудиту безопасности (CLI)
  9. Типовые рабочие процессы
  10. Темы оформления
  11. Сессии
  12. Советы и хитрости
  13. Устранение неполадок

Быстрый старт

Установка

# Клонируйте репозиторий и установите зависимости
cd codegraph
pip install -r requirements.txt

# Настройте учетные данные API (выберите один вариант)
export GIGACHAT_AUTH_KEY="ваш-ключ-здесь"    # GigaChat (Сбер)
# ИЛИ
export OPENAI_API_KEY="ваш-ключ-здесь"        # OpenAI

Запуск TUI

python -m src.tui.app

Ваш первый запрос

╭─────────────────────────────────────────────────────────╮
│  Интерактивная консоль CodeGraph                          │
│  Введите /help для получения списка команд, /exit для выхода │
╰─────────────────────────────────────────────────────────╯

> Где определена функция heap_insert?

╭─────────────── Ответ ────────────────╮
│ heap_insert определена в:            │
│   src/backend/access/heap/heapam.c    │
│   Строка: 2156                        │
│                                       │
│ Сигнатура:                            │
│   void heap_insert(Relation relation, │
│                    HeapTuple tup,     │
│                    CommandId cid,     │
│                    ...)               │
╰───────────────────────────────────────╯

Основные команды

Команда Описание
/help Показать все доступные команды
/scenarios Вывести список из 21 сценария анализа
/select 02 Переключиться в режим аудита безопасности
/project Переключение между проектами CPG
/review git Просмотреть текущие изменения в коде
/stat Показать статистику базы данных
/generate-docs Сгенерировать полную документацию проекта
/exit Сохранить сессию и выйти

Сценарии для разработчиков

День 1: Освоение кодовой базы

Сценарий: Новый разработчик присоединяется к команде и должен быстро понять структуру кодовой базы.

Шаг 1: Выберите сценарий освоения

/select 01

Шаг 2: Задайте обзорные вопросы

> Что такое подсистема исполнителя (executor)?

╭─────────────── Ответ ────────────────╮
│ Подсистема исполнителя отвечает за  │
│ выполнение планов запросов,          │
│ сгенерированных планировщиком.       │
│                                      │
│ Основные компоненты:                 │
│   - ExecutorStart: Инициализация     │
│   - ExecutorRun: Основной цикл       │
│   - ExecutorEnd: Освобождение ресурсов│
│                                      │
│ Точка входа: src/backend/executor/   │
│              execMain.c              │
╰──────────────────────────────────────╯

> Каковы основные точки входа в исполнитель?

> Покажите архитектуру выполнения запросов

Шаг 3: Погрузитесь в детали

> Что делает ExecProcNode?
> Кто вызывает ExecutorRun?
> Объясните связь между Plan и PlanState

Пример из реальной практики: Понимание управления памятью

> Как работает выделение памяти в PostgreSQL?

╭─────────────── Ответ ────────────────╮
│ PostgreSQL использует контексты      │
│ памяти для иерархического управления│
│ памятью:                             │
│                                      │
│ Основные функции:                    │
│   palloc()  - Выделить память        │
│   pfree()   - Освободить память      │
│   MemoryContextCreate() - Новый контекст│
│   MemoryContextReset()  - Массовое освобождение│
│                                      │
│ Основные контексты:                  │
│   TopMemoryContext - Корневой контекст│
│   CurrentMemoryContext - Текущий     │
│   MessageContext - На сообщение      │
╰──────────────────────────────────────╯

Поиск определений функций

Сценарий: Разработчику нужно найти реализации функций.

Быстрый поиск определения

> Где определена функция palloc?

╭─────────────── Ответ ────────────────╮
│ palloc определена в:                 │
│   src/backend/utils/mmgr/mcxt.c:1089 │
│                                      │
│ Сигнатура:                           │
│   void *palloc(Size size)            │
│                                      │
│ Связанные функции:                   │
│   palloc0(), palloc_extended(),      │
│   repalloc(), pfree()                │
╰──────────────────────────────────────╯

С графом вызовов

> Покажите всех вызывающих palloc

╭─────────────── Вызывающие ───────────╮
 1. heap_form_tuple()                 
 2. ExecStoreTuple()                  
 3. construct_array()                 
 4. pnstrdup()                        
 5. SPI_connect()                     
 ... (показано первые 5 из 2 847)     
╰──────────────────────────────────────╯

> Какие функции вызывает LWLockAcquire?

Отслеживание потока данных

> Как проходят данные от pg_parse_query до исполнителя?

╭─────────────── Поток данных ─────────╮
│ pg_parse_query()                     │
│     ↓                                │
│ pg_analyze_and_rewrite()             │
│     ↓                                │
│ pg_plan_queries()                    │
│     ↓                                │
│ PortalRun()                          │
│     ↓                                │
│ ExecutorRun()                        │
│     ↓                                │
│ ExecProcNode()                       │
╰──────────────────────────────────────╯

Добавление новых функций

Сценарий: Разработчику нужно добавить новый алгоритм соединения (join).

Шаг 1: Выберите сценарий разработки функций

/select 04

Шаг 2: Найдите точки интеграции

> Где мне добавить новый алгоритм соединения?

╭─────────────── Ответ ────────────────╮
│ Чтобы добавить новый алгоритм:       │
│                                      │
│ 1. Определите тип узла:              │
│    src/include/nodes/plannodes.h     │
│                                      │
│ 2. Добавьте поддержку в планировщик:│
│    src/backend/optimizer/path/       │
│    joinpath.c - add_xxx_path()       │
│                                      │
│ 3. Добавьте поддержку в исполнитель:│
│    src/backend/executor/             │
│    nodeXxxjoin.c - ExecXxxJoin()     │
│                                      │
│ 4. Зарегистрируйте в execProcnode.c  │
╰──────────────────────────────────────╯

> Какие хуки существуют в исполнителе для пользовательских узлов плана?

> Покажите, как hashjoin интегрируется с планировщиком

Шаг 3: Оцените влияние изменений

> Что сломается, если я изменю add_path?

╭──────────── Анализ влияния ──────────╮
│ Изменение add_path() повлияет на:   │
│                                      │
│ Прямые вызывающие (47):             │
│   - add_partial_path()               │
│   - add_partial_path_precheck()      │
│   - create_seqscan_path()            │
│   - create_index_path()              │
│   ...                                │
│                                      │
│ Риск: ВЫСОКИЙ — ядро выбора путей    │
│ Рекомендация: Добавьте новую функцию │
│ вместо изменения существующей        │
╰──────────────────────────────────────╯

> Покажите зависимости create_hashjoin_path

Помощь при отладке

Сценарий: Разработчик отлаживает сбой или неожиданное поведение.

Шаг 1: Выберите сценарий отладки

/select 15

Шаг 2: Найдите точки отладки

> Где в исполнителе используются макросы утверждений (assert)?

╭─────────────── Ответ ────────────────╮
│ Макросы утверждений в исполнителе:   │
│                                      │
│ Assert() - src/include/c.h:846       │
│ AssertArg() - Проверка аргументов    │
│ AssertState() - Проверка состояния   │
│                                      │
│ Использование в исполнителе:         │
│   execMain.c: 89 утверждений         │
│   execProcnode.c: 34 утверждения     │
│   execScan.c: 23 утверждения         │
╰──────────────────────────────────────╯

> Найдите вызовы elog в heap_insert

> Какие функции пишут в WAL?

Шаг 3: Отследите выполнение

> Отследите выполнение от INSERT до heap_insert

╭──────────── Трассировка выполнения ──╮
│ ProcessQuery()                       │
│   ↓                                  │
│ PortalRunMulti()                     │
│   ↓                                  │
│ ExecutorRun()                        │
│   ↓                                  │
│ ExecModifyTable()                    │
│   ↓                                  │
│ ExecInsert()                         │
│   ↓                                  │
│ table_tuple_insert()                 │
│   ↓                                  │
│ heap_insert()                        │
╰──────────────────────────────────────╯

> Где поставить точки останова для фиксации транзакции?

Рефакторинг кода

Сценарий: Разработчик устраняет технический долг во время спринта рефакторинга.

Шаг 1: Выберите сценарий рефакторинга

/select 05

Шаг 2: Найдите неиспользуемый код

> Найдите неиспользуемые статические функции в исполнителе

╭──────────── Неиспользуемый код ──────╮
│ Потенциально неиспользуемые функции: │
│                                      │
│ 1. execUtils.c:                      │
│    - old_get_typlenbyval() :234      │
│                                      │
│ 2. execTuples.c:                     │
│    - legacy_slot_init() :456         │
│                                      │
│ Всего: 12 кандидатов                 │
│ Подтверждено неиспользуемых: 8       │
╰──────────────────────────────────────╯

> Покажите устаревшие функции, которые всё ещё используются

> Найдите дублирующиеся шаблоны обработки ошибок

Шаг 3: Планирование рефакторинга

> От чего зависит ExecProcNode?

╭──────────── Зависимости ─────────────╮
│ Прямые зависимости: 47               │
│ Транзитивные зависимости: 312        │
│                                      │
│ Ключевые вызывающие:                 │
│   - ExecutorRun()                    │
│   - ExecSubPlan()                    │
│   - ExecMaterial()                   │
│   - ExecSort()                       │
│                                      │
│ Риск рефакторинга: КРИТИЧЕСКИЙ       │
│ Рекомендация: Поэтапная миграция     │
╰──────────────────────────────────────╯

> Влияние переименования heap_open в table_open

Сценарии для QA/тестировщиков

Анализ покрытия тестами

Сценарий: Инженеру по тестированию необходимо выявить непротестированные участки кода.

Шаг 1: Выбор сценария анализа покрытия тестами

/select 07

Шаг 2: Поиск пробелов в покрытии

> Какие функции не покрыты тестами?

╭─────────────── Пробелы в покрытии ─────────╮
│ Функции без прямых тестов:                │
│                                           │
│ Критические (executor):                   │
│   - ExecParallelHashJoinNewBatch()        │
│   - ExecReScanGather()                    │
│                                           │
│ Высокий приоритет (storage):              │
│   - heap_lock_updated_tuple()             │
│   - heap_abort_speculative()              │
│                                           │
│ Всего непротестированных: 234 функции     │
│ Оценка покрытия: 78%                      │
╰───────────────────────────────────────────╯

> Какие критические функции нужно протестировать в первую очередь?

> Найти непротестированные пути обработки ошибок

Шаг 3: Определение приоритетов тестирования

> Какие непротестированные функции имеют наибольшее влияние?

╭─────────────── Список приоритетов ─────────╮
│ Высокое влияние + нет тестов:              │
│                                            │
│ 1. heap_lock_updated_tuple()               │
│    Влияние: Целостность транзакций         │
│    Количество вызовов: 23                  │
│                                            │
│ 2. ExecParallelHashJoinNewBatch()          │
│    Влияние: Корректность параллельных запросов │
│    Количество вызовов: 8                   │
│                                            │
│ 3. AtEOXact_RelationCache()                │
│    Влияние: Согласованность кеша           │
│    Количество вызовов: 4                   │
╰────────────────────────────────────────────╯

> Показать точки входа без тестов

Помощь при проверке кода

Сценарий: Рецензенту необходимо проанализировать запрос на слияние на наличие проблем с качеством и безопасностью.

Вариант A: GitHub PR

/review github 123

Вариант B: GitLab MR

/review gitlab 456

Вариант C: Локальные изменения в Git

/review git

Вариант D: Файл изменений

/review file path/to/changes.patch

Понимание результата

╭─────────────── Результаты ревью ────────────────────────────╮
│                                                             │
│  Оценка: 72/100         Рекомендация: REQUEST_CHANGES        │
│                                                             │
│  ══════════════════════════════════════════════════════     │
│                                                             │
│  Найденные проблемы:                                        │
│                                                             │
│  🔴 КРИТИЧЕСКИЙ  Риск SQL-инъекции                           │
│     Местоположение: src/api/user_query.c:45                 │
│     Паттерн: Ввод пользователя вставляется в запрос напрямую │
│     Исправление: Использовать параметризованные запросы     │
│                                                             │
│  🟡 СРЕДНИЙ     Сложность по Маккейбу                       │
│     Местоположение: src/parser/gram.y:1234                  │
│     Значение: 47 (порог: 10)                                │
│     Исправление: Вынести вспомогательные функции             │
│                                                             │
│  🟢 НИЗКИЙ      Отсутствует проверка на NULL                │
│     Местоположение: src/utils/string.c:89                   │
│     Исправление: Добавить проверку указателя на NULL        │
│                                                             │
╰─────────────────────────────────────────────────────────────╯

Проверка кода с встроенными комментариями

/review git --format md --inline

╭─────────────── Встроенные комментарии ───────────────────────────╮
                                                                   
  src/api/user_query.c                                             
  ─────────────────────                                            
                                                                   
  Строка 45:                                                       
    sprintf(query, "SELECT * FROM users WHERE id=%s", id);         
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    🔴 SQL-инъекция: Используйте snprintf с правильным экранированием 
                                                                   
  Строка 67:                                                       
    char *result = malloc(len);                                    
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^                                    
    🟡 Память: Проверьте возвращаемое значение malloc на NULL      
                                                                   
╰───────────────────────────────────────────────────────────────────╯

Генерация тестовых сценариев

Сценарий: QA-инженеру необходимо создать комплексные тесты для функции.

> Сгенерируй тестовые сценарии для heap_insert

╭─────────────── Тестовые сценарии ────────────────────────────────╮
                                                                  
 Функция: heap_insert()                                           
 Файл: src/backend/access/heap/heapam.c:2156                      
                                                                  
 ═════════════════════════════════════════════════════════        
                                                                  
 1. Обычная вставка                                               
    Входные данные: Корректная таблица, корректный кортеж,         
                    корректный CommandId                           
    Ожидаемое: Возвращён OID, кортеж виден                         
                                                                  
 2. NULL в указателе таблицы                                      
    Входные данные: Указатель таблицы равен NULL                   
    Ожидаемое: Сбой утверждения или корректное сообщение об ошибке 
                                                                  
 3. Слишком большой кортеж                                         
    Входные данные: Кортеж больше BLCKSZ                          
    Ожидаемое: Ошибка с понятным сообщением                       
                                                                  
 4. Параллельная вставка                                          
    Входные данные: Несколько потоков выполняют вставку            
    Ожидаемое: Все вставки успешны, без повреждений данных         
                                                                  
 5. Откат транзакции                                              
    Входные данные: Вставка, за которой следует ROLLBACK           
    Ожидаемое: Кортеж не виден после отката                       
                                                                  
 6. Требуется TOAST                                               
    Входные данные: Кортеж с большим полем varlena                
    Ожидаемое: TOAST-таблица заполнена корректно                  
                                                                  
╰──────────────────────────────────────────────────────────────────╯

> Какие граничные случаи нужно протестировать в LWLockAcquire?

> Создай тестовые данные для сценариев фиксации транзакций

Сценарии специалиста по информационной безопасности

Сканирование уязвимостей

Сценарий: Инженер по безопасности проводит аудит в рамках спринта.

Шаг 1: Выбор сценария безопасности

/select 02

Шаг 2: Поиск уязвимостей

> Найти уязвимости типа SQL-инъекция

╭─────────────── Результаты проверки безопасности ─────────────────────────╮
                                                                           
  🔴 КРИТИЧЕСКИЙ: SQL-инъекция                                               
     ──────────────────────────────────────                                
                                                                           
     Расположение: src/pl/plpgsql/src/pl_exec.c:4567                       
     Паттерн: Динамический запрос с конкатенацией строк                     
     Код:                                                                 
       snprintf(query, "SELECT * FROM %s", table_name);                    
                                                                           
     Риск: Управляемое пользователем имя таблицы может внедрить SQL         
     Исправление: Использовать quote_identifier() для имён таблиц          
     CWE: CWE-89                                                           
                                                                           
  ──────────────────────────────────────────────────────────────────────── 
                                                                           
     Расположение: src/backend/utils/adt/ruleutils.c:2341                  
     Паттерн: Строка формата с внешним вводом                              
     Риск: Потенциальная инъекция строки формата                           
     Исправление: Проверить спецификаторы формата                          
                                                                           
  Всего найдено: 7 критических, 12 высоких, 34 средних                      
                                                                           
╰───────────────────────────────────────────────────────────────────────────╯

> Найти риски переполнения буфера в строковых функциях

> Показать функции, использующие sprintf без проверки границ

Анализ потока заражённых данных (Taint Flow Analysis)

Сценарий: Инженер по безопасности отслеживает ненадёжные данные через систему.

Шаг 1: Определение точек входа

> Найти все внешние точки входа

╭─────────────── Точки входа ──────────────────────────────╮
                                                           
  Сетевые точки входа:                                     
    - pq_getmsgstring()     - Чтение строки от клиента     
    - pq_getmsgint()        - Чтение целого от клиента     
    - ProcessClientRead()   - Прямое чтение из сокета      
                                                           
  Точки входа SQL:                                         
    - exec_simple_query()   - Прямое выполнение SQL        
    - exec_parse_message()  - Подготовленный оператор      
    - exec_bind_message()   - Привязка параметров          
                                                           
  Файловые точки входа:                                    
    - pg_read_file()        - Чтение произвольного файла   
    - pg_ls_dir()           - Просмотр содержимого папки    
                                                           
  Всего: обнаружено 47 точек входа                         
                                                           
╰───────────────────────────────────────────────────────────╯

> Показать обработчики сетевого ввода

> Перечислить функции ввода пользователя

Шаг 2: Отслеживание потока данных

> Отследить поток данных от PQgetvalue до выполнения SQL

╭─────────────── Поток заражённых данных ────────────────────────╮
                                                               
  ИСТОЧНИК: PQgetvalue() [Ввод клиента]                         
                                                              
  pq_getmsgstring()                                            
                                                              
  exec_simple_query()                                          
                                                              
  pg_parse_query()                                             
                                                              
  СТОК: SPI_execute() [Выполнение SQL]                         
                                                               
  ════════════════════════════════════════════════════         
                                                               
  Санация найдена: ДА                                           
  Расположение: pg_parse_query() проверяет синтаксис            
  НО: Не предотвращает семантическую инъекцию                   
                                                               
  Уровень риска: ВЫСОКИЙ                                        
  Рекомендация: Добавить проверку ввода на точке входа          
                                                               
╰───────────────────────────────────────────────────────────────╯

> Достигает ли ввод пользователя strcpy без проверки?

> Показать путь от чтения из сокета до выделения памяти

Шаг 3: Поиск санации данных

> Где ввод санируется перед выполнением запроса?

╭─────────────── Точки санации данных ───────────────────────╮
│                                                           │
│  Обнаруженные средства санации:                            │
│                                                           │
│  1. quote_identifier()                                    │
│     Расположение: src/backend/utils/adt/ruleutils.c:10234 │
│     Назначение: Экранирование идентификаторов SQL         │
│     Охват: Частичный — не всегда используется             │
│                                                           │
│  2. quote_literal()                                       │
│     Расположение: src/backend/utils/adt/quote.c:45        │
│     Назначение: Экранирование литералов SQL               │
│     Охват: Хороший — широко используется                  │
│                                                           │
│  3. pg_parse_query()                                      │
│     Расположение: src/backend/tcop/postgres.c:645         │
│     Назначение: Проверка синтаксиса                       │
│     Охват: Все запросы                                    │
│                                                           │
│  Отсутствует санация в:                                   │
│    - Построение имён таблиц (12 мест)                     │
│    - Построение строк формата (5 мест)                    │
│                                                           │
╰───────────────────────────────────────────────────────────╯

> Найти все функции проверки в аутентификации

Укрепление исходного кода по D3FEND

Сценарий: Инженер по безопасности проверяет практики оборонительного программирования с использованием фреймворка MITRE D3FEND.

Модуль D3FEND анализирует код на соответствие 11 методикам укрепления исходного кода, определённым MITRE:

ID Методика Описание CWE
D3-VI Инициализация переменных Неинициализированные переменные CWE-457
D3-CS Очистка учётных данных Жёстко заданные учётные данные CWE-798
D3-IRV Проверка диапазона целых Риски переполнения целых CWE-190
D3-PV Проверка указателей Разыменование указателя без проверки CWE-476
D3-RN Обнуление ссылок Риски использования после освобождения CWE-416
D3-TL Надёжные библиотеки Использование небезопасных функций CWE-676
D3-VTV Проверка типа переменных Проблемы с типами CWE-704
D3-MBSV Проверка начала блока памяти Выход за границы буфера CWE-119
D3-NPC Проверка на null-указатель Отсутствие проверок NULL CWE-476
D3-DLV Проверка логики домена Ошибки бизнес-логики CWE-20
D3-OLV Проверка операционной логики Управление состоянием CWE-754

Пример 1: Полный аудит укрепления

/select 02

> Выполнить проверку соответствия D3FEND

╭─────────────── Отчёт о соответствии D3FEND ─────────────────────╮
                                                               
  Общий балл соответствия: 72,5%                                
                                                               
  ═══════════════════════════════════════════════════════════  
                                                               
  Найденные проблемы по методикам:                             
                                                               
  D3-VI (Инициализация переменных): 23 проблемы                
  ──────────────────────────────────────────────────────      
    - palloc без palloc0: 15 мест                              
    - Неинициализированные поля структур: 8 мест               
                                                               
  D3-TL (Надёжные библиотеки): 12 проблем                      
  ─────────────────────────────────────────────────────       
    🔴 использование strcpy: src/backend/utils/adt/varlena.c:234
    🔴 использование sprintf: src/backend/libpq/auth.c:567      
    🟡 использование strtok: src/backend/parser/gram.c:1234     
                                                               
  D3-NPC (Проверка на null-указатель): 8 проблем               
  ──────────────────────────────────────────────────────      
    - malloc без проверки на NULL: 5 мест                      
    - palloc без проверки: 3 места                             
                                                               
  D3-RN (Обнуление ссылок): 6 проблем                          
  ──────────────────────────────────────────────────────      
    - pfree без ptr = NULL: 6 мест                             
                                                               
  Баллы по категориям:                                         
    Инициализация: 65%                                         
    Безопасность памяти: 78%                                   
    Безопасность указателей: 82%                               
    Безопасность библиотек: 58%                                
                                                               
╰───────────────────────────────────────────────────────────────╯

Пример 2: Проверка конкретных методик D3FEND

> Проверить использование небезопасных функций (D3-TL Надёжные библиотеки)

╭─────────────── D3-TL: Надёжные библиотеки ───────────────────────╮
                                                               
  Найдено небезопасных функций: 47                              
                                                               
  🔴 КРИТИЧЕСКИЙ - strcpy (риск переполнения буфера):           
  ──────────────────────────────────────────────────────       
    src/backend/utils/adt/varlena.c:234                        
    src/backend/libpq/pqformat.c:567                           
    src/pl/plpgsql/src/pl_exec.c:1234                          
                                                               
  🔴 КРИТИЧЕСКИЙ - sprintf (риск строки формата):               
  ──────────────────────────────────────────────────────       
    src/backend/libpq/auth.c:567                               
    src/backend/utils/error/elog.c:890                         
                                                               
  🟡 ВЫСОКИЙ - gets (устарела, всегда небезопасна):             
  ──────────────────────────────────────────────────────       
    Не найдено                                                
                                                               
  🟡 ВЫСОКИЙ - rand (слабый генератор случайных чисел):         
  ──────────────────────────────────────────────────────       
    src/backend/utils/misc/pg_random.c:45                      
                                                               
  Рекомендации по исправлению:                                 
  ──────────────────────────────                               
    - strcpy  strncpy/strlcpy                                 
    - sprintf  snprintf                                       
    - gets  fgets                                             
    - rand  pg_prng_* или arc4random                          
                                                               
╰───────────────────────────────────────────────────────────────╯

> Найти уязвимости из-за отсутствия проверки null-указателя (D3-NPC)

╭─────────────── D3-NPC: Проверка на null-указатель ────────────────╮
                                                               
  Отсутствие проверки NULL после выделения: 23                   
                                                               
  malloc без проверки:                                         
  ─────────────────────                                        
    src/backend/utils/mmgr/aset.c:345                          
      char *buf = malloc(size);                                
      use(buf);  //  Нет проверки на NULL!                    
                                                               
  palloc без проверки:                                         
  ──────────────────────────                                   
    src/backend/executor/execUtils.c:234                       
      TupleTableSlot *slot = palloc(sizeof(...));              
      slot->tts_values = palloc(...);  //  Нет проверки       
                                                               
  Примечание PostgreSQL: palloc() вызывает ERROR при нехватке памяти,
  но явные проверки улучшают читаемость кода.                   
                                                               
  Пример исправления:                                          
  ─────────────────────                                        
    char *buf = malloc(size);                                  
    if (buf == NULL) {                                         
        ereport(ERROR, (errcode(ERRCODE_OUT_OF_MEMORY)));      
    }                                                          
                                                               
╰───────────────────────────────────────────────────────────────╯

Пример 3: Проверка безопасности памяти (D3-RN Обнуление ссылок)

> Проверить риски использования после освобождения

╭─────────────── D3-RN: Обнуление ссылок ────────────────╮
                                                       
  Освобождение без обнуления: 34 места                 
                                                       
  pfree без присвоения NULL:                           
  ──────────────────────────────                       
                                                       
    src/backend/utils/cache/relcache.c:567             
    ─────────────────────────────────────              
      pfree(rel->rd_options);                          
      // rel->rd_options всё ещё указывает на освобождённую память! 
                                                       
       ИСПРАВЛЕНИЕ:                                   
      pfree(rel->rd_options);                          
      rel->rd_options = NULL;                          
                                                       
    src/backend/executor/nodeHash.c:234                
    ─────────────────────────────────                  
      pfree(hashtable->buckets);                       
      // Риск висячего указателя в путях обработки ошибок 
                                                       
  MemoryContextDelete без обнуления:                   
  ──────────────────────────────────────────           
                                                       
    src/backend/utils/mmgr/mcxt.c:890                  
      MemoryContextDelete(ctx);                        
      // ctx может быть использован позже!             
                                                       
  Справка CWE: CWE-416 (Использование после освобождения) 
                                                       
╰───────────────────────────────────────────────────────╯

Пример 4: Проверка инициализации переменных (D3-VI)

> Найти неинициализированные переменные

╭─────────────── D3-VI: Инициализация переменных ───────────────╮
                                                               
  Найдено неинициализированных переменных: 56                   
                                                               
  Локальные переменные без инициализации:                      
  ──────────────────────────────────────────────────────      
                                                               
    src/backend/executor/execMain.c:456                        
    ─────────────────────────────────────                      
      EState *estate;        //  Неинициализирована           
      QueryDesc *queryDesc;  //  Неинициализирована           
                                                               
       ИСПРАВЛЕНИЕ:                                           
      EState *estate = NULL;                                   
      QueryDesc *queryDesc = NULL;                             
                                                               
  palloc без palloc0:                                          
  ───────────────────                                          
                                                               
    src/backend/nodes/copyfuncs.c:234                          
    ─────────────────────────────────                          
      Node *newnode = palloc(sizeof(Node));                    
      // Поля могут содержать мусор!                           
                                                               
       ИСПРАВЛЕНИЕ:                                           
      Node *newnode = palloc0(sizeof(Node));                   
                                                               
  Структура без memset:                                        
  ──────────────────────                                       
                                                               
    struct MyStruct s;       //  Неинициализированные поля    
     ИСПРАВЛЕНИЕ:                                             
    struct MyStruct s = {0}; // Нулевая инициализация          
                                                               
  Справка CWE: CWE-457 (Использование неинициализированной переменной) 
                                                               
╰───────────────────────────────────────────────────────────────╯

Пример 5: Очистка учётных данных (D3-CS)

> Найти жёстко заданные учётные данные

╭─────────────── D3-CS: Очистка учётных данных ──────────────────╮
                                                               
  🔴 КРИТИЧЕСКИЙ: Обнаружены жёстко заданные учётные данные     
                                                               
  Литералы паролей:                                            
  ─────────────────                                            
                                                               
    src/backend/libpq/auth.c:123                               
    ─────────────────────────────                              
      char *default_password = "postgres123";                  
      //    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^                  
      // НИКОГДА не задавайте пароли в исходном коде!          
                                                               
  Шаблоны API-ключей:                                          
  ────────────────────                                         
                                                               
    src/contrib/postgres_fdw/connection.c:456                  
    ──────────────────────────────────────────                 
      #define AWS_SECRET_KEY "AKIAIOSFODNN7EXAMPLE"            
      // Учётные данные в исходном коде!                       
                                                               
  Шаблоны токенов:                                             
  ────────────────                                             
    Не найдено                                                
                                                               
  Рекомендации по исправлению:                                 
  ────────────────────────────                                 
    - Используйте переменные окружения: getenv("DB_PASSWORD")  
    - Используйте защищённые хранилища учётных данных          
    - Используйте файл .pgpass для PostgreSQL                  
    - Реализуйте ротацию учётных данных                        
                                                               
  Справка CWE: CWE-798 (Использование жёстко заданных учётных данных) 
                                                               
╰───────────────────────────────────────────────────────────────╯

Пример 6: Проверка диапазона целых чисел (D3-IRV)

> Проверить риски переполнения целых чисел

╭─────────────── D3-IRV: Проверка диапазона целых чисел ─────────╮
                                                               
  Рисков переполнения целых: 18                                
                                                               
  Вычисление размера выделения без проверки:                   
  ──────────────────────────────────────────                   
                                                               
    src/backend/utils/palloc.c:234                             
    ───────────────────────────────                            
      size_t size = count * sizeof(int);  // Может переполниться! 
      ptr = palloc(size);                                      
                                                               
       ИСПРАВЛЕНИЕ (стиль PostgreSQL):                        
      if (count > SIZE_MAX / sizeof(int))                      
          ereport(ERROR, ...);                                 
      ptr = palloc(count * sizeof(int));                       
                                                               
       ИСПРАВЛЕНИЕ (с макросом проверки переполнения):        
      if (pg_mul_s64_overflow(count, sizeof(int), &size))      
          ereport(ERROR, ...);                                 
      ptr = palloc(size);                                      
                                                               
  Вычисление индекса массива:                                  
  ────────────────────────────                                 
                                                               
    src/backend/access/heap/heapam.c:567                       
    ────────────────────────────────────                       
      int offset = base + delta;  // Может произойти переполнение! 
      array[offset] = value;                                   
                                                               
  Справка CWE: CWE-190 (Переполнение целого числа)            
                                                               
╰───────────────────────────────────────────────────────────────╯

Пример 7: Специфичные проверки для домена (PostgreSQL)

> Выполнить проверки укрепления, специфичные для PostgreSQL

╭─────────────── Отчёт по укреплению PostgreSQL ─────────────────╮
                                                               
  Специфичные для PostgreSQL находки D3FEND                    
                                                               
  D3-VI-PG: palloc vs palloc0                                  
  ─────────────────────────────                                
    palloc без инициализации: 45 мест                          
    Рекомендация: Используйте palloc0() для структур           
                                                               
  D3-TL-PG: Стандартные C-функции vs функции PostgreSQL        
  ─────────────────────────────────────────────                
    использование malloc (следует использовать palloc): 12 мест 
    использование free (следует использовать pfree): 8 мест    
    использование strdup (следует использовать pstrdup): 5 мест 
                                                               
  D3-DLV-PG: Проверка OID                                     
  ─────────────────────────────                                
    SearchSysCache без OidIsValid: 7 мест                      
    GetSysCacheOid без проверки: 3 места                       
                                                               
  D3-OLV-PG: Управление состоянием SPI                        
  ───────────────────────────────                              
    SPI_execute без SPI_connect: 2 места                       
    Отсутствует SPI_finish в путях обработки ошибок: 4 места   
                                                               
  Лучшие практики PostgreSQL:                                  
  ──────────────────────────                                   
     Используйте palloc/pfree вместо malloc/free              
     Используйте palloc0 для инициализации структур           
     Всегда проверяйте OidIsValid() перед поиском в кеше     
     Используйте HeapTupleIsValid() после SearchSysCache     
     Обеспечьте баланс SPI_connect/SPI_finish во всех путях  
                                                               
╰───────────────────────────────────────────────────────────────╯

Пример 8: Генерация отчёта о соответствии

> Сгенерировать отчёт о соответствии D3FEND для аудита

╭─────────────── Отчёт аудита соответствия D3FEND ───────────────╮
                                                               
  Соответствие MITRE D3FEND по укреплению исходного кода       
  ═══════════════════════════════════════════                  
                                                               
  Дата аудита: 2024-12-09                                      
  Объект: PostgreSQL 16.1 (src/backend/*)                      
  Язык: C                                                      
                                                               
  КРАТКОЕ РЕЗЮМЕ                                               
  ─────────────────                                            
  Общий балл соответствия: 72,5%                               
  Всего находок: 156                                           
    - Критических: 12                                          
    - Высоких: 34                                              
    - Средних: 67                                              
    - Низких: 43                                               
                                                               
  СООТВЕТСТВИЕ ПО МЕТОДИКАМ                                    
  ─────────────────────                                        
                                                               
  D3-VI  Инициализация переменных   ████████░░  78%            
  D3-CS  Очистка учётных данных     ██████████  95%            
  D3-IRV Проверка диапазона целых   ███████░░░  68%            
  D3-PV  Проверка указателей        ████████░░  82%            
  D3-RN  Обнуление ссылок           ██████░░░░  62%            
  D3-TL  Надёжные библиотеки        █████░░░░░  58%            
  D3-VTV Проверка типа переменных   ████████░░  85%            
  D3-MBSV Проверка блока памяти     ███████░░░  72%            
  D3-NPC Проверка null-указателя    ████████░░  80%            
  D3-DLV Проверка логики домена     ███████░░░  75%            
  D3-OLV Проверка операц. логики    ██████░░░░  65%            
                                                               
  ПРИОРИТЕТНЫЕ ИСПРАВЛЕНИЯ                                     
  ────────────────────────                                     
  1. Заменить небезопасные строковые функции (D3-TL)           
  2. Добавить проверки NULL после выделения памяти (D3-NPC)    
  3. Обнулять указатели после освобождения (D3-RN)             
  4. Добавить проверки переполнения в вычислениях размеров (D3-IRV) 
                                                               
  Полный отчёт сохранён в: d3fend_audit_2024-12-09.md          
                                                               
╰───────────────────────────────────────────────────────────────╯

Программный доступ через API

Для автоматизации и интеграции с CI/CD:

from src.security.hardening import HardeningScanner, HardeningCategory
from src.services.cpg import CPGQueryService

# Инициализация сканера
with CPGQueryService() as cpg:
    scanner = HardeningScanner(cpg, language="c")

    # Запуск всех проверок
    findings = scanner.scan_all(limit_per_check=50)

    # Или запуск конкретных методик D3FEND
    findings = scanner.scan_by_d3fend_id(
        ["D3-VI", "D3-NPC", "D3-TL"],
        limit=30
    )

    # Или запуск по категории
    findings = scanner.scan_by_category(
        HardeningCategory.MEMORY_SAFETY,
        limit=20
    )

    # Получение баллов соответствия
    scores = scanner.get_compliance_score(findings)
    print(f"Общий балл: {scores['overall_score']}%")
    print(f"По D3FEND: {scores['d3fend_scores']}")

    # Генерация отчёта с рекомендациями по исправлению
    report = scanner.get_remediation_report(findings)
    with open("hardening_report.md", "w") as f:
        f.write(report)

Проверка соответствия нормативным требованиям

Сценарий: Аудитор проверяет кодовую базу на соответствие нормативным требованиям.

Шаг 1: Выбор сценария проверки соответствия

/select 08

Шаг 2: Проверка стандартов

> Проверить на уязвимости из OWASP Top 10

╭─────────────── Аудит OWASP Top 10 ──────────────────────────╮
│                                                           │
│  A01:2021 — Нарушение контроля доступа                    │
│  ─────────────────────────────────                        │
│  Статус: 3 находки                                        │
│    - Отсутствует проверка ACL в pg_ls_dir()               │
│    - Повышение привилегий через ALTER ROLE                │
│                                                           │
│  A02:2021 — Криптографические ошибки                      │
│  ─────────────────────────────────                        │
│  Статус: ПРОЙДЕНО                                         │
│    - Используется OpenSSL для шифрования                  │
│    - scram-sha-256 для аутентификации                     │
│                                                           │
│  A03:2021 — Инъекции                                      │
│  ────────────────────────                                 │
│  Статус: 7 находок                                        │
│    - См. отчёт по SQL-инъекциям выше                      │
│                                                           │
│  A04:2021 — Небезопасное проектирование                   │
│  ──────────────────────────                               │
│  Статус: 2 находки                                        │
│    - Суперпользователь по умолчанию без пароля            │
│                                                           │
│  Общий балл: 72/100                                       │
│                                                           │
╰───────────────────────────────────────────────────────────╯

> Найти жёстко заданные учётные данные

> Сгенерировать отчёт о соответствии для CWE-89

Аудит безопасности Python/Django

Сценарий: Инженер по безопасности проводит аудит веб-приложения на Django.

При анализе проектов на Python/Django система использует специализированные шаблоны безопасности для обнаружения веб-уязвимостей:

Поддерживаемые уязвимости

Идентификатор Уязвимость CWE Индикаторы
DJANGO_SQL_INJECTION SQL-инъекция через необработанный запрос CWE-89 raw(), extra(), RawSQL(), cursor.execute()
DJANGO_XSS Межсайтовый скриптинг CWE-79 mark_safe(), \|safe, autoescape off
DJANGO_CSRF Уязвимость CSRF CWE-352 @csrf_exempt
DJANGO_AUTH_BYPASS Обход аутентификации CWE-287 @permission_classes([]), AllowAny
DJANGO_INSECURE_DESERIALIZE Небезопасная десериализация CWE-502 pickle.loads, yaml.load, eval()
DJANGO_PATH_TRAVERSAL Обход пути CWE-22 open(), os.path.join() с пользовательским вводом
DJANGO_CMD_INJECTION Инъекция команд CWE-78 subprocess.*, os.system(), shell=True
DJANGO_MASS_ASSIGNMENT Массовое присваивание CWE-915 **request.data, update(**kwargs)

Примеры запросов

# Сначала переключитесь на проект Django
/project switch fsin_module

# Затем выберите сценарий аудита безопасности
/select 02

# Задавайте вопросы по безопасности
> Найти SQL-инъекции во вьюхах
> Проверить XSS в шаблонах
> Найти конечные точки без защиты CSRF
> Показать функции, использующие eval() или exec()

Источники заражения (пользовательский ввод)

Система отслеживает поток данных из следующих источников Django: - request.GET.get(), request.POST.get(), request.data.get() - request.body, request.path, request.FILES - form.cleaned_data, serializer.validated_data - Параметры URL (kwargs.get())

Приёмники заражения (опасные функции)

Данные, достигающие этих приёмников, помечаются как опасные: - SQL: raw(), extra(), execute(), RawSQL() - XSS: mark_safe(), HttpResponse() - Команды: subprocess.*, os.system(), os.popen() - Файлы: open(), FileResponse() - Десериализация: pickle.loads(), yaml.load(), eval(), exec()


Реагирование на инциденты

Сценарий: Команда безопасности расследует инцидент.

Шаг 1: Выбор сценария инцидента

/select 14

Шаг 2: Трассировка вектора атаки

> Проследить вектор атаки от входа до получения административного доступа

╭─────────────── Анализ вектора атаки ────────────────────────╮
│                                                           │
│  Потенциальные пути повышения привилегий:                  │
│                                                           │
│  Путь 1: SQL-инъекция → Суперпользователь                 │
│  ─────────────────────────────────────                    │
│  1. login() принимает пользовательский ввод               │
│  2. Ввод передаётся в authenticate()                      │
│  3. Запрос строится через конкатенацию строк              │
│  4. Инъекция обходит аутентификацию                       │
│  5. Сессия получает привилегии суперпользователя          │
│                                                           │
│  Путь 2: Перегрузка функций                               │
│  ────────────────────────────                             │
│  1. Пользователь создаёт функцию с такой же сигнатурой   │
│  2. Манипуляция search_path                               │
│  3. Вредоносная функция вызывается суперпользователем     │
│                                                           │
│  Меры защиты:                                             │
│    - Параметризованные запросы                            │
│    - Явная квалификация схемы                             │
│    - Аудит SECURITY DEFINER                               │
│                                                           │
╰───────────────────────────────────────────────────────────╯

> Найти пути повышения привилегий

> Показать доступ к данным из скомпрометированной функции

Шаг 3: Оценка последствий

> Какие данные можно получить из функции auth_check?

╭─────────────── Оценка последствий ──────────────────────────╮
│                                                           │
│  Функция: auth_check()                                    │
│  Уровень доступа: Контекст суперпользователя              │
│                                                           │
│  Достижимые данные:                                       │
│  ────────────────                                         │
│                                                           │
│  Прямой доступ:                                           │
│    - pg_authid (пароли, роли)                             │
│    - pg_auth_members (членство в ролях)                   │
│    - Все пользовательские таблицы                         │
│                                                           │
│  Через вызовы функций:                                    │
│    - pg_read_file() — доступ к файловой системе           │
│    - pg_ls_dir() — просмотр каталога                      │
│    - COPY TO PROGRAM — выполнение команд                  │
│                                                           │
│  Радиус поражения: КРИТИЧЕСКИЙ                            │
│    - Полная компрометация базы данных                     │
│    - Потенциальный доступ на уровне ОС                    │
│                                                           │
╰───────────────────────────────────────────────────────────╯

> Найти все вызывающие функции скомпрометированного компонента

Сценарии для технического писателя

Генерация документации по API

Сценарий: Технический писатель документирует публичное API.

Шаг 1: Выбор сценария документации

/select 03

Шаг 2: Генерация документации по функциям

> Создай документацию для heap_insert

╭─────────────── Документация API ─────────────────────────╮
│                                                           │
│  ## heap_insert                                           │
│                                                           │
│  Вставляет кортеж в отношение кучи.                       │
│                                                           │
│  ### Сигнатура                                           │
│                                                           │
│

c │ │ void heap_insert(Relation relation, │ │ HeapTuple tup, │ │ CommandId cid, │ │ int options, │ │ BulkInsertState bistate) │ │

                                                      │
│                                                           │
│  ### Параметры                                           │
│                                                           │
│  | Параметр  | Тип           | Описание                   │
│  |-----------|---------------|----------------------------│
│  | relation  | Relation      | Целевое отношение кучи    │
│  | tup       | HeapTuple     | Кортеж для вставки         │
│  | cid       | CommandId     | Идентификатор команды для MVCC │
│  | options   | int           | Флаги опций вставки        │
│  | bistate   | BulkInsertState | Состояние массовой вставки │
│                                                           │
│  ### Возвращаемое значение                                │
│                                                           │
│  void (кортеж модифицируется на месте, при необходимости с присвоением OID) │
│                                                           │
│  ### Пример                                               │
│                                                           │
│

c │ │ HeapTuple tuple = heap_form_tuple(desc, values, nulls); │ │ heap_insert(rel, tuple, GetCurrentCommandId(true), │ │ 0, NULL); │ │

                                                      
                                                           
  ### Смотрите также                                       
                                                           
  - heap_update() - Обновление существующего кортежа      
  - heap_delete() - Удаление кортежа                       
  - simple_heap_insert() - Упрощённая обёртка              
                                                           
  ### Исходный код                                         
                                                           
  src/backend/access/heap/heapam.c:2156                    
                                                           
╰───────────────────────────────────────────────────────────╯

> Документируй функции интерфейса SPI
>
>
> Создай справочник API для управления блокировками

Понимание архитектуры модуля

Сценарий: Технический писатель документирует архитектуру системы.

> Объясни архитектуру модуля исполнителя (executor)

╭─────────────── Архитектура ──────────────────────────────╮
│                                                           │
│  Архитектура модуля исполнителя (executor)                 │
│  ══════════════════════════════════════════                │
│                                                           │
│  Назначение: Выполнение планов запросов, созданных планировщиком │
│                                                           │
│  Каталог: src/backend/executor/                            │
│                                                           │
│  Основные компоненты:                                     │
│  ────────────────                                         │
│                                                           │
│  1. execMain.c - Основные точки входа исполнителя         │
│     - ExecutorStart(): Инициализация состояния выполнения  │
│     - ExecutorRun(): Основной цикл выполнения             │
│     - ExecutorEnd(): Очистка и завершение работы          │
│                                                           │
│  2. execProcnode.c - Диспетчер узлов                      │
│     - ExecProcNode(): Перенаправление на конкретные типы узлов │
│     - ExecInitNode(): Инициализация узлов плана           │
│     - ExecEndNode(): Очистка узлов плана                  │
│                                                           │
│  3. Исполнители, специфичные для узлов:                   │
│     - nodeSeqscan.c    - Последовательное сканирование    │
│     - nodeIndexscan.c  - Сканирование по индексу          │
│     - nodeHashjoin.c   - Хеш-соединение                   │
│     - nodeMergejoin.c  - Слияние соединений               │
│     - nodeAgg.c        - Агрегация                        │
│     - nodeSort.c       - Сортировка                       │
│                                                           │
│  Поток данных:                                            │
│  ──────────                                               │
│                                                           │
│  Дерево плана → Дерево состояния плана → Вывод кортежей   │
│                                                           │
│  Зависимости:                                             │
│  ─────────────                                            │
│    → access/    (уровень хранения)                        │
│    → utils/     (память, кеш)                             │
│    → nodes/     (определения узлов)                       │
│                                                           │
╰───────────────────────────────────────────────────────────╯

> Каковы основные компоненты WAL?
>
>
> Как работает MVCC в PostgreSQL?

Создание справочника функций

Сценарий: Технический писатель составляет индекс функций.

> Перечисли все публичные функции в модуле исполнителя

╭─────────────── Справочник функций ────────────────────────╮
│                                                           │
│  Публичные функции исполнителя                            │
│  ════════════════════════════════                          │
│                                                           │
│  Точки входа:                                             │
│  ─────────────                                            │
│  ExecutorStart()      Инициализация выполнения            │
│  ExecutorRun()        Выполнение плана                    │
│  ExecutorFinish()     Обработка после выполнения          │
│  ExecutorEnd()        Очистка                             │
│                                                           │
│  Операции с узлами:                                       │
│  ────────────────                                         │
│  ExecProcNode()       Выполнить один узел                 │
│  ExecInitNode()       Инициализировать узел               │
│  ExecEndNode()        Очистить узел                       │
│  ExecReScan()         Сброс для повторного сканирования   │
│                                                           │
│  Операции с кортежами:                                    │
│  ─────────────────                                        │
│  ExecStoreTuple()     Сохранить кортеж в слоте            │
│  ExecClearTuple()     Очистить слот                       │
│  ExecCopySlot()       Скопировать содержимое слота        │
│                                                           │
│  Всего: 156 публичных функций                              │
│                                                           │
╰───────────────────────────────────────────────────────────╯

Покажи все точки входа с их сигнатурами

Использование прямого SQL-запроса

/query SELECT name, signature, filename FROM nodes_method
       WHERE filename LIKE ‘%executor%’
       ORDER BY name
       LIMIT 20

╭─────────────── Результаты запроса ────────────────────────╮
│                                                           │
│  name              | signature              | filename    │
│  ──────────────────┼────────────────────────┼──────────   │
│  ExecAgg           | ExecAgg(PlanState*)    | nodeAgg.c   │
│  ExecAppend        | ExecAppend(…)        | nodeAppend  │
│  ExecBitmapAnd     | ExecBitmapAnd(…)     | nodeBitma   │
│  …               | …                    | …         │
│                                                           │
│  Возвращено 20 строк                                      │
│                                                           │
╰───────────────────────────────────────────────────────────╯

Справочник команд TUI

Все команды

Команда Аргументы Описание
/help [команда] Показать справку по всем командам или по конкретной команде
/scenarios [группа] Список доступных сценариев, с необязательной фильтрацией
/select <номер> Выбрать сценарий по номеру (01–16)
/history [количество] Показать историю диалога
/save [имя_файла] Сохранить текущую сессию
/load <имя_файла> Загрузить сохранённую сессию
/config [раздел] [ключ] [значение] Просмотр или изменение конфигурации
/stat Показать статистику CPG и ChromaDB
/query <SQL> Выполнить SQL-запрос к базе данных CPG
/review [источник] [id] [--format] [--inline] Запустить анализ кода
/demo [--scenarios N,N] [--lang en\|ru] Запустить быстрое тестирование
/clear Очистить экран
/exit Выйти из приложения
/project [list\|switch\|add] Управление проектами CPG
/cpg <подкоманда> [аргументы] Операции GoCPG (статистика, запросы, ветки, хуки, мониторинг)
/explain <имя_метода> [--depth N] [--format json\|rich] Комплексный анализ метода
/watch <start\|stop\|status> [путь] Панель наблюдения с метриками и оповещениями

Подробное описание команд

/project

Управление несколькими проектами CPG (переключение между разными кодовыми базами).

# Показать информацию о текущем проекте
/project

# Список всех доступных проектов
/project list

# Переключиться на другой проект
/project switch fsin_module
/project switch postgresql

# Добавить новый проект
/project add myproject path/to/project.duckdb python "Мой Python-проект"

Конфигурация проектов (projects.yaml):

projects:
  postgresql:
    db_path: "data/projects/postgres.duckdb"
    language: c
    description: "Исходный код PostgreSQL 17"
  fsin_module:
    db_path: "workspace/fsin_module_v2.duckdb"
    language: python
    description: "Django-модуль FSIN"

active_project: postgresql

Автоматическое переключение доменов:

При смене проекта система автоматически активирует соответствующий доменный плагин:

Язык Доменный плагин Шаблоны безопасности
c, cpp postgresql / generic_cpp Безопасность памяти, переполнение буфера
python python_django SQL-инъекции, XSS, CSRF
# Пример: переключение на проект Python/Django
/project switch fsin_module
# Вывод: Домен активирован: python_django

# Пример: возврат к проекту на C
/project switch postgresql
# Вывод: Домен активирован: postgresql

/cpg

Операции GoCPG — взаимодействие с движком графа кода непосредственно из TUI.

# Показать справку
/cpg

# Статистика CPG
/cpg stats
/cpg stats data/projects/postgres.duckdb

# Выполнение SQL-запроса
/cpg query SELECT COUNT(*) FROM nodes_method
/cpg query SELECT full_name FROM nodes_method LIMIT 10

# Список языковых модулей
/cpg frontends

# Управление ветками
/cpg branches                    # Список отслеживаемых веток
/cpg branches switch feature-x   # Переключить активную ветку
/cpg branches prune              # Удалить устаревшие ветки

# Управление git-хуками
/cpg hooks status                # Показать статус хуков
/cpg hooks install               # Установить git-хуки
/cpg hooks uninstall             # Удалить git-хуки

# Управление индексами
/cpg index                       # Создать/пересоздать индексы DuckDB

# Валидация метрик
/cpg metrics
/cpg metrics /path/to/source

# Управление подмодулями
/cpg submodules                  # Список отслеживаемых подмодулей
/cpg submodules prune            # Удалить устаревшие подмодули

# Поиск структурных паттернов
/cpg search "malloc($x)" --lang c        # Ad-hoc поиск паттернов (без CPG-базы)
/cpg search "if ($cond) { return $x; }" --lang c --max-results 20

# Сканирование структурных паттернов (с CPG-ограничениями, использует правила)
/cpg scan                                 # Сканирование по всем правилам
/cpg scan --rule unchecked-return         # Сканирование по конкретному правилу
/cpg scan --severity high                 # Фильтрация по серьёзности

# Мониторинг файлов
/cpg watch start /path/to/source # Начать мониторинг изменений
/cpg watch stop                  # Остановить мониторинг
Подкоманда Аргументы Описание
stats [путь_к_db] Статистика CPG: количество узлов/рёбер, размер БД
query <sql> Выполнение SQL-запроса к базе данных CPG
frontends Список доступных языковых модулей
branches [list\|switch ИМЯ\|prune] Управление отслеживаемыми ветками CPG
hooks [status\|install\|uninstall] Управление git-хуками для автообновления CPG
index [путь_к_db] Создание/пересоздание индексов DuckDB
metrics [путь] Валидация метрик
submodules [list\|prune] Управление отслеживаемыми подмодулями
search <шаблон> --lang ЯЗЫК Ad-hoc поиск структурных шаблонов (без CPG-базы)
scan [--rule ID] [--severity УРОВЕНЬ] Сканирование шаблонов с CPG-ограничениями по YAML-правилам
watch [start <путь>\|stop] Мониторинг файлов для обновления CPG в реальном времени

/explain

Комплексный анализ метода — метрики, граф вызовов, флаги безопасности и информация о подсистеме в одном представлении.

# Базовый анализ метода
/explain heap_insert

# Увеличить глубину обхода вызывающих
/explain ExecCreateTable --depth 3

# Вывод в формате JSON (для скриптов или MCP)
/explain palloc --format json

Выводимая информация:

Раздел Детали
Идентификация Полное имя, путь к файлу, диапазон строк
Метрики Цикломатическая сложность, уровень риска, входящая/исходящая связность
Граф вызовов Прямые вызывающие, транзитивное количество, прямые вызываемые
Безопасность Флаги taint source/sink, пути потока данных через метод
Контекст Подсистема, флаги шаблонов (deprecated, debug, todo)

Пример вывода:

╭──────────────── Метод: heap_insert ──────────────────╮
                                                      
  Файл: src/backend/access/heap/heapam.c              
  Строки: 18421956 (114 строк)                       
  Сложность: 12 (Средний риск)                        
  Fan-in: 24  Fan-out: 8                              
                                                      
  Вызывающие (прямые): ExecInsert, simple_heap_insert 
  Вызываемые (прямые): heap_prepare_insert, ...       
  Taint: source=нет  sink=нет                         
  Подсистема: access/heap                             
                                                      
╰──────────────────────────────────────────────────────╯

Если метод не найден, /explain предлагает похожие имена через нечёткий поиск:

Метод не найден: hepa_insert
Возможно, вы имели в виду:
  /explain heap_insert
  /explain heap_inplace
  /explain heap_delete

/watch

Панель наблюдения в реальном времени — подписывается на события gocpg watch и отображает дельты метрик, новые пути распространения данных и оповещения.

# Запустить панель наблюдения
/watch start /путь/к/исходникам

# Проверить статус панели
/watch status

# Остановить панель наблюдения
/watch stop

При запуске панель:

  1. Запускает webhook-приёмник на 127.0.0.1 (порт из config.yamlwatch_dashboard.webhook_port, по умолчанию 8765)
  2. Запускает подпроцесс gocpg watch с указанием webhook
  3. Отображает Rich Live layout с панелями: - Изменённые методы — дельты сложности с цветовой индикацией - Пути распространения данных — новые taint-пути через изменённый код - Оповещения — пороговые оповещения для пиков сложности, входящая связность и новых taint-путей

Конфигурация в config.yaml:

watch_dashboard:
  webhook_port: 8765
  debounce_ms: 1000
  complexity_warning: 15
  complexity_critical: 25
  new_taint_path_alert: true
  fan_in_warning: 20
  panels:
    - changed_methods
    - taint_paths
    - metrics_summary

/scenarios

# Показать все сценарии
/scenarios

# Фильтрация по группе
/scenarios security    # Сценарии, связанные с безопасностью
/scenarios dev         # Сценарии разработки
/scenarios qa          # Сценарии обеспечения качества

/select

# Выбор по номеру
/select 1     # Онбординг
/select 02    # Аудит безопасности
/select 15    # Отладка

/config

# Показать все разделы конфигурации
/config

# Показать конкретный раздел
/config llm

# Установить значение
/config llm temperature 0.7
/config llm provider gigachat

/query

# Простые запросы
/query SELECT COUNT(*) FROM nodes_method
/query SELECT name, filename FROM nodes_method WHERE name LIKE 'heap%'

# Описание таблиц
/query DESCRIBE nodes_method
/query SHOW TABLES

# Сложные запросы
/query SELECT caller.name, callee.name
       FROM edges_call e
       JOIN nodes_method caller ON e.src = caller.id
       JOIN nodes_method callee ON e.dst = callee.id
       WHERE callee.name = 'palloc'
       LIMIT 10

/review

# Интерактивный режим (выбор источника)
/review

# GitHub PR
/review github 123
/review github 123 --format json

# GitLab MR
/review gitlab 456 --inline

# Локальные изменения в git
/review git
/review git --format yaml

# Файл изменений
/review file changes.patch --format md --inline

Руководство по настройке

Настройка поставщика LLM

GigaChat (Sber)

# config.yaml
llm:
  provider: "gigachat"
  gigachat:
    credentials: ${GIGACHAT_AUTH_KEY}
    model: "GigaChat-2"  # или GigaChat-2-Pro, GigaChat-2-Max
    temperature: 0.7
# Переменная окружения
export GIGACHAT_AUTH_KEY="ваш-ключ-в-base64"

OpenAI

# config.yaml
llm:
  provider: "openai"
  openai:
    api_key: ${OPENAI_API_KEY}
    model: "gpt-4"
    temperature: 0.7
# Переменная окружения
export OPENAI_API_KEY="sk-..."

Локальная модель (llama.cpp)

# config.yaml
llm:
  provider: "local"
  local:
    model_path: ${QWEN3_MODEL_PATH}
    n_gpu_layers: -1  # Все слои на GPU
    n_ctx: 8192

Настройки поиска

retrieval:
  embedding_model: "all-MiniLM-L6-v2"
  top_k_qa: 3       # Количество извлекаемых примеров вопросов и ответов
  max_results: 50   # Максимальное количество результатов поиска

Ограничения запросов

query:
  default_limit: 100  # Значение LIMIT по умолчанию для SQL
  max_limit: 1000     # Максимально допустимое значение LIMIT

Приложение: Все 21 сценарий

Название Для кого подходит Пример запроса
01 Онбординг Новые разработчики “Где определена функция X?”
02 Аудит безопасности Команда безопасности “Найти уязвимости к SQL-инъекциям”
03 Документация Технические писатели “Создать документацию для функции X”
04 Разработка функций Добавление новых возможностей “Куда добавить новый хук?”
05 Рефакторинг Очистка кода “Найти неиспользуемый код в модуле X”
06 Производительность Оптимизация “Найти узкие места в производительности”
07 Покрытие тестами Команда тестирования “Какие функции не покрыты тестами?”
08 Соответствие требованиям Аудиторы “Проверить соответствие OWASP Top 10”
09 Проверка кода Рецензенты “Проверить эти изменения”
10 Межрепозиторные связи Архитекторы “Найти зависимости между репозиториями”
11 Архитектура Архитекторы “Найти нарушения уровневой архитектуры”
12 Технический долг Менеджеры “Оценить объём технического долга”
13 Массовый рефакторинг Крупные изменения “Переименовать все X в Y”
14 Реагирование на инциденты Безопасность “Отследить вектор атаки”
15 Отладка Разработчики “Найти точки для отладки”
16 Точки входа Безопасность “Перечислить все конечные точки API”
17 Редактирование файлов Разработчики “Редактировать функцию validate_input”
18 Оптимизация кода Разработчики “Оптимизировать модуль аутентификации”
19 Проверка стандартов QA/Соответствие “Проверить по company_standards.yaml”
20 Зависимости Безопасность/DevOps “Сканировать на уязвимые пакеты”
21 Поиск шаблонов Безопасность/QA “Найти непроверённые возвращаемые значения”

Руководство по выбору сценариев

Для разработчиков: - Первый день: Сценарий 01 (Онбординг) - Разработка функций: Сценарий 04 (Разработка функций) - Исправление ошибок: Сценарий 15 (Отладка) - Очистка кода: Сценарий 05 (Рефакторинг) - Редактирование кода: Сценарий 17 (Редактирование файлов) - Оптимизация: Сценарий 18 (Оптимизация кода)

Для QA / тестировщиков: - Пробелы в покрытии: Сценарий 07 (Покрытие тестами) - Проверка кода: Сценарий 09 (Проверка кода) - Метрики качества: Сценарий 12 (Технический долг) - Стандарты: Сценарий 19 (Проверка стандартов)

Для специалистов по безопасности / DevOps: - Поиск уязвимостей: Сценарий 02 (Аудит безопасности) - Соответствие стандартам: Сценарий 08 (Соответствие требованиям) - Инциденты: Сценарий 14 (Реагирование на инциденты) - Атакуемая поверхность: Сценарий 16 (Точки входа) - Зависимости: Сценарий 20 (Зависимости) - Поиск шаблонов: Сценарий 21 (Поиск шаблонов)

Для технических писателей: - Документация API: Сценарий 03 (Документация) - Архитектура: Сценарий 11 (Архитектура) - Межрепозиторные связи: Сценарий 10 (Межрепозиторные связи)


Отчёты о проверке безопасности (CLI)

Обзор

CodeGraph предоставляет инструмент командной строки (CLI) для создания полных отчётов о проверке безопасности.

Отчёты могут быть сгенерированы в нескольких форматах (Markdown, JSON, SARIF) с поддержкой локализации (английский, русский).

Сценарий: Проверка безопасности проекта на Django

Ситуация: Инженеру по безопасности необходимо проверить проект на Django перед развертыванием в рабочей среде.

Шаг 1: Выполнение полного сканирования безопасности

python -m src.cli.security_audit full \
  --path /path/to/django/project \
  --output-dir ./security_reports \
  --language ru

Шаг 2: Просмотр сгенерированного отчёта

Инструмент создаёт три файла:

  • security_report.md — читаемый отчёт в формате Markdown
  • security_report.json — машинно-читаемый JSON для CI/CD
  • security_report.sarif — формат GitHub Security Alerts

Пример вывода (Markdown)

# Отчёт по безопасности: My Django Project

**Путь к проекту:** `/path/to/django/project`
**Время аудита:** 2025-12-09 20:43:19
**Проанализировано файлов:** 88

Краткое резюме

Серьёзность Количество
🔴 КРИТИЧЕСКИЙ 2
🟠 ВЫСОКИЙ 6
🟡 СРЕДНИЙ 2

🔴 КРИТИЧЕСКИЙ уровень уязвимости (2)

1. SECRET_KEY с резервным значением (сканирование файлов)

Файл: backend/settings.py:25

CWE: CWE-798

Описание: SECRET_KEY имеет небезопасное резервное (fallback) значение

Уязвимый код:

SECRET_KEY = os.environ.get('SECRET_KEY', 'insecure-fallback')

Рекомендация: Удалите резервное значение: SECRET_KEY = os.environ["SECRET_KEY"]

Сценарий: Быстрая проверка безопасности

Ситуация: Разработчик хочет выполнить быструю проверку на уязвимости перед коммитом.

python -m src.cli.security_audit quick --path .

╭─────────────────── Результаты быстрой проверки ───────────────────╮
│                                                                 │
│  Проверено файлов: 45                                           │
│  Время: 0.3с                                                    │
│                                                                 │
│  Обнаружено:                                                    │
│    🔴 Критические: 0                                            │
│    🟠 Высокие: 2                                                │
│    🟡 Средние: 1                                                │
│                                                                 │
│  Запустите 'security-audit full', чтобы получить подробный отчёт │
│                                                                 │
╰─────────────────────────────────────────────────────────────────╯

Сценарий: Интеграция в CI/CD

Ситуация: Добавление проверок безопасности в конвейер GitLab CI.

.gitlab-ci.yml

security-audit:
  stage: test
  script:
    - pip install -r requirements.txt
    - python -m src.cli.security_audit full \
        --path . \
        --output-dir ./security_reports \
        --format json,sarif
    - |
      CRITICAL=$(jq '.summary.critical_issues' security_reports/security_report.json)
      if [ "$CRITICAL" -gt 0 ]; then
        echo "Обнаружены критические уязвимости!"
        exit 1
      fi
  artifacts:
    paths:
      - security_reports/
    reports:
      sast: security_reports/security_report.sarif

Программное использование

Ситуация: Генерация отчётов из кода на Python.

from src.security.file_scanner import FileSecurityScanner
from src.security.report_generator import ReportGenerator

# Инициализация сканера
scanner = FileSecurityScanner()

# Запуск сканирования
result = scanner.scan_project('/path/to/project')

# Генерация отчёта
generator = ReportGenerator()
report = generator.create_report(
    project_name='My Project',
    project_path=result.project_path,
    scan_result=result
)

# Сохранение в нескольких форматах
output_files = generator.save_report(
    output_dir='./reports',
    formats=['markdown', 'json', 'sarif'],
    language='ru'  # Локализация на русский язык
)

print(f"Отчёт сохранён в: {output_files['markdown']}")

Обнаруживаемые шаблоны уязвимостей

Сканер безопасности выявляет шаблоны, специфичные для Django/Python:

ID шаблона Уровень серьёзности Описание
FILE_SECRET_FALLBACK_001 Критический SECRET_KEY с небезопасным резервным значением
FILE_DJANGO_DEBUG_001 Критический DEBUG=True в рабочей среде
FILE_CORS_001 Высокий CORS_ALLOW_ALL_ORIGINS=True
FILE_HOSTS_001 Высокий ALLOWED_HOSTS=[‘*’]
FILE_DB_001 Высокий Стандартный пароль базы данных
FILE_JWT_001 Высокий Срок действия JWT-токена > 24 часов
FILE_PATH_001 Высокий Риск перехода по путям (path traversal)
FILE_DEBUG_PERM_001 Высокий Права доступа зависят от DEBUG
FILE_TOOLBAR_001 Средний Debug toolbar включён безусловно
FILE_PAGESIZE_001 Средний PAGE_SIZE > 1000 (риск DoS)

Раздел соответствия D3FEND

Отчёты включают соответствие стандарту MITRE D3FEND по повышению защищённости исходного кода:


Соответствие D3FEND укреплению исходного кода

Техника Название Статус Применимость
D3-CS Очистка учётных данных Применимо для Python
D3-DLV Валидация доменной логики Применимо для Python
D3-OLV Валидация операционной логики Применимо для Python
D3-VI Инициализация переменных N/A Только C/C++

Общий показатель соответствия: 100% (3/3 применимых техник)

Типовые рабочие процессы

Ежедневная проверка безопасности

# Утренний анализ безопасности
/select 02
> Найти уязвимости в недавно изменённых файлах
/review git
/exit

Еженедельная проверка качества кода

# Еженедельный анализ качества
/select 05
> Найти неиспользуемый код, появившийся на этой неделе

/select 12
> Показать сводку по техническому долгу

/select 07
> Какие новые функции не покрыты тестами?

Аудит перед релизом

# Перед основным релизом
/select 08
> Сгенерировать отчёт о соответствии OWASP Top 10

/select 02
> Найти все критические уязвимости

/review git --format json > audit_report.json

Онбординг нового разработчика

# Настройка первого дня
/select 01
> Объясни общую архитектуру
> Какие основные подсистемы существуют?
> С какого места лучше начать изучение кода?

/save onboarding_session

Темы

Доступные темы

Тема Описание
default Акценты бирюзового цвета, сбалансированный контраст
dark Акценты пурпурного цвета, подходит для тёмного фона
light Акценты синего цвета, подходит для светлого терминала

Использование тем

# Через командную строку
python -m src.tui.app --theme dark

# В config.yaml
tui:
  theme: dark

Элементы темы

Темы настраивают: - Цвета заголовка и подзаголовка - Цвета сообщений (пользователя, ассистента, системы, ошибки) - Цвета рамок - Индикаторы сценариев - Подсветку кода - Индикаторы выполнения


Сессии

Автоматическое управление сессиями

Сессии автоматически: - Создаются при запуске TUI - Сохраняются периодически во время использования - Сохраняются при выходе

Ручное управление сессиями

/save              # Сохранить текущую сессию
/save analysis_v2  # Сохранить с указанием пользовательского имени
/load              # Вывести список сессий
/load analysis_v2  # Загрузить конкретную сессию

Содержимое сессии

Сессии содержат: - Историю диалога - Текущий сценарий - Состояние конфигурации - Контекст проекта - Метаданные (временные метки, количество сообщений)

Расположение хранилища сессий

По умолчанию: ./sessions/

Пользовательский путь: python -m src.tui.app --session-dir /путь/к/сессиям


Советы и рекомендации

Горячие клавиши

Клавиша Действие
Ctrl+C Отменить текущий ввод
Ctrl+D Выйти (с подтверждением)
Стрелка вверх Предыдущая команда (readline)
Стрелка вниз Следующая команда (readline)

Псевдонимы команд

Псевдоним Команда
/h /help
/q /exit
/quit /exit
/stats /stat
/sql /query
/proj /project
/grp /group
/sess /session
/whoami /auth me

Эффективные рабочие процессы

Быстрый аудит безопасности:

/select 2
Найти уязвимости к SQL-инъекциям
Найти риски командных инъекций
Найти уязвимости к XSS

Исследование кода:

/select 1
Что делает функция main?
Покажи граф вызовов для функции X

Процесс проверки кода:

/review git
# Просмотр результатов
/save security_review_dec9

Советы по запросам

  1. Будьте конкретны: “Найти SQL-инъекции в модуле аутентификации” лучше, чем “Найти SQL-инъекции”
  2. Используйте контекст сценария: Выберите подходящий сценарий перед выполнением запроса
  3. Сначала проверьте статистику: Используйте /stat, чтобы понять размер базы данных
  4. Используйте SQL для точности: /query SELECT * FROM nodes_method WHERE name LIKE '%auth%'

Устранение неполадок

Распространённые проблемы

«Copilot недоступен»

Причина: ChromaDB не установлен или инициализация не удалась.

Решения:

pip install chromadb
# или
pip install -r requirements.txt

«База данных не найдена»

Причина: Отсутствует база данных CPG.

Решения: 1. Импортируйте проект:

bash
   python -m src.cli.import_commands full --path ./mycode
  1. Проверьте конфигурацию проекта:
bash
   /project list

«Ошибка поставщика LLM»

Причина: Отсутствуют учётные данные API.

Решения: 1. Проверьте переменные окружения:

bash
   echo $GIGACHAT_CREDENTIALS
   echo $OPENAI_API_KEY
  1. Проверьте config.yaml:
bash
   /config llm

Медленные ответы

Причина: Большая база данных или задержка в сети.

Решения: 1. Проверьте статистику базы данных: /stat 2. Используйте более конкретные запросы 3. Рассмотрите возможность использования локального поставщика LLM 4. Уменьшите размер контекста в config.yaml:

yaml
   llm:
     local:
       n_ctx: 4096  # Уменьшить с 8192

Проблемы с кодировкой символов (Windows)

Причина: Несоответствие кодировки терминала.

Решения:

# Установите UTF-8 в PowerShell
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8

# Или используйте Windows Terminal (рекомендуется)

Режим отладки

Включите логирование отладки для диагностики:

python -m src.tui.app --debug

Это позволяет увидеть: - Вызовы API LLM - Запросы к базе данных - Операции поиска - Трассировки ошибок

Файлы журналов (логов)

Журналы записываются в файл logs/tui.log (если настроено).

Получение помощи

  • Введите /help для справки по командам
  • Введите /help <команда> для справки по конкретной команде
  • Проверьте логи в каталоге logs/
  • Сообщите о проблемах: https://github.com/anthropics/claude-code/issues

Смотрите также


Создано для CodeGraph v1.0