3,583 papers
arXiv:2610.38617 78 28 окт. 2026 г. FREE

Snyk VulnBench 2.0: статический анализатор и ИИ-агент безопасности делят работу, а встроенная политика агента прячет целые классы уязвимостей

КЛЮЧЕВАЯ СУТЬ
Обнаружено: когда встроенная команда /security-review в Claude Code отвечает «чисто», это не значит, что проверены все виды уязвимостей. Исследование Snyk VulnBench 2.0 показывает, как не принимать молчание агента за проверку: связка из статического анализатора и агента с общим аудиторским промптом ловит больше, чем любой из них в одиночку. Её политика исключает ReDoS и пропускает загрязнение прототипа и открытое перенаправление без очень высокой уверенности. Модель могла бы это найти. Инструкция обвязки ей запрещает. В тех же классах без такой политики та же модель нашла 16 уязвимостей из 20 вместо 9.
Адаптировать под запрос

Исследователи проверили, как поиск уязвимостей в коде делят между собой обычный статический анализатор (SAST — программа, которая ищет уязвимости по заранее заданным правилам, без запуска кода) и ИИ-агенты. Главный практический вывод для читателя: ни один из двух подходов не закрывает задачу в одиночку, а встроенная команда /security-review в Claude Code по умолчанию «слепа» к нескольким классам уязвимостей — и это зависит от обвязки (harness), а не от модели.

Ключевая находка про поведение агента: когда ИИ «пропускает» уязвимость, виновата не обязательно модель. Встроенная политика команды /security-review исключает атаки типа ReDoS (отказ в обслуживании через «тяжёлое» регулярное выражение) и допускает отчёт про загрязнение прототипа и открытое перенаправление только при очень высокой уверенности. Модель могла бы это найти, но инструкция ей запрещает. Без такой политики та же модель в тех же классах нашла 16 уязвимостей из 20 вместо 9.

Выход из ситуации — смотреть на связку «анализатор + агент» и не доверять встроенной команде вслепую. Анализатор находит то, что агент не репортит по правилам обвязки (например, открытые перенаправления). Агент находит то, что анализатору не по силам: уязвимости, которые проходят через несколько файлов, и ошибки логики доступа.

🔬

Схема метода

ШАГ 1: Прогон статического анализатора по репозиторию → список находок (быстро, минуты)
ШАГ 2: Прогон ИИ-агента по тому же коду с общим аудиторским промптом, не с урезанной встроенной командой → отчёт агента
ШАГ 3: Объединение двух списков и ручная проверка спорных мест → итоговый перечень уязвимостей

Шаги 1 и 2 независимы и идут отдельными запросами. Шаг 3 делает человек или отдельный запрос к модели.

🚀

Пример применения

Задача: Вы руководите небольшой командой в российском стартапе, где сервис доставки на Python пишут с помощью Claude Code. Перед релизом нужно проверить код на уязвимости. Встроенная команда /security-review вернула «чисто», но есть сомнение, что она смотрит не везде.

Промпт:

Ты проводишь аудит безопасности репозитория этого сервиса доставки.
Проверь все классы уязвимостей без исключений, включая ReDoS (тяжёлые регулярные выражения),
загрязнение прототипа, открытые перенаправления, XSS, SQL-инъекции, обход путей, инъекции команд.
Для каждой находки укажи: класс, файл и строку, где данные приходят от пользователя (источник),
файл и строку, где они попадают в опасную операцию (приёмник), и как это можно эксплуатировать.
Не отбрасывай находки из-за низкой уверенности: пометь уверенность отдельным полем.
Проверяй цепочки, которые проходят через несколько файлов.

Результат: Агент вернёт список находок с указанием источника и приёмника для каждой, с полем уверенности. Среди них должны появиться классы, которые встроенная команда отбрасывала по умолчанию. Часть находок окажется ложной, их придётся проверять вручную.

🧠

