Фаззинг-тестирование программы: что это, типы, инструменты
Проверено экспертной редакцией SecRadar · по первоисточникам ФСТЭК / ФСБ / Банка России
Фаззинг (fuzzing, фаззинг-тестирование) — метод тестирования программного обеспечения, при котором на вход программы автоматически подают большие объёмы случайных, некорректных или граничных данных, чтобы найти ошибки, сбои и уязвимости, которые не всплывают при обычном функциональном тестировании. Материал разбирает, чем фаззинг отличается от ручного тестирования, какие типы фаззинга существуют — чёрный, серый и белый ящик, мутационный и генерационный, coverage-guided, — какие инструменты применяют на практике (AFL, libFuzzer, honggfuzz) и как фаззинг-тестирование закреплено в требованиях РБПО по ГОСТ Р 56939 рядом с SAST и DAST.
Кратко
- Что это
- Подача случайных, некорректных или граничных данных на вход программы для поиска сбоев и уязвимостей, которые не находят обычные тесты.
- Типы по знанию структуры
- Чёрный ящик (без знания кода), серый ящик (частичное знание через обратную связь по покрытию), белый ящик (полное знание кода).
- Типы по стратегии
- Мутационный (видоизменяет валидные образцы) и генерационный (строит данные по модели формата с нуля).
- Инструменты
- AFL / AFL++, libFuzzer (часть LLVM/Clang), honggfuzz — открытые coverage-guided фаззеры.
- Место в РБПО
- ГОСТ Р 56939-2024, процесс 5.11 «Динамический анализ кода программы» (включает обязательное фаззинг-тестирование, п. 5.11.2.7) — рядом с SAST (5.10) и SCA (5.16).
- Отличие от DAST-сканера
- DAST на рынке обычно значит тестирование веб-приложения HTTP-запросами; фаззинг шире — применяется и к бинарным программам, парсерам, протоколам.
Что такое фаззинг
Фаззинг (fuzzing) — метод тестирования программного обеспечения, при котором на вход программы автоматически подают большие объёмы случайных, некорректных или намеренно граничных данных и следят за реакцией: падениями, зависаниями, необработанными исключениями, утечками памяти. Цель не в том, чтобы подтвердить, что программа правильно работает на ожидаемых данных, — это задача обычных функциональных тестов, — а в том, чтобы найти вход, на котором программа ведёт себя непредсказуемо.
Такой вход часто указывает на дефект обработки данных, который в реальной эксплуатации может стать уязвимостью.
Программу, которая генерирует и подаёт такие данные, называют фаззером, а сам процесс проверки — фаззинг-тестированием или фаззинг-кампанией. В отличие от ручного тестирования по заранее написанным сценариям, фаззер не требует, чтобы человек заранее знал, где искать ошибку: он сам перебирает тысячи или миллионы вариаций входных данных и автоматически откладывает те, что вызвали сбой, — для последующего разбора инженером.
Метод и сам термин связывают с исследованиями, которые в конце 1980-х годов проводил Бартон Миллер в Университете Висконсина: короткая программа-фаззер подавала на вход стандартных Unix-утилит случайные потоки байтов и фиксировала аварийные завершения. С тех пор фаззинг вырос из простых генераторов случайного мусора в отдельное направление автоматизированного поиска дефектов, где активно развиваются алгоритмы обратной связи по покрытию кода и гибридные подходы с символьным выполнением.
Типы фаззинга
Фаззеры различают по двум независимым признакам — сколько фаззер знает о внутреннем устройстве цели и как именно он строит входные данные. На практике эти признаки комбинируются: например, современный coverage-guided фаззер обычно относится к серому ящику и использует мутационную стратегию одновременно.
↔ таблицу можно прокрутить вбок
| Признак | Тип | Суть |
|---|---|---|
| Знание структуры цели | Чёрный ящик (black-box) | Фаззер не знает ни формата входных данных, ни внутренней логики программы — подаёт данные вслепую, полагаясь в основном на случайность и объём попыток |
| Знание структуры цели | Серый ящик (grey-box) | Фаззер не анализирует исходный код целиком, но получает обратную связь от инструментированного бинарника — например, какие участки кода выполнились на конкретном входе — и направленно эволюционирует данные в сторону нового покрытия |
| Знание структуры цели | Белый ящик (white-box) | Фаззер использует полное знание кода, часто с символьным или конколическим выполнением, чтобы построить входные данные, проходящие по конкретным путям программы — точнее, но существенно ресурсоёмче и хуже масштабируется на крупный код |
| Стратегия генерации данных | Мутационный (mutation-based) | Берёт набор валидных образцов (seed corpus) и вносит в них случайные изменения — переворачивает биты, меняет или дублирует байты; прост в запуске, не требует знания формата входных данных |
| Стратегия генерации данных | Генерационный (generation-based) | Строит входные данные с нуля по модели или грамматике формата — например, по спецификации протокола или языка; эффективнее там, где случайные мутации почти всегда отбрасываются парсером на входе |
| Обратная связь | Coverage-guided | Расширение серого ящика: фаззер отслеживает покрытие кода на каждом входе и с помощью генетического алгоритма отдаёт предпочтение мутациям, открывающим новые пути выполнения — подход, популяризированный AFL и ставший практическим стандартом для фаззинга бинарных программ |
Инструменты фаззинга
Большинство широко используемых фаззеров — открытые проекты, а не проприетарные разработки одного вендора. Три инструмента упоминаются в отраслевых материалах чаще остальных как отправная точка для coverage-guided фаззинга.
AFL / AFL++ coverage-guided
American Fuzzy Lop — один из наиболее известных фаззеров для бинарных программ. Инструментирует код при компиляции и использует генетический алгоритм, чтобы эволюционировать входные данные в сторону нового покрытия кода. Оригинальный проект сейчас продолжает активно поддерживаемый форк AFL++, развиваемый сообществом.
libFuzzer in-process
Библиотека для фаззинга на уровне отдельных функций и API, часть инфраструктуры LLVM/Clang. Тестируемый код и сам фаззер компилируются в один процесс, что даёт высокую скорость итераций. Обычно применяется вместе с санитайзерами — например, AddressSanitizer — для обнаружения ошибок работы с памятью.
honggfuzz coverage-guided
Ещё один распространённый coverage-guided фаззер с поддержкой нескольких санитайзеров и persistent-режима запуска. Используется как самостоятельно, так и в связке с непрерывным фаззингом open-source кода.
Выбор конкретного инструмента зависит от того, что тестируется: libFuzzer удобен для точечного фаззинга отдельной функции внутри проекта, который уже собирается через LLVM/Clang; AFL/AFL++ и honggfuzz чаще применяют для фаззинга целых бинарных программ и утилит, включая случаи, когда исходный код недоступен и фаззер работает через эмуляцию или инструментирование бинарника «на лету».
Фаззинг в РБПО и AppSec
В российском реестре ПО фаззинг не выделен как отдельный класс средств защиты информации — это метод, встроенный в процессы безопасной разработки. Раздел 5 ГОСТ Р 56939-2024 «Защита информации. Разработка безопасного программного обеспечения. Общие требования» прямо называет процесс 5.11 «Динамический анализ кода программы» (включает обязательное фаззинг-тестирование, п.
5.11.2.7) — то есть фаззинг официально закреплён как часть практики динамического анализа наравне со статическим анализом кода (SAST, процесс 5.10) и композиционным анализом компонентов (SCA, процесс 5.16).
На практике фаззинг и рыночный класс DAST — не строго одно и то же. DAST в типичном понимании рынка — это чёрно-ящичное тестирование уже развёрнутого веб-приложения или API HTTP(S)-запросами, без доступа к исходному коду. Фаззинг шире конкретного класса DAST-сканеров: цель фаззинга может быть любой — бинарный файл, библиотека, парсер файлового формата, сетевой протокол, а не только веб-приложение.
ГОСТ Р 56939-2024 объединяет оба смысла в одном процессе 5.11 именно потому, что это две стороны одной практики — искать дефекты не по коду, а по поведению работающей программы.
Для разработчиков СЗИ, которые проходят сертификацию ФСТЭК по уровням доверия (приказ №76 от 02.06.2020), документация по безопасной разработке средства требуется на всех открытых уровнях 4–6. Приказ №76 не ссылается на номер ГОСТ Р 56939 напрямую, но содержательно эта документация опирается на процессы стандарта, включая динамический анализ и фаззинг-тестирование, — особенно на более высоких уровнях доверия, где требования к исследованию на предмет уязвимостей и недекларированных возможностей строже.
Уязвимости, найденные фаззингом на этапе разработки, попадают в тот же процесс триажа и устранения, что и уязвимости, обнаруженные после релиза, — этот процесс подробнее описан в материале об управлении уязвимостями.
Частые вопросы
Что такое фаззинг простыми словами?
Что такое фаззинг-тестирование программы?
Какие бывают типы фаззинга?
Какие инструменты используют для фаззинга?
Как фаззинг связан с РБПО и ГОСТ Р 56939?
Чем фаззинг отличается от SAST и DAST?
Словарь угроз на SecRadar
Разбор терминов и методов защиты без вендорной привязки — что стоит за понятием, как оно связано со смежными практиками AppSec и какие классы СЗИ закрывают конкретную задачу.