appsec.guide โ Fuzzing Chapter (Trail of Bits Testing Handbook)
- title
- appsec.guide โ Fuzzing Chapter (Trail of Bits Testing Handbook)
- type
- summary
- summary
- Trail of Bits' Testing Handbook fuzzing chapter โ terminology, the mutation-based evolutionary algorithm, fuzzer components, and a taxonomy of bug classes; entry point to language-specific subsections
- parent
- supply-chain-security
- tags
- fuzzing, security, testing, reference, trail-of-bits
- created
- 2026-05-12
- updated
- 2026-05-12
The fuzzing chapter of appsec.guide โ Trail of Bits' open Testing Handbook. The page itself is the chapter index and a foundational primer; the rest of the chapter splits into language-specific (C/C++, Rust, Go, Python, Ruby) and cross-language subsections.
This summary captures the foundational material here. Sub-chapters (libFuzzer, AFL++, cargo-fuzz, OSS-Fuzz, snapshot fuzzing, etc.) are separate ingests when needed.
Terminology (the vocabulary the rest of the chapter assumes)
- SUT / target โ System Under Test
- Fuzzer โ the program implementing the fuzzing algorithm; fuzzing the activity
- Test case โ a concrete input to the harness (bitstring, AST, structured value)
- Harness โ wraps the SUT, initializes it, integrates it into the testing environment
- libFuzzer harness โ a harness that exposes the
LLVMFuzzerTestOneInputentry point - Fuzz test โ the compiled binary containing harness + SUT
- Campaign โ one start-to-stop execution of the fuzzer
- Corpus โ the evolving set of test cases the campaign maintains
- Seed corpus โ the initial test cases the campaign starts from; individual entries are seeds
- Fuzzing engine / runtime โ the orchestrator (libFuzzer, AFL++, LibAFL, Honggfuzz)
- Instrumentation โ non-functional code added to the SUT to report coverage, sanitizer trips, comparisons, etc.
- Code coverage โ the metric most fuzzers use as their fitness function
The de facto algorithm
Modern coverage-guided fuzzers are evolutionary: maintain a population (corpus), schedule fit members, mutate them, keep offspring that show new fitness, repeat. Fitness is almost always code coverage. See coverage-guided-fuzzing for the concept page; the pseudocode from the handbook:
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;
}
The four customization points (schedule, mutate, execute, is_interesting / is_bug) are what fuzzer engines differ on. LibAFL's composition story is exactly "make all four traits."
What fuzzing finds
The handbook's bug-class taxonomy goes beyond the "memory corruption" reputation:
- Crashes and panics โ UAF, integer overflows, undefined behavior, buffer overflows, memory leaks
- Invariant violations โ business-logic / state-invariant bugs; requires stateful fuzzing (drive the SUT through a sequence of operations rather than one input)
- Differentials โ comparing implementations / platforms / versions; the technique behind most consensus-bug findings, see differential-fuzzing
- Broken logical properties โ round-trip (
decode(encode(x)) = x), idempotence (f(f(x)) = f(x)), monotonicity, identity, commutativity, associativity - Race conditions โ with thread-sanitizer / native race detector
Property checks (round-trip, idempotence, etc.) are the hook for property-based fuzzing โ the same mental model as property-based testing (QuickCheck / Hypothesis) but driven by a coverage-guided mutator instead of a random generator.
Why this page is worth keeping in the wiki
The handbook is the right reference to point at when one of the wiki's fuzzing-adjacent pages needs background. It's open, author-bylined, vendor-neutral within fuzzing (the language-specific chapters cover libFuzzer, AFL++, cargo-fuzz, etc. โ not just Trail of Bits tools), and reasonably current. Most other fuzzing primers online are either outdated AFL-era walkthroughs or vendor docs that don't generalize.
Sub-chapters (separate ingests when relevant)
- C/C++ โ libFuzzer, AFL++, LibAFL, techniques
- Rust โ cargo-fuzz, techniques
- Go โ covered by gosentry-go-fuzzing-fork in its own right; the handbook's Go section is older / pre-gosentry
- Python and Ruby
- Cross-language techniques โ harnesses, dictionaries, ASan, environments, FAQ
- OSS-Fuzz, snapshot fuzzing
- Static analysis (CodeQL, Semgrep) is referenced from here but lives in a different chapter
Related wiki pages
- gosentry-go-fuzzing-fork โ the same publisher's Go-specific fuzzing fork; the handbook is the conceptual layer underneath
- grammar-based-fuzzing โ covered as a technique in the C/C++ sub-chapter (Nautilus, AFL++ grammar mode)
- structure-aware-fuzzing โ
arbitrary/ FuzzedDataProvider; the in-language equivalent of grammars - differential-fuzzing โ the "Differentials" bug class
- coverage-guided-fuzzing โ the algorithm this page formalizes
- trail-of-bits โ author entity; the handbook is one of their three load-bearing public security resources (alongside the blog and the audit reports)