Почему это работает

Встроенная команда — это не «голая» модель, а модель плюс набор правил, что считать находкой, а что шумом. Правила вшиты, чтобы отчёт был коротким и достоверным. Побочный эффект: то, что правило считает шумом, агент даже не пытается показать. Слабость в том, что читатель видит результат «ничего не найдено» и принимает его за проверку всех классов.

Сильная сторона модели — рассуждать над кодом с учётом контекста: проследить, как данные идут от запроса через несколько файлов к опасному вызову. Анализатор по правилам делает это хуже в логике доступа, зато быстрее и стабильнее в типовых однофайловых шаблонах.

Метод «общий аудиторский промпт вместо встроенной команды» убирает чужие ограничения и возвращает контроль вам. Рычаги: перечень классов в промпте (добавляйте то, что важно именно вам), требование указывать источник и приёмник (так проще проверить находку), поле уверенности (вместо отбрасывания слабых находок).

📋

Шаблон промпта

В видимой части статьи готового текста промпта авторов нет (приложение с промптами обрезано). Ниже общий шаблон по описанному принципу: убрать фильтр по классам и потребовать источник и приёмник.

Проведи аудит безопасности проекта {название_проекта} на языке {язык}.
Проверь все классы уязвимостей без исключений: {список_классов}.
Для каждой находки выведи: класс, файл:строка источника (где приходят данные от пользователя),
файл:строка приёмника (опасная операция), путь данных между ними, как эксплуатировать.
Не отбрасывай находки из-за низкой уверенности. Укажи уверенность: высокая / средняя / низкая.
Отдельно проверь цепочки через несколько файлов и места, где проверяются права доступа.

Что подставлять: {название_проекта} и {язык} — как в вашем репозитории; {список_классов} — все классы, которые вас волнуют (например, XSS, SQL-инъекция, обход путей, инъекция команд, открытое перенаправление, ReDoS).

🚀 Быстрый старт — вставь в чат агента:

Вот шаблон аудита безопасности. Адаптируй под мой проект: [твоя задача].
Задавай вопросы, чтобы заполнить поля.

[вставить шаблон выше]

Агент спросит про язык, структуру проекта и приоритетные классы — потому что без них список классов и формат находок будут слишком общими.

⚠️

Ограничения

⚠️ Один запуск на ячейку: каждая конфигурация проверена один раз на каждом приложении. Разброс между запусками одного и того же агента авторы не измеряли, поэтому разницу между двумя лучшими вариантами они сами называют статистически неразличимой.

⚠️ Интересы авторов: все авторы работают в Snyk, компании, которая делает анализатор из сравнения. Эталонный набор уязвимостей частично создан с помощью ИИ-ассистента, и авторы сами описывают возможные смещения.

⚠️ Малая выборка: 108 уязвимостей в 20 приложениях, в основном веб-сервисы на четырёх языках. Выводы про другие виды кода и про другие агенты не проверялись.

⚠️ Проверка прохода «без политики»: эксперимент без встроенной политики сделан на 19 из 20 приложений, через месяц после основных запусков, и там не измерено, сколько ложных находок добавилось.

⚠️ Строгая метка: находка засчитывалась, только если указывала и источник, и приёмник с допуском в две строки. Агент мог найти уязвимость, но «промахнуться мимо строки»: в одной из конфигураций Codex Security нашёл 80 уязвимостей на уровне файла, но только 34 — на уровне строки.

🔍

Как исследовали

Команда Snyk собрала 20 открытых веб-приложений на Go, JavaScript/TypeScript, Python и Java и вручную составила список из 108 уязвимостей. Каждая из них достижима для внешнего атакующего, для каждой отмечены источник и приёмник данных и проверен рабочий пример эксплуатации. В 62 случаях путь данных идёт через несколько файлов.

