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
LLVMFuzzerTestOneInputfunction - 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)