Методика и бенчмарк
Мы измеряем себя честно и публично. Ниже — как устроен наш бенчмарк детекции уязвимостей 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 не видит в принципе; это наша территория.
Как измеряем
Каждой системе даётся код и определения всех классов; она размечает найденные уязвимости. Фронтир-модели работают zero-shot одним проходом (им отдаётся весь код + все определения — условия скорее в их пользу). Наш каскад проходит полный precision-очищающий конвейер. Метрики:
- Recall — доля реальных уязвимостей, которые система поймала.
- Precision — доля срабатываний, которые оказались настоящими.
- macro-F1 — баланс recall и precision, усреднённый по классам.
- LOAD — число ложных срабатываний на один пример (шум, который читает человек).
Как устроен каскад
Наш детектор — не одна модель, а конвейер специализированных этапов: широкая сеть на входе, precision-очистка на выходе. На входе несколько детекторов работают параллельно — специализированная модель на AI-native классы, отдельная на классику, плюс символьные сканеры (Semgrep, CodeQL-taint) как фильтр. Дальше — сбор контекста и локальный судья, который отсекает ложные и доказывает эксплуатируемость. Нажмите на этап, чтобы увидеть его роль.
Ширина полоски под этапом — сколько кандидатов доходит до этого шага: воронка сужает «весь код» до горстки доказанных находок. Поэтому precision на выходе высокий (0.91), а человек читает не шум, а результат.
Результаты: наш каскад vs фронтир
Один held-out (755 примеров, 15 измеримых классов), одна таксономия, один скорер. Фронтир-модели — zero-shot одним проходом (весь код + все определения — условия в их пользу); наш детектор — специализированный, локальный. Метрика — macro-F1 (баланс recall/precision по классам) и отдельно AI-native (наш moat). ■ красная рамка — наш каскад, ■ синяя — лучший фронтир.
| Система | macro-F1 | AI-native | classic | exact |
|---|---|---|---|---|
| red-team.tech (каскад, локально) | 0.65 | 0.70 | 0.61 | 0.94 |
| Claude Sonnet 4.6 (egress, авториз.*) | 0.58 | 0.52 | 0.64 | 0.74 |
| Claude Opus 4.8 (egress, авториз.*) | 0.57 | 0.53 | 0.61 | 0.68 |
| GPT-5 (egress) | 0.54 | 0.59 | 0.49 | 0.58 |
| Qwen3.8-27B (egress) | 0.50 | 0.54 | 0.46 | 0.59 |
| DeepSeek v4-pro (egress) | 0.47 | 0.53 | 0.43 | 0.54 |
| Gemini 2.5 Pro (egress) | 0.45 | 0.47 | 0.43 | 0.48 |
| Kimi K2 (egress) | 0.45 | 0.49 | 0.40 | 0.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-team | Sonnet* | GPT-5 |
|---|---|---|---|
| Классические (CWE) | |||
| Облачный мисконфиг | 0.99 | 0.85 | 0.58 |
| Внедрение команд (CMDi) | 0.95 | 0.59 | 0.58 |
| SSRF | 0.95 | 0.90 | 0.87 |
| SQL-инъекция | 0.93 | 0.76 | 0.67 |
| Service-ключ на клиенте | 0.80 | 0.80 | 0.57 |
| IDOR (чужие объекты) | 0.00 | 0.67 | 0.31 |
| AI-native (OWASP LLM Top-10) — наш moat | |||
| Отравление RAG | 1.00 | 1.00 | 0.77 |
| Утечка system-промпта | 0.95 | 1.00 | 0.95 |
| Публичная share-ссылка | 0.90 | 1.00 | 0.83 |
| Утечка через эмбеддинги | 0.89 | 0.00 | 1.00 |
| Избыточные права агента | 0.77 | 0.86 | 0.70 |
| Побег из песочницы | 0.76 | 0.42 | 0.50 |
| Prompt injection | 0.67 | 0.73 | 0.44 |
| Небезопасный вывод LLM | 0.57 | 0.11 | 0.36 |
Как это читать
- Лидируем по общему балансу. macro-F1 0.65 против 0.58 у лучшего фронтира (Sonnet 4.6 с авторизованным доступом) и 0.54 у GPT-5 — узкий специализированный каскад бьёт универсальные модели на своей задаче.
- AI-native — наша территория. macro-F1 0.70 на AI-native классах против 0.52–0.59 у фронтира. Это OWASP LLM Top-10 (prompt injection, утечки в embeddings, RAG-poisoning, insecure output) — то, что классический SAST не видит в принципе.
- Обходим даже Claude с cyber-доступом. Мы выше direct-Sonnet (0.65 vs 0.58) и GPT-5 по AI-native (0.70 vs 0.59) — при этом полностью локально.
- Локальность (no-egress). Всё — на вашей машине, код никуда не отправляется. Для приватного, корпоративного и КИИ-кода это условие, а не «плюс».
Честная рамка: 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.47 | 0.52 |
| текущая | 0.73 | 0.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 — код не покидает вашу инфраструктуру. Для банков, КИИ и приватного кода это условие, а не опция. Развёртывание для бизнеса и заявка на пилот →