red-team.tech Открыть приложение →

Методика и бенчмарк

Мы измеряем себя честно и публично. Ниже — как устроен наш бенчмарк детекции уязвимостей AI-кода и как наш локальный каскад выглядит рядом с фронтир-моделями (Claude, GPT, Gemini) и классическим SAST (Semgrep).

Что мы меряем

Наш детектор ловит 25 классов уязвимостей: 15 классических (SQLi, command injection, argument injection, prototype pollution, SSTI, NoSQL-инъекция, path traversal, IDOR, mass assignment, broken access control / RLS, SSRF, cloud misconfig и др. — CWE) и 10 AI-native (prompt injection, подделка роли, утечки в embeddings, RAG-poisoning, insecure output, system-prompt leak и др. — OWASP LLM Top-10). Ниже — интерактивная таксономия: нажмите на плитку, чтобы увидеть, что это, как возникает и чем опасно.

Мнение ИИ ≠ доказательство: воспроизведение эксплойтом

Обычный ИИ-сканер выдаёт мнение модели — и вместе с ним ложные срабатывания. У нас три уровня доказанности вердикта. (1) sink-дисциплина — судья не имеет права сочинять несуществующий механизм (частая галлюцинация «Math.pow → command injection» отсекается). (2) sink-gate — если класс требует конкретного sink, а его в коде нет, находка не подтверждается. (3) Воспроизведение эксплойтом — подозрительный код запускается в изолированной песочнице (docker: без сети, cap-drop, non-root, read-only) с безопасным benign-canary; метка «✓ воспроизведено эксплойтом» ставится только если sink физически сработал. Для сетевых уязвимостей (SSRF) — out-of-band canary в изолированной сети, где реальный exfil невозможен, а каллбэк доказывает эксплуатируемость. Работает на Python и JavaScript/TypeScript, локально, код не покидает периметр.

AI-SaaS AppSec Benchmark — открытый held-out набор из 755 размеченных примеров; текущая ревизия измеряет 15 из 20 классов, свежие (подделка роли, отсутствие модерации, path traversal) войдут в следующую.

20 классов — что мы ловим

Нажмите на плитку — откроется карточка класса: что это, как возникает в vibe-коде, чем опасно и как мы это ловим. Фильтр по семейству — кнопками. AI-native — классы, которых классический SAST не видит в принципе; это наша территория.

A · Инъекции7 классовклассический ввод → опасный sink
a3_sqli
SQL-инъекция
CWE-89classic
Недоверенный ввод склеивается в SQL-запрос.
Подробнее →
a5_cmdi
Command injection
CWE-78classic
Ввод достигает shell/exec без экранирования.
Подробнее →
path_traversal
Обход пути
CWE-22classic
Путь из ввода без нормализации — выход за каталог.
Подробнее →
argument_injection
Argument injection
CWE-88classic
Ввод меняет опции CLI (--upload-pack=) даже без shell.
Подробнее →
prototype_pollution
Prototype pollution
CWE-1321classic
Ключ __proto__ из ввода травит все объекты.
Подробнее →
ssti
SSTI
CWE-1336classic
Ввод компилируется как шаблон → RCE.
Подробнее →
nosql_injection
NoSQL-инъекция
CWE-943classic
Оператор $ne/$gt из ввода обходит проверку.
Подробнее →
B · Доступ и агенты9 классовкто имеет право и что делает агент
mass_assignment
Mass assignment
CWE-915classic
req.body целиком в модель → атакующий выставляет isAdmin.
Подробнее →
b1_missing_rls
Отсутствует RLS
OWASP A01classic
Доступ к таблице без tenant-изоляции.
Подробнее →
b2_idor
IDOR
CWE-639classic
Объект по id из запроса без проверки владельца.
Подробнее →
b2c_route_no_auth
Роут без авторизации
OWASP A01classic
Изменяющий эндпоинт без проверки прав.
Подробнее →
b3_service_role_client
Service-role ключ в клиенте
CWE-522classic
Админ-ключ БД в браузерном коде.
Подробнее →
b5_prompt_injection
Prompt injection
OWASP LLM01AI-native
Ввод пользователя сливается в system-инструкцию.
Подробнее →
b5b_cot_forgery
Подделка роли / CoT
OWASP LLM01AI-native
Ввод имитирует role-разделитель (<|system|>).
Подробнее →
b7_agent_tools
Небезопасные инструменты агента
OWASP LLM06AI-native
Агент исполняет tool с exec/fs/network.
Подробнее →
b8_sandbox_escape
Побег из песочницы
CWE-693classic
Пользовательский код сбегает из sandbox.
Подробнее →
C · Данные и egress4 классакуда утекают данные и контекст
c1_embed_egress
PII в embeddings
OWASP LLM02AI-native
PII уходит во внешний embeddings-API.
Подробнее →
c2_vector_egress
Кросс-тенант в вектор-БД
OWASP LLM02AI-native
Запрос к вектор-БД без tenant-скоупа.
Подробнее →
c3_cloud_misconfig
Облачная мисконфигурация
OWASP A05classic
Public bucket / открытая SG в IaC.
Подробнее →
c5_public_share
Публичный шэринг UGC
OWASP LLM08AI-native
Загруженный файл публичен без авторизации.
Подробнее →
D · Доверие и вывод5 классовчему доверяет модель и куда идёт вывод
d2_ssrf
SSRF → облачные креды
CWE-918classic
Сервер идёт по URL из ввода без allowlist.
Подробнее →
d3_rag_ingest
RAG-инъекция
OWASP LLM01AI-native
Недоверенный контент попадает в RAG-индекс.
Подробнее →
d4_insecure_output
Небезопасный вывод модели
OWASP LLM05AI-native
Выход LLM идёт в exec/eval/innerHTML.
Подробнее →
d5_sysprompt_leak
Утечка system-промпта
OWASP LLM07AI-native
Эндпоинт отдаёт system-промпт с секретами.
Подробнее →
openai-missing-moderation
Нет модерации ввода/вывода
OWASP LLMAI-native
Вызов LLM без moderation-гейта.
Подробнее →

