# appsec.guide — Fuzzing Chapter (Trail of Bits Testing Handbook)

The fuzzing chapter of [[appsec-guide|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 `LLVMFuzzerTestOneInput` entry 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|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|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)
