appsec.guide - глава о фаззинге (Trail of Bits Testing Handbook)
- title
- appsec.guide - глава о фаззинге (Trail of Bits Testing Handbook)
- type
- summary
- summary
- Глава о фаззинге из Testing Handbook от Trail of Bits: терминология, эволюционный алгоритм, компоненты фаззера и таксономия классов багов.
- parent
- supply-chain-security
- tags
- fuzzing, security, testing, reference, trail-of-bits
- created
- 2026-05-12
- updated
- 2026-05-12
- lang
- ru
- translation_of
- appsec-guide-fuzzing-handbook
- source_updated
- 2026-05-12
- translated
- 2026-09-01
- translator
- lllm/antigravity/gemini-3.7-flash-medium
Глава о фаззинге из appsec.guide - открытого руководства по тестированию (Testing Handbook) от Trail of Bits. Сама страница представляет собой оглавление главы и базовое введение; остальная часть главы разбита на подразделы по конкретным языкам (C/C++, Rust, Go, Python, Ruby) и общим техникам.
Этот конспект фиксирует базовый материал. Подразделы (libFuzzer, AFL++, cargo-fuzz, OSS-Fuzz, snapshot-фаззинг и т. д.) будут оформляться отдельными ingest'ами по мере необходимости.
Терминология (базовый словарь для остальной части главы)
- SUT / target - тестируемая система (System Under Test)
- Fuzzer - программа, реализующая алгоритм фаззинга; fuzzing - сам процесс
- Test case - конкретные входные данные для harness'а (битовая строка, AST, структурированное значение)
- Harness - обёртка вокруг SUT, которая инициализирует её и интегрирует в тестовое окружение
- libFuzzer harness - harness, предоставляющий точку входа
LLVMFuzzerTestOneInput - Fuzz test - скомпилированный бинарник, содержащий harness + SUT
- Campaign - один прогон фаззера от запуска до остановки
- Corpus - развивающийся набор тест-кейсов, который поддерживается в рамках кампании
- Seed corpus - начальный набор тест-кейсов, с которого стартует кампания; отдельные элементы называются seed'ами
- Fuzzing engine / runtime - оркестратор (libFuzzer, AFL++, LibAFL, Honggfuzz)
- Instrumentation - нефункциональный код, добавляемый в SUT для сбора покрытия, отслеживания срабатываний санитайзеров, сравнений и т. д.
- Code coverage - покрытие кода, метрика, которую большинство фаззеров используют в качестве функции приспособленности (fitness function)
Общепринятый алгоритм
Современные фаззеры на основе покрытия (coverage-guided) работают как эволюционный алгоритм: поддерживают популяцию (корпус), выбирают подходящие элементы (schedule), мутируют их, сохраняют потомков с новой приспособленностью и повторяют цикл. Приспособленность почти всегда измеряется покрытием кода. См. концептуальную страницу coverage-guided-fuzzing; псевдокод из руководства:
fn fuzz(corpus) {
let bug_set = [];
while let Some(test_case) = schedule(corpus) {
let offspring = mutate(test_case);
let observations = execute(offspring);
if (is_interesting(observations)) { corpus.append(offspring); }
if (is_bug(observations)) { bug_set.append(offspring); }
}
return bug_set;
}
Четыре точки кастомизации (schedule, mutate, execute, is_interesting / is_bug) - это как раз то, чем различаются движки фаззеров. Архитектурный подход LibAFL буквально заключается в том, чтобы сделать все четыре точки трейтами.
Что находит фаззинг
Таксономия классов багов в руководстве выходит далеко за рамки репутации инструмента только для поиска "повреждений памяти":
- Падения и паники (crashes and panics) - UAF, целочисленные переполнения, неопределённое поведение, переполнения буфера, утечки памяти
- Нарушения инвариантов (invariant violations) - баги бизнес-логики и инвариантов состояния; требуют stateful-фаззинга (прогона SUT через последовательность операций, а не через один входной параметр)
- Дифференциальные расхождения (differentials) - сравнение реализаций, платформ или версий; техника, стоящая за большинством найденных багов консенсуса, см. differential-fuzzing
- Нарушения логических свойств - round-trip (
decode(encode(x)) = x), идемпотентность (f(f(x)) = f(x)), монотонность, тождественность, коммутативность, ассоциативность - Состояния гонки (race conditions) - при использовании thread-санитайзера или встроенного детектора гонок
Проверки свойств (round-trip, идемпотентность и т. д.) служат основой для property-based фаззинга - здесь используется та же ментальная модель, что и в property-based тестировании (QuickCheck / Hypothesis), но генерация управляется мутатором на основе покрытия, а не случайным генератором.
Зачем эта страница нужна в wiki
Это руководство - отличный источник, на который удобно ссылаться, когда смежным страницам wiki о фаззинге нужен контекст. Оно открытое, с указанием авторов, вендор-нейтральное внутри предметной области фаззинга (главы по языкам разбирают libFuzzer, AFL++, cargo-fuzz и т. д., а не только инструменты Trail of Bits) и достаточно актуальное. Большинство других руководств по фаззингу в сети - это либо устаревшие пошаговые инструкции эпохи AFL, либо документация конкретных продуктов, которая не даёт общего понимания.
Подразделы (отдельные ingest'ы по мере необходимости)
- C/C++ - libFuzzer, AFL++, LibAFL, техники
- Rust - cargo-fuzz, техники
- Go - отдельно описан на странице gosentry-go-fuzzing-fork; раздел по Go в руководстве более старый (до появления gosentry)
- Python и Ruby
- Межъязыковые техники - harness'ы, словари, ASan, окружения, FAQ
- OSS-Fuzz, snapshot-фаззинг
- Статический анализ (CodeQL, Semgrep) упоминается здесь, но вынесен в отдельную главу
Связанные страницы wiki
- gosentry-go-fuzzing-fork - Go-специфичный форк фаззера от того же издателя; руководство служит концептуальной базой для него
- grammar-based-fuzzing - описан как техника в подразделе по C/C++ (Nautilus, режим грамматик в AFL++)
- structure-aware-fuzzing -
arbitrary/ FuzzedDataProvider; эквивалент грамматик внутри языка - differential-fuzzing - класс багов "Дифференциальные расхождения"
- coverage-guided-fuzzing - алгоритм, который формализует эта страница
- trail-of-bits - компания-автор; руководство входит в тройку их главных публичных ресурсов по безопасности (наряду с блогом и отчётами об аудитах)