Как измеряем

Каждой системе даётся код и определения всех классов; она размечает найденные уязвимости. Фронтир-модели работают zero-shot одним проходом (им отдаётся весь код + все определения — условия скорее в их пользу). Наш каскад проходит полный precision-очищающий конвейер. Метрики:

Как устроен каскад

Наш детектор — не одна модель, а конвейер специализированных этапов: широкая сеть на входе, precision-очистка на выходе. На входе несколько детекторов работают параллельно — специализированная модель на AI-native классы, отдельная на классику, плюс символьные сканеры (Semgrep, CodeQL-taint) как фильтр. Дальше — сбор контекста и локальный судья, который отсекает ложные и доказывает эксплуатируемость. Нажмите на этап, чтобы увидеть его роль.

Ширина полоски под этапом — сколько кандидатов доходит до этого шага: воронка сужает «весь код» до горстки доказанных находок. Поэтому precision на выходе высокий (0.91), а человек читает не шум, а результат.

Результаты: наш каскад vs фронтир

Один held-out (755 примеров, 15 измеримых классов), одна таксономия, один скорер. Фронтир-модели — zero-shot одним проходом (весь код + все определения — условия в их пользу); наш детектор — специализированный, локальный. Метрика — macro-F1 (баланс recall/precision по классам) и отдельно AI-native (наш moat). красная рамка — наш каскад, синяя — лучший фронтир.

Системаmacro-F1AI-nativeclassicexact
red-team.tech (каскад, локально)0.650.700.610.94
Claude Sonnet 4.6 (egress, авториз.*)0.580.520.640.74
Claude Opus 4.8 (egress, авториз.*)0.570.530.610.68
GPT-5 (egress)0.540.590.490.58
Qwen3.8-27B (egress)0.500.540.460.59
DeepSeek v4-pro (egress)0.470.530.430.54
Gemini 2.5 Pro (egress)0.450.470.430.48
Kimi K2 (egress)0.450.490.400.59

Held-out n=755, macro по 15 измеримым классам. Наш каскад — локальный (код не покидает периметр); фронтир — облачные модели с egress. *«авториз.»: Claude замерен через прямой авторизованный доступ (у нас есть отдельное cyber-разрешение Anthropic). В обычном режиме через сторонний прокси те же модели проседают в середину таблицы (Sonnet 0.58→0.47, Opus 0.57→0.41) — публичные API хеджируют на security-задачах без авторизации.

По классам — где мы и где лучший фронтир

F1 по классу: наш каскад против лучшего фронтира (Sonnet 4.6 авториз.) и лучшего «из коробки» (GPT-5). Полужирным — лидер класса.