Дальше прогнали девять конфигураций вслепую, без подсказок: статический анализатор Snyk Code, /security-review из Claude Code в трёх вариантах (Opus 5, Sonnet 5, Opus 5 с подключённым анализатором), Codex Security в трёх моделях и сканер DeepSec в двух. Находка считалась, только если попадала в источник и приёмник с допуском в две строки.

Результат: Snyk Code нашёл 89 из 108 (82,4%), Claude Code с Opus 5 на высоком усилии — 85 (79,3%). Они расходятся лишь на 28 уязвимостях (16 против 12), и такая разница на этой выборке неотличима от случайной. Вместе они дают 101 из 108 — столько же, сколько все семь сопоставимых конфигураций вместе. Анализатор добавил уязвимости в однофайловых случаях и классах вроде открытого перенаправления; агент добавил семь межфайловых случаев, включая классы авторизации.

Самое показательное: на 20 уязвимостях в «политических» классах Claude Code нашёл 9, анализатор — 18. Когда ту же модель на том же усилии запустили с общим аудиторским промптом вместо встроенной команды, она нашла 16 из 20. Ещё: более дорогая модель не дала лучшего покрытия — Codex Security с GPT-5.6 Sol стоил в 35 раз больше, чем с Luna, и нашёл на 11 уязвимостей меньше. Анализатор просканировал все 20 приложений за 8 минут, а ИИ-конфигурации — за время от 2,4 до 8,9 часа.

💡

Адаптации и экстраполяции

🔧 Техника: добавить требование «источник → приёмник» в любой аудит → проще проверять находки

Для каждой находки укажи, откуда приходят данные пользователя и куда они попадают, с файлом и строкой в обоих местах.

Так ответ можно быстро сверить с кодом, а общие слова вроде «возможна SQL-инъекция» отсекаются.

Экстраполяция: тот же принцип «проверь, что встроенная команда агента не режет нужное» применим к любой готовой команде или скилу агента. Если команда выдаёт «чисто», запросите у неё список правил, по которым она отбрасывает находки.

🔗

Ресурсы

How Deterministic SAST and AI Security Agents Divide the Work: Coverage, Harness Policy and Cost in Snyk VulnBench 2.0. Liran Tal, Chris Liu, Charlotte Fereday, Sebastian Roth, Brian Clark (Snyk), октябрь 2026. Авторы сообщают, что код, исходные данные, эталонные наборы и все данные запусков опубликованы. Предыдущая работа: VulnBench JS 1.0.


📋 Дайджест исследования

Ключевая суть

Обнаружено: когда встроенная команда /security-review в Claude Code отвечает «чисто», это не значит, что проверены все виды уязвимостей. Исследование Snyk VulnBench 2.0 показывает, как не принимать молчание агента за проверку: связка из статического анализатора и агента с общим аудиторским промптом ловит больше, чем любой из них в одиночку. Её политика исключает ReDoS и пропускает загрязнение прототипа и открытое перенаправление без очень высокой уверенности. Модель могла бы это найти. Инструкция обвязки ей запрещает. В тех же классах без такой политики та же модель нашла 16 уязвимостей из 20 вместо 9.

Принцип работы

Результат агента — это модель плюс правила обвязки. Правила вшиты, чтобы отчёт был коротким. Побочный эффект: всё, что правило считает шумом, агент даже не пытается показать. Не доверяй встроенной команде вслепую: дай агенту свой полный список классов и убери чужой фильтр. Делят работу так: анализатор по правилам ловит типовые шаблоны, например открытые перенаправления. Агент ловит цепочки через несколько файлов и ошибки логики доступа.

Почему работает

Модель умеет рассуждать над кодом с контекстом: проследить, как данные идут от запроса через несколько файлов к опасному вызову. Анализатор с правилами в этом слабее, зато быстрее и стабильнее на однофайловых шаблонах. Различие 9 против 16 из 20 объясняется не умом модели, а инструкцией обвязки. Требование указывать источник данных и опасное место, плюс отдельное поле уверенности вместо отбрасывания слабых находок, помогает потом проверить каждую находку руками.

