Перейти к содержанию
Публикация AiManual

Фаззер против LLM-агента: как Fuzzilli и BigSleep ищут уязвимости в V8 и почему они пока дополняют друг друга

Project Zero сравнила фаззер Fuzzilli и LLM-агента BigSleep на движке V8: 45 против 37 исправленных уязвимостей за полгода при пересечении около четверти. Разби

Коротко

Что будет в материале

  1. 01

    Что именно сравнили в Project Zero: условия эксперимента и главные цифры

  2. 02

    Как работает Fuzzilli: непрерывный генеративный фаззинг JavaScript-движков

  3. 03

    Как работает BigSleep: LLM-агент, который раз в сутки читает коммиты

  4. 04

    45 против 37: что на самом деле говорят цифры и почему пересечение считают по-разному

Project Zero сравнила два автоматических конвейера поиска уязвимостей в V8, JavaScript-движке Chrome: непрерывно работающий фаззер Fuzzilli и LLM-агент BigSleep, который раз в сутки просматривает новые коммиты. За апрель-сентябрь 2026 года после очистки от дубликатов и нерабочих репортов у BigSleep оказалось 45 исправленных уязвимостей, у Fuzzilli 37. Пересечение по баг-трекеру составило 20 из 81 репорта, около четверти. Методику, подсчёты и разбор конкретных багов Самуэль Гросс (Samuel Groß) описал в блоге Project Zero, русский перевод статьи опубликован на Habr.

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

Дальше разберём механику Fuzzilli и BigSleep, расшифруем, почему пересечение считают и как четверть, и как 60%, посмотрим на эксперимент со 112 старыми багами и соберём практическую схему для своей команды.

Что именно сравнили в Project Zero: условия эксперимента и главные цифры

Сравнивали два рабочих конвейера, а не лабораторные прототипы. Fuzzilli крутится постоянно на множестве инстансов и живёт в ритме свежих сборок. BigSleep запускается раз в сутки, получает задание просмотреть новые коммиты и для каждого найденного бага написать тесткейс, доказывающий проблему (proof-of-concept). Дальше репорты проходили общую очистку: дубликаты и нерабочие находки из статистики убирали, поэтому 45 и 37 это число исправленных уязвимостей, а не число срабатываний.

Третий показатель, без которого первые два читаются неверно, это пересечение. Его считали отдельно, с дополнительным поиском дубликатов через коммиты-исправления и базу Clusterfuzz: общими оказались 20 из 81 репорта. Проще говоря, примерно четверть найденного встретилась в обоих списках, а остальное каждый инструмент нашёл в одиночку.

Почему V8 - удобный полигон для такого сравнения

V8 это JavaScript-движок Chrome с крупной кодовой базой и интенсивным потоком коммитов. Такой профиль удобен сразу для двух конвейеров: непрерывный фаззер успевает проверять свежие изменения, а агент получает поток диффов, по которым можно рассуждать о причинах поломок. Обе системы к тому же работают на одном и том же коде, что делает сравнение осмысленным.

Ограничение стоит держать в голове с первого абзаца: сравнили один движок, один проект и две конкретные продакшен-системы. Цифры 45 и 37 нельзя переносить на произвольную кодовую базу как норму или ожидание.

Как работает Fuzzilli: непрерывный генеративный фаззинг JavaScript-движков

Fuzzilli это генеративный фаззер для JavaScript-движков. Он строит синтаксически корректные JS-программы, а не мутирует случайные байты, и следит за аномалиями в поведении движка. Такой подход позволяет заходить в глубину языка: генератор собирает конструкции, до которых случайный перебор файлов не доберётся.

Работа идёт непрерывно на множестве инстансов. Первые из них обычно подхватывают новые изменения в течение нескольких часов: правка попала в репозиторий, и уже через пару часов её прогоняют в реальных условиях. За апрель-сентябрь 2026 года фаззер дал 37 исправленных уязвимостей.

Сильные стороны предсказуемы. Круглосуточная работа без участия человека, огромное число прогонов, независимость от того, понял ли кто-то смысл изменений. Фаззеру не нужно читать дифф, ему нужно его выполнить.

