Map

Fuzzing โ€” Testing Handbook (Trail of Bits)

publisher
Trail of Bits โ€” Testing Handbook
captured
2026-05-12

Fuzzing โ€” Testing Handbook (Trail of Bits)

Page Type

This is the overview and introductory chapter for the fuzzing section of Trail of Bits' Testing Handbook (appsec.guide). It is the main entry point for a comprehensive set of fuzzing subsections.

Main Content

Introduction

"Fuzzing represents a dynamic testing method that inputs malformed or unpredictable data to a system to detect security issues, bugs, or system failures." The chapter provides both foundational concepts and advanced techniques applicable across multiple programming languages.

Audience and Scope

  • Developers and security engineers
  • Requires programming-language familiarity and Linux experience
  • Focuses on projects where source code is available

Structure

  • Language-specific fuzzers (C/C++, Rust, Go, Python, Ruby)
  • Language-specific techniques subsections
  • Cross-language techniques at the end

Terminology (12 defined terms)

  • SUT/target: System Under Test โ€” software being tested, standalone application or library
  • Fuzzing/Fuzzer: Automated software testing supplying invalid, unexpected, or random data; the program implementing the algorithm is called a fuzzer
  • Test case: Concrete input given to the testing harness, usually a string or bitstring, or encoded in complex formats like abstract syntax trees
  • (Testing/fuzzing) harness: Handles test setup for a given SUT by wrapping the software, initializing it, and integrating it into a testing environment
  • libFuzzer harness: A harness compatible with libFuzzer, referring to the LLVMFuzzerTestOneInput function
  • Fuzz test: Fuzzing harness + SUT; typically refers to the compiled binary containing both
  • Fuzzing campaign: An execution of the fuzzer from start to stop
  • Corpus: The evolving set of test cases that grows during a fuzzing campaign as new test cases are discovered
  • Seed corpus: The initial set of test cases bootstrapping a campaign; each test case is called a seed
  • Fuzzing engine/runtime: The part of the fuzzer executed when fuzzing starts, orchestrating the entire process
  • Instrumentation: Non-functional changes to a program to retrieve data from it or enhance its security/robustness
  • Code coverage: A metric measuring the degree to which source code of a program is executed

Pros and Cons of Fuzzing

Advantages:

  • Finds overlooked vulnerabilities
  • Automation
  • Cost-effectiveness
  • Proven for memory corruption detection

Disadvantages:

  • Complex inputs challenging
  • Incomplete bug detection
  • Traditionally memory-focused

Mutation-Based Evolutionary Algorithm

The de facto algorithm for modern fuzzers, inspired by evolutionary principles, maintains a population of test cases where fitness is typically determined by code coverage metrics.

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;
}

Components:

  • Input: non-empty initial corpus
  • schedule(): picks the next test case, returns nothing to end the campaign
  • mutate(): creates offspring via bit flips, byte insertions, truncations, etc.
  • execute(): runs the test case, generates observations (timing, coverage)
  • Output: offspring added to corpus if interesting, to bug_set if buggy

Introduction to Fuzzers

Components: SUT, harness, fuzzer runtime, instrumentation. C/C++ and Rust code examples.

What to Fuzz โ€” Bug Classes

  • Crashes and panics: Memory corruption โ€” UAFs, integer overflows, undefined behavior, buffer overflows, memory leaks
  • Invariant violations: Business-logic and state-invariant violations requiring stateful fuzzing
  • Differentials: Cross-testing between implementations, platforms, versions, or tools
  • Broken logical properties: Round-trip, idempotence, monotonicity, identity, commutativity, associativity violations
  • Race conditions

Subsections Referenced (not yet fetched)

  • C/C++ fuzzing โ€” libFuzzer, AFL++, LibAFL, techniques
  • Rust fuzzing โ€” cargo-fuzz, techniques
  • Python and Ruby fuzzing
  • General techniques โ€” harnesses, dictionaries, AddressSanitizer, environments, FAQ
  • OSS-Fuzz and Snapshot Fuzzing
  • Static analysis tools โ€” CodeQL, Semgrep (cross-referenced)
  • Cryptographic and web application testing sections (separate chapters)