Когда применять

Проверка кода перед релизом, особенно когда доверяешь встроенной команде агента → конкретно для веб-сервисов, где важны ReDoS, загрязнение прототипа и открытые перенаправления. НЕ подходит как единственная защита: часть находок будет ложной, а выводы получены на 108 уязвимостях в 20 приложениях и не проверены на другом коде.

Мини-рецепт

1. Запусти анализатор: получи быстрый список находок по правилам.
2. Запусти агента отдельно: дай общий аудиторский промпт со своим списком классов, а не урезанную встроенную команду.
3. Требуй источник и приёмник: для каждой находки файл и строка, где данные приходят, и где попадают в опасную операцию.
4. Не режь по уверенности: слабые находки помечай полем, а не выбрасывай.
5. Сложи два списка: спорные места проверь вручную.

Примеры

[ПЛОХО] : /security-review и спокойный релиз после ответа «чисто».
[ХОРОШО] : Проведи аудит безопасности проекта {название_проекта}. Проверь все классы без исключений, включая ReDoS, загрязнение прототипа, открытые перенаправления, XSS, SQL-инъекции, обход путей, инъекции команд. Для каждой находки укажи файл и строку источника данных, файл и строку опасной операции и как это эксплуатировать. Не отбрасывай находки из-за низкой уверенности, пометь её отдельным полем. Проверь цепочки через несколько файлов. Авторы работают в Snyk, чей анализатор участвовал в сравнении, и сами оговаривают возможные смещения.
Источник: How Deterministic SAST and AI Security Agents Divide the Work: Coverage, Harness Policy and Cost in Snyk VulnBench 2.0
ArXiv ID: 2610.38617 | Сгенерировано: 2026-10-30 06:55

Проблемы LLM

ПроблемаСутьКак обойти
Встроенная команда аудита безопасности молча пропускает целые классы уязвимостейЗапускаешь готовую команду проверки безопасности в агенте для кода. Получаешь "чисто". Но её правила вшиты в обвязку: часть атак исключена, часть показывается только при очень высокой уверенности. Модель могла бы найти их, но инструкция запрещает. Читатель принимает "ничего не найдено" за проверку всех классовНе доверяй встроенной команде вслепую. Запусти общий аудиторский запрос без исключений. Перечисли нужные классы явно. Требуй поле уверенности вместо отбрасывания слабых находок. Без вшитой политики та же модель нашла 16 уязвимостей из 20 в этих классах вместо 9
Один инструмент безопасности не закрывает задачу целикомСтатический анализатор по правилам быстр и стабилен на типовых однофайловых шаблонах, но плох в логике доступа и цепочках через несколько файлов. Агент хорошо рассуждает о цепочках, но отбрасывает часть классов по правилам обвязки. Каждый в одиночку оставляет дырыИспользуй связку. Шаг 1: анализатор по репозиторию. Шаг 2: агент с общим аудиторским запросом. Шаг 3: объедини списки и проверь спорные места вручную

Методы

МетодСуть
Общий аудиторский запрос вместо урезанной встроенной командыНапиши свой запрос аудита. Перечисли все классы уязвимостей без исключений. Для каждой находки требуй: класс, файл и строку источника (откуда приходят данные пользователя), файл и строку приёмника (опасная операция), путь данных между ними, способ эксплуатации. Добавь Не отбрасывай находки из-за низкой уверенности, укажи уверенность: высокая / средняя / низкая. Отдельно попроси проверить цепочки через несколько файлов и места проверки прав. Почему работает: убирает чужие вшитые ограничения и возвращает контроль вам. Пара источник-приёмник упрощает проверку находки. Когда применять: перед релизом, когда готовый отчёт слишком чистый. Когда не работает: часть находок будет ложной, их проверяют вручную. Без списка важных вам классов запрос слишком общий
Связка анализатор + агент с ручной проверкой спорногоЗапусти статический анализатор по репозиторию. Отдельным запросом запусти агента с аудиторским запросом. Объедини два списка. Спорные места проверь вручную или отдельным запросом к модели. Почему работает: анализатор находит то, что агент не показывает по правилам обвязки, например открытые перенаправления. Агент находит то, что анализатору не по силам: уязвимости через несколько файлов и ошибки логики доступа. Когда применять: важная кодовая база. Когда не работает: нет времени на ручную проверку объединённого списка