Ограничения тоже предсказуемы. Фаззеру нужен сигнал: крэш, сработавший ассерт, расхождение поведения. Логическая ошибка без явного падения для него почти невидима. Причину поломки он не объясняет: на выходе сигнал о проблеме, а разбор и поиск корня достаются человеку. Тесткейсы-PoC и патчи пишет не фаззер.

Как работает BigSleep: LLM-агент, который раз в сутки читает коммиты

BigSleep это агентная система поиска багов на основе LLM. Раз в сутки она получает задание просмотреть новые коммиты и для каждого найденного бага подготовить proof-of-concept, то есть тесткейс, который демонстрирует проблему при прогоне.

Режим работы объясняет природу результата. Агент читает диффы и рассуждает о том, что могло сломаться рядом с изменением. По характеру это ближе к ревью кода, чем к перебору входных данных: инструмент ищет смысловую нестыковку, а не падение на случайном вводе. За апрель-сентябрь 2026 года такой подход дал 45 исправленных уязвимостей.

Ограничения начинаются с темпа. Суточный цикл против нескольких часов у фаззера означает более позднюю реакцию на свежие изменения. Дальше идёт зависимость от качества диффа и объёма контекста вокруг него: чем менее очевиден коммит, тем сложнее агенту восстановить картину. И ложные срабатывания, из-за которых в методике и появилась очистка от нерабочих репортов.

Отдельная оговорка по моделям. В основном прогоне BigSleep конкретная модель в пересказе статьи не раскрывается, поэтому приписывать системе определённую версию не стоит. Gemini 3.6 flash фигурирует только в отдельном эксперименте с историческими багами.

ПоказательFuzzilliBigSleep
Режим работынепрерывно, множество инстансовраз в сутки, по новым коммитам
Исправленных уязвимостей, апрель-сентябрь 20263745
Что даёт на выходесигнал о поломке: крэш, ассерт, расхождение поведениятесткейс, доказывающий проблему
Опорный сигналреальный прогон кодадифф и рассуждение о последствиях

45 против 37: что на самом деле говорят цифры и почему пересечение считают по-разному

Разница в восемь багов при базе 37 и 45 это не турнирная таблица. Перед нами два разных способа находить ошибки, и главный результат исследования в другом: заметная часть уязвимостей нашлась только одним из инструментов.

Теперь про два числа пересечения, которые легко принять за противоречие. Первое, 20 из 81 или около четверти, получено по баг-трекеру с дополнительным поиском дубликатов через коммиты-исправления и базу Clusterfuzz. Второе, около 60%, это теоретическое пересечение из дополнительных экспериментов на уязвимостях, найденных с 2023 года.

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

Практический вывод из обоих чисел одинаковый: инструменты находят в значительной степени не совпадающие наборы багов. Даже при оценке в 60% остаётся 40% находок, которые второй инструмент пропустил.

Проверка на запоминание обучающих данных

Главный контраргумент к любому впечатляющему результату LLM в поиске уязвимостей звучит так: модель могла видеть баг и его исправление в обучающих данных, и тогда находка ничего не доказывает. В статье Самуэля Гросса эта проверка разобрана отдельно, детализированная методика осталась в оригинале, в переводе она изложена сжато.

Логика проверки в том, чтобы отделить узнавание знакомого паттерна от анализа нового кода. Пока такое разделение не сделано, цифры вроде 45 выглядят убедительнее, чем есть на самом деле. Для любого, кто оценивает агентные инструменты безопасности, это обязательный пункт программы, а не формальность.

Эксперимент со 112 старыми багами: сколько находит агент на Gemini 3.6 flash

Отдельный эксперимент проверял способность агента восстанавливать уже известные проблемы. Агент на модели Gemini 3.6 flash получал коммиты, которые, вероятно, внесли 112 старых багов Fuzzilli. На каждый коммит отводилось 25 попыток, заново агент нашёл около 62% багов. С дополнительными промптами доля выросла примерно до 70%.

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

25 попыток на коммит это бюджет, а не один запрос. Результат зависит от бюджета напрямую: больше попыток, больше шансов зацепиться за нужный участок кода. И 62-70% означают, что 30-38% багов агент не восстановил даже с таким запасом попыток.

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

Что даёт рост с 62% до 70% при дополнительных промптах

