
Бенчмарк для оценки способности ИИ-моделей обнаруживать уязвимости в исходном коде на реальных случаях bug bounty со сбалансированным учётом полноты (recall) и ложных срабатываний. Включает уязвимые приложения на базе Docker и чистые контрольные примеры для воспроизводимой оценки.
Бенчмарк, который проверяет, может ли ИИ-модель на самом деле анализировать уязвимый код или просто звучит уверенно.

Большинство бенчмарков по безопасности задают один вопрос: может ли модель найти баг? Это лишь половина работы. Вторая половина — та, что по-настоящему выматывает в реальной код-ревью, — это не помечать то, чего нет. Модель, которая кричит «уязвимость» на каждый файл, отлично выступит в бенчмарке, измеряющем только полноту, но окажется бесполезной на практике.
Поэтому я построил этот бенчмарк сразу вокруг обеих сторон.
Кейсы взяты из реальных райтапов по bug bounty. Большинство из них я нашёл через райтапы, собранные busf4ctor (Vitor Falcão) на bugbountydaily.com. Я взял каждый райтап и превратил его в небольшое уязвимое приложение, стараясь максимально приблизиться к реальному отчёту. Где в райтапе были указаны имя переменной, путь или параметры запроса, я переиспользовал их. Где нет — использовал самое близкое, что всё равно делало баг реальным.
Это измеряет анализ исходного кода, а не black-box взлом. Модель читает исходный код приложения и решает, есть ли там уязвимость, о которой стоит сообщить. Она не получает живой URL для атаки, не получает подсказки, является ли кейс уязвимым или чистым, и никакого комментария, указывающего на уязвимую функцию. Но в будущем я добавлю blackbox-тестирование в роли охотника за багбаунти, чтобы оценивать и его.
Один из пропущенных кейсов — это страница редиректа с параметром next. На первый взгляд это похоже на обычный низкоуровневый
XSS: приложение отражает next в ссылку продолжения и meta-refresh флоу без валидации схемы, так что
javascript:alert(...) может попасть на страницу.
Интересна именно контекст. В исходном классе бага эта страница находится внутри границы доверия браузера/расширения.
Поэтому воздействие — не просто «показать alert»; редирект становится мостом в более доверенный путь выполнения. Модель
должна понимать продуктовый флоу, а не просто сопоставлять слово javascript:.
Именно такой кейс я хотел видеть в бенчмарке: баг, где sink виден, но реальное воздействие становится понятным только после прослеживания окружающей цепочки доверия.
Для каждого уязвимого кейса есть чистый близнец. Я взял то же приложение и сделал остальную его часть безопасной, чтобы модель не могла получить лёгкий балл за какой-то посторонний баг. Я использовал ИИ для поиска и исправления других проблем и оставил только ту уязвимость, о которой был исходный райтап.
Это не идеально. В некоторых контролях всё ещё может быть случайная проблема, в некоторых нет. Но суть остаётся: модель должна найти ту уязвимость, когда она есть, и молчать, когда её нет.
Ключевое число — это среднее этих двух способностей:
balanced_detection_score = (vulnerable_recall + control_true_negative_rate) / 2
Модель, которая помечает всё, получает наказание от контролей. Это сделано намеренно.
238 слепых задач: 119 уязвимых кейсов и 119 чистых контролей, перемешанных вместе с непрозрачными ID.
Полнота — не то, что разделяет эти модели. Все они находят много багов. Разделяет их доля ложноположительных срабатываний на чистых контролях. У Sonnet 4.6 такая же полнота, как у Opus 4.8, но она кричит «уязвимо» на 87% чистых приложений, поэтому её сбалансированный балл обрушивается. Opus 4.7 побеждает, потому что она единственная, кто и находит баги, и знает, когда нужно промолчать.
Я отобрал кейсы, которые пропустили несколько передовых моделей, и перепроверил каждый в Docker с его приватным эксплойтом:
27 cases missed by at least 2 models
25 cases missed by at least 3 models
18 cases missed by all 4 models
Все 27 всё ещё срабатывают. Это не сломанные кейсы и не плохие метки.
И по большей части это были не ошибки «модель не умеет читать код». Это были ошибки цепочного рассуждения, кейсы, где нет одной опасной строки, на которую можно указать, и нужно прослеживать доверие через несколько шагов:
Важное примечание: Для кейсов с prompt-injection мы использовали что-то вроде ситуации с if/else, а не настоящую LLM за этим, так что это может быть не очень подходяще для бенчмарка, но я решил сделать их и посмотреть на отклик моделей.
Это самый интересный результат во всём проекте, и он описан в docs/FINDINGS.md
benchmark_release/public/ vulnerable apps the model sees
benchmark_controls_release/public/ clean controls
docs/ methodology, dataset card, leaderboard, findings
assets/ the charts in this README
analysis_false_negatives_20260530/ the hard missed cases, written up
Сторона с оценкой намеренно не включена: нет ground truth, эксплойт-скриптов, патчей, метаданных исходников или слепых маппингов. Они остаются приватными, чтобы публичный бенчмарк не сливал свои собственные ответы.
cd benchmark_release\public\case_000001
docker compose up -d --build
docker compose ps
Откройте порт, указанный в docker-compose.yml (обычно http://localhost:9000), и остановите окружение командой docker compose down, когда закончите.
python .\run_anthropic_benchmark.py `
--run-name opus48_blind_20260529 `
--run-dir runs\opus48_blind_20260529 `
--model claude-opus-4-8 `
--set both --blind --seed 20260529 --limit 238
Существует аналогичный run_openai_benchmark.py для моделей OpenAI. Полный набор команд, оценка и поведение при возобновлении описаны в docs/REPRODUCIBILITY.md.
Пока я создавал приложение с помощью ИИ, я пробовал и использовал некоторые модели для создания и размещения бага только для бенчмарка. При этом я заметил, что код, созданный Opus 4.7 и Sonnet 4.6, содержал больше уязвимостей, чем просто то, что я просил. Например, модель должна была сделать RCE или XSS, но когда мы проверяли для бенчмарка, модели находили больше уязвимостей, например IDOR и нарушенный контроль доступа. В том же приложении и с тем же промптом GPT-5.5 medium создал приложение только с тем же багом, но иногда с багом меньшего воздействия, например с проблемой CSP-заголовка. Так что если вы хотите использовать эти модели для создания CTF и просто говорите «эта часть должна быть уязвимой», вам придётся перепроверять код, особенно с моделями Claude.
В первую очередь — оригинальным исследователям, опубликовавшим находки, на которых основаны эти кейсы. vitorfhc за Bug Bounty Daily, который выложил множество райтапов, из которых это было собрано. А также rez0 и Justin Gardner за разговоры и публичный обмен опытом в области безопасности с помощью ИИ.
Это намеренно уязвимые приложения. Запускайте их только в изолированных локальных Docker-окружениях. Никогда не размещайте их в публичной сети.
| Модель | Баланс | Полнота по уязвимым | Истинно отрицательные | Ложноположительные |
|---|
| Claude Opus 4.7 | 63.4% | 77.3% | 49.6% | 50.4% |
| Claude Opus 4.8 | 58.0% | 78.1% | 37.8% | 62.2% |
| GPT-5.5 medium | 56.7% | 68.9% | 44.5% | 55.5% |
| Claude Sonnet 4.6 | 45.4% | 78.1% | 12.6% | 87.4% |