Тезисы

ТезисКомментарий
Пропуск уязвимости агентом не всегда вина моделиВстроенная команда это модель плюс набор правил, что считать находкой, а что шумом. Правила делают отчёт короче и достовернее, но то, что они считают шумом, агент даже не пытается показать. Результат "ничего не найдено" относится только к разрешённым классам. Применяй: читай политику готовой команды. Если классы исключены, закрывай их отдельным запросом
Проверка по источнику и приёмнику упрощает проверку находкиКогда агент указывает строку, где данные приходят от пользователя, и строку, где они попадают в опасную операцию, находку легко проверить глазами. Без пары строк остаётся расплывчатое "тут есть риск". Применяй: в запросе аудита требуй оба места и путь данных между ними. Допуск по строкам делай небольшим, иначе находка на уровне файла не станет находкой на уровне строки
📖 Простыми словами

How Deterministic SAST and AI Security Agents Divide the Work: Coverage, Harness Policy and Cost in Snyk VulnBench 2.0

arXiv: 2610.38617

Твой AI-ассистент по безопасности врёт тебе не потому, что тупой, а потому, что его заставили быть удобным пай-мальчиком. Встроенные команды вроде /security-review — это не чистая нейронка, а модель с жестким намордником фильтрации (harness policy). Создатели тупо глушат всё, что кажется спорным, лишь бы не спамить ложными срабатываниями. В итоге статус «уязвимостей нет» означает не чистый код, а то, что модель просто промолчала в тряпочку о куче подозрительных мест.

Это как вызвать клининг перед важными гостями, где уборщик смахнул пыль с тумбочки, а весь остальной хлам ногой запихал под ковер и бодро рапортует: «хозяин, всё блестит». Формально отчет короткий и красивый, глаз радуется, но под диваном уже гниет бутерброд. Ты свято веришь, что прошел полноценный аудит безопасности, а агент просто выкинул 80% реальных находок, решив за тебя, что это «пустой шум».

Исследование на свежем бенчмарке Snyk VulnBench 2.0 наглядно показывает, как надо: детерминированный SAST и AI-агенты обязаны делить работу. Классический статический анализатор туп как дрова, но за три копейки гарантированно выгребает 100% известных паттернов вроде кривых SQL-запросов. А вот нейросетевые агенты хороши в глубоком контексте, но из-за политики обвязки теряют покрытие и в соло превращаются в решето.

Тестировали на Python и Claude Code, но грабли абсолютно универсальны. Ровно та же беда сидит в GitHub Copilot, Cursor и любом модном стартап-пайплайне, где безопасность бездумно спихнули на один промпт. Надеяться на одну волшебную кнопку проверки — гарантированный способ словить взлом в первую же неделю после деплоя.

Короче: зеленый статус от AI-команды — это опасная иллюзия, а не гарантия защиты. Загоняй в CI/CD жесткий детерминированный сканер вроде Semgrep или Snyk для железной базы, а агенту скармливай только точечные спорные куски. Иначе за эту погоню за «удобными отчетами» стартап заплатит слитой базой клиентов.

Работа с исследованием

Адаптируйте исследование под ваши задачи или создайте готовый промпт на основе техник из исследования.

0 / 2000
~0.5-2 N-токенов ~10-30с
~0.3-1 N-токенов ~5-15с