Рост дали дополнительные промпты, то есть уточнение задачи и контекста. Модель осталась той же, изменилась постановка. Для практики вывод простой: качество формулировки задачи напрямую влияет на результат, поэтому промпты стоит держать в том же репозитории, что и сам пайплайн, и версионировать вместе с ним.

Конкретные формулировки из эксперимента в пересказе не приводятся, воспроизвести их дословно не получится. Настраивать промпты придётся под свой код и свой стиль коммитов.

Где фаззер по-прежнему сильнее, а где проседает агент

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

В JIT-компиляторах пересечение между результатами меньше. Причина в характере багов: они часто висят на тонких деталях работы JIT и на состоянии, которое тяжело восстановить из диффа без запуска. Агенту приходится рассуждать о том, чего он не видит, а фаззеру достаточно выполнить код и дождаться расхождения.

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

Инструменты ошибаются в разных местах. Именно поэтому заметная часть уязвимостей находится только одним из них, и именно поэтому совет авторов применять оба подхода выглядит обоснованным, а не осторожным.

Три разобранных бага: что нашёл только агент и что - только фаззер

В переводе статьи разобраны три бага: часть нашлась только агентом, один только фаззером. Номера и CVE в пересказе не приводятся, поэтому ограничимся распределением ролей.

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

Практический вывод: почему разработчику стоит запускать оба инструмента

Рекомендация авторов Project Zero прямая: применять к своему коду и фаззинг, и агентный анализ, чтобы до пользователей добиралось меньше уязвимостей. Это вывод из данных, а не общая пожелание.

Как это выглядит в работе. Фаззинг даёт непрерывный фон и ловит регрессии в рантайме: сборка крутится, изменения проверяются без участия человека. Агентный анализ коммитов добавляет смысловой слой: ревью диффов и PoC к найденному. Один инструмент не заменяет второй, потому что ищет в другом месте.

Для небольшой команды не обязательно строить два пайплайна с нуля. Разумный старт: фаззинг в CI на критичных компонентах и агентный разбор диффов на изменённых участках. Дальше схему можно расширять по мере появления находок и свободного времени.

Цена вопроса честная: инстансы фаззера и прогоны LLM стоят денег и времени, а ложные срабатывания требуют ручной фильтрации. В исследовании репорты BigSleep проходили очистку от дубликатов и нерабочих находок, и в реальной команде похожая фильтрация тоже понадобится, иначе очередь разбора утонет.

Обещаний вроде «это заменит пентест» из данных не следует, и авторы их не дают. Автоматические конвейеры сокращают число известных уязвимостей, а не отменяют ручной анализ.

Что из этого применимо за пределами V8 и чего ждать дальше

Ограничения переноса стоит назвать прямо: один движок, один проект, две конкретные продакшен-системы. Цифры 45 и 37, как и 20 из 81, не масштабируются на произвольную кодовую базу.

Что переносится: сама схема «непрерывный фаззер плюс агентный анализ коммитов» и понимание, что инструменты покрывают разные классы багов. Переносится и урок про методику. Проверка на запоминание обучающих данных, дополнительный поиск дубликатов через коммиты-исправления и Clusterfuzz, отдельные эксперименты на исторических уязвимостях это части одного измерения. Без них сравнивать инструменты бессмысленно: легко получить красивое число, за которым ничего не стоит.

Направление развивается, и инструменты поиска уязвимостей на базе AI-агентов продолжают появляться. Вместе с ними растёт значение аккуратных методик сравнения: модели меняются быстро, а способы проверять их результат меняются медленно, и именно они определяют, каким цифрам можно верить. Подробный разбор с методикой и примерами багов доступен в переводе статьи.

Чек-лист, если хотите повторить подход у себя:

  • Определите классы багов, которые критичны именно вашему проекту: падения и повреждения памяти здесь, логические ошибки там.
  • Закройте рантайм-регрессии фаззингом на критичных компонентах, встройте прогоны в CI.
  • Добавьте агентный анализ диффов на изменённых участках, а не на всей кодовой базе сразу.
  • Считайте пересечение находок, а не только их количество: общие баги показывают, где инструменты дублируют друг друга, а разница показывает реальную добавку.
  • Заложите время на ручную фильтрацию ложных срабатываний и на разбор того, что инструменты нашли, но не объяснили.

Подписаться на канал