Fuzzing

RecipeCratesCategories
aflaflcat-development-tools::testing
cargo fuzz[![cargo-fuzz][c-cargo-fuzz-badge]][c-cargo-fuzz]cat-development-tools::testing

Fuzzing (or fuzz testing) is an automated technique that involves providing invalid, unexpected, or random data as input to a computer program. The purpose is to find security vulnerabilities, crashes, and undefined behaviors. For example, a web application might be subjected to random strings, files, or network requests to see if any of them cause the application to crash or behave unexpectedly.

Fuzzing is a unguided approach to random testing. A fuzzer generally provides an input of random bytes, and then examines fairly generic properties (such as "doesn't crash" or "commit undefined behavior") about the resulting program.

Fuzzers generally get their power through a kind of evolutionary algorithm that rewards new mutant inputs that "discover" new branches of the program under test. Fuzzers are excellent for testing security boundaries, precisely because they make no validity assumptions (hence, they are "unguided") when generating the input.

Fuzzing Engines

  • cargo fuzz: The most common and recommended way to perform fuzzing in Rust. It integrates well with Cargo and uses libFuzzer under the hood.
  • afl.rs: Bindings to the American Fuzzy Lop (AFL) fuzzer. AFL is a powerful fuzzer, but cargo fuzz with libFuzzer is often sufficient and easier to set up.

In almost all cases, cargo fuzz will be your primary tool for fuzzing Rust code. It uses libFuzzer, a powerful and modern fuzzing engine, and simplifies the fuzzing process significantly. Make sure you define good fuzz targets and use sanitizers to detect errors effectively.

Target Definition

You'll need to define a fuzz target - a function in your code that the fuzzer will call with different inputs. This is a crucial step in setting up fuzzing.

Corpus Management

(Important for effective fuzzing)

A corpus is a set of initial inputs that the fuzzer uses as a starting point. cargo fuzz helps manage corpora.

Coverage-Guided Fuzzing

(Most effective)

libFuzzer (used by cargo fuzz): libFuzzer is a coverage-guided fuzzer, meaning it uses code coverage information to guide its search for bugs. AFL: Also a coverage-guided fuzzer.

Sanitizers (for Detecting errors)

Address Sanitizer (ASan): Detects memory errors (e.g., use-after-free, memory leaks). Enable it with compiler flags (e.g., -fsanitize=address). Undefined Behavior Sanitizer (UBSan): Detects undefined behavior (e.g., integer overflow, out-of-bounds access). Enable it with compiler flags (e.g., -fsanitize=undefined).

Differential Fuzzing: (For Comparing implementations)

This is a more advanced technique and often involves custom scripting or tools. There aren't specific crates for it.

cargo fuzz

cargo-fuzz cargo-fuzz-crates.io cargo-fuzz-github cargo-fuzz-lib.rs cat-development-tools::testing

A cargo subcommand for fuzzing with libFuzzer.

afl

afl afl-crates.io afl-github afl-lib.rs

Fuzz testing (or fuzzing) is a software testing technique used to find security and stability issues by providing pseudo-random data as input to the software. AFLplusplus is a popular, effective, and modern fuzz testing tool based on AFL. afl.rs allows one to run AFLplusplus on code written in the Rust programming language.

// // COMING SOON

Related Topic: Property-Based Testing

The proptest, quickcheck crates are used for property-based testing, which is a different but complementary technique to fuzzing. Property-based testing generates many random inputs to verify properties of your code.