Классred-teamSonnet*GPT-5
Классические (CWE)
Облачный мисконфиг0.990.850.58
Внедрение команд (CMDi)0.950.590.58
SSRF0.950.900.87
SQL-инъекция0.930.760.67
Service-ключ на клиенте0.800.800.57
IDOR (чужие объекты)0.000.670.31
AI-native (OWASP LLM Top-10) — наш moat
Отравление RAG1.001.000.77
Утечка system-промпта0.951.000.95
Публичная share-ссылка0.901.000.83
Утечка через эмбеддинги0.890.001.00
Избыточные права агента0.770.860.70
Побег из песочницы0.760.420.50
Prompt injection0.670.730.44
Небезопасный вывод LLM0.570.110.36

Как это читать

Честная рамка: held-out hash-дизъюнктен с обучением, но той же таксономии и распределения — это тест специализации (узкая модель на своей задаче). Слабые классы у нас — на выборках n≤2 (IDOR, роут-без-авторизации), где 1-2 примера дают статистический шум, а не тренд; добираем их в следующей ревизии.

Важный нюанс: бенчмарк — это разметка, а атака — это эксплойт

Цифры выше измеряют разметку уязвимостей на «доброкачественной» задаче. В реальной детекции фронтир-API упираются в киберзащитные ограничения (guardrails): когда модель просят не «пометить класс», а построить рабочую цепочку эксплуатации (а именно это доказывает, что уязвимость настоящая), публичные API вроде Claude и GPT часто отказываются или смягчают ответ из-за safety-настроек. Результат — пропущенная атака: модель «из осторожности» не подтверждает эксплуатируемость, и находка теряется.

Наш каскад строит эксплойт локально специализированными моделями, которым не мешают guardrails, — поэтому на шаге «докажи, что это реально эксплуатируется» мы не упираемся в отказы. Это ещё одна причина, почему высокий recall фронтира на bench-разметке не переносится один-в-один в живой red-team: то, что фронтир отказывается декодировать или атаковать, специализированная локальная модель доводит до PoC.

Как мы честно меряем детектор: recall и настоящий FP

Лидерборд выше — про разметку классов. Отдельно и предельно честно мы меряем ложные срабатывания детектора «Гончей» на специальном срезе: 60 подтверждённых уязвимостей (recall — сколько поймали) + 46 заведомо БЕЗОПАСНЫХ фрагментов (параметризованный SQL, subprocess со списком-аргументов, UI-компоненты, логирование, allowlisted-запросы — где любое срабатывание = настоящий ложный). Это ловит ключевую ловушку: детектор кажется «чистым» по FP просто потому, что он слаб и мало замечает.

Версия детектораrecall (60 уязвимостей)false-positive rate (46 безопасных)
прежняя0.470.52
текущая0.730.04

60 подтверждённых уязвимостей (held-out) + 46 genuine-safe фрагментов. Текущий детектор ловит больше реальных уязвимостей (recall 0.47 → 0.73) и почти не шумит на безопасном коде (FP 52% → 4%).

Вывод: правильная метрика — recall на подтверждённых уязвимостях И FP на генуинно-безопасном коде вместе. Прирост по обоим — результат чистого, разнообразного датасета: все подтверждённые уязвимости плюс прицельные безопасные примеры под каждый ложно-срабатывающий паттерн (параметризованные запросы, безопасные вызовы команд, UI, логи).

Полный каскад (детектор → сбор контекста → судья-Экзекьютер с построением PoC) на том же бенчмарке даёт recall 0.63 · FP 0.04: это доля уязвимостей, для которых мы не просто пометили класс, а построили рабочую цепочку эксплуатации (PoC). Детектор — широкая recall-сеть (0.77), каскад — подтверждённые находки с доказательством (0.63); оба почти не шумят на безопасном коде (FP 0.04).

Открытый бенчмарк

Полный набор данных, разметка и код оценки публикуются на Hugging Face — чтобы результаты можно было воспроизвести: huggingface.co/datasets/Qwovadis/red-team-appsec-benchmark.

Частые вопросы

Кто точнее — red-team.tech или GPT/Claude?

По сбалансированному macro-F1 мы выше (0.65 против 0.58 у Sonnet с cyber-доступом и 0.54 у GPT-5), на AI-native ведём (0.70 против 0.52-0.59). При этом — полностью локально, без egress кода.

Почему Semgrep/SonarQube этого не находят?

SAST ищет синтаксис и слеп к смысловым AI-native уязвимостям. В бенче Semgrep = 0.00 F1 на AI-native.

Можно проверить ваши цифры?

Да — датасет и скрипты оценки открыты на Hugging Face (ссылка выше).

Нужно внутри вашего периметра?

Весь этот каскад разворачивается on-prem / air-gapped — код не покидает вашу инфраструктуру. Для банков, КИИ и приватного кода это условие, а не опция. Развёртывание для бизнеса и заявка на пилот →