Back to Security & Vulnerability Analysis

cargo-fuzz

RustFuzzingSecurity TestingCode QualitylibFuzzerVulnerability DetectionCargoAutomated Testing
⭐ 5.7kπŸ“„ CC-BY-SA-4.0πŸ•’ 2026-06-15Source β†—

Install this skill

npx skills add trailofbits/skills

Works across Claude Code, Cursor, Codex, Copilot & Antigravity

cargo-fuzz acts as the standard command-line interface for applying coverage-guided fuzz testing to Rust applications. By wrapping libFuzzer, it automates the orchestration of compilation flags, instrumentation, and sanitizer execution required to expose edge-case bugs. Developers initialize the tool within a Cargo workspace to generate isolated fuzz targets, which receive raw byte slices or structured data inputs. The workflow automatically manages a persistent corpus, saving inputs that trigger crashes into a local artifacts directory for debugging. Because it prioritizes developer ergonomics, the tool integrates directly with the nightly Rust compiler, allowing teams to verify the reliability of complex logic, parsers, and serialization routines without manual instrumentation setups. It serves as an essential companion for hardening crates that handle untrusted inputs or interact with unsafe memory pointers.

When to Use This Skill

  • β€’Testing custom data parsers or protocol decoders for unexpected input
  • β€’Verifying the safety of crates containing unsafe blocks
  • β€’Detecting buffer overflows, use-after-free, or memory leaks
  • β€’Ensuring fuzzer input determinism through saved reproduction artifacts

How to Invoke This Skill

Example prompts that trigger this skill in Claude Code, Cursor, or Antigravity:

  • β€œHow do I fuzz my Rust crate with cargo-fuzz?
  • β€œSet up a fuzzing harness for my library
  • β€œHow to debug a crash found by cargo-fuzz
  • β€œUse structure-aware input generation in Rust
  • β€œDisable AddressSanitizer in cargo-fuzz for better performance

Pro Tips

  • πŸ’‘Always start with simple fuzz targets focusing on critical components, then incrementally expand complexity as your understanding of the target code and fuzzing needs evolve.
  • πŸ’‘Leverage sanitizers like AddressSanitizer (`-Zsanitizer=address`) extensively, especially when dealing with FFI or `unsafe` blocks, to catch memory-related issues early.
  • πŸ’‘Integrate `cargo-fuzz` execution into your continuous integration pipeline to ensure ongoing vulnerability detection and maintain code robustness against new changes.

What this skill does

  • β€’Automated build-time instrumentation for libFuzzer
  • β€’Built-in integration with AddressSanitizer (ASan) for memory error detection
  • β€’Persistent corpus and crash artifact management
  • β€’Support for structure-aware fuzzing using the arbitrary crate
  • β€’Command-line control over fuzzing dictionary injection

When not to use it

  • βœ•Projects requiring heavy multi-core scalability beyond local machine limits
  • βœ•Non-Rust codebases or projects that cannot utilize the nightly compiler

Example workflow

  1. Install the nightly Rust toolchain and cargo-fuzz
  2. Execute cargo fuzz init in the root directory
  3. Define the fuzz harness in the generated fuzz/fuzz_targets folder
  4. Compile and run the target using cargo +nightly fuzz run
  5. Inspect the fuzz/artifacts folder to reproduce found crashes

Prerequisites

  • –Nightly Rust toolchain
  • –Cargo build system
  • –Code structured as a library crate

Pitfalls & limitations

  • !Nightly compiler dependency can break workflows if stable features are strictly required
  • !ASan introduces significant performance overhead, slowing down execution speed
  • !Ineffective if the project logic does not adequately handle or propagate errors
  • !Harnesses that use global state or RNGs will cause non-deterministic results

FAQ

Can I use cargo-fuzz with the stable Rust toolchain?
No, cargo-fuzz relies on nightly-only compiler features for instrumentation and must be run using the nightly toolchain.
How do I speed up my fuzzing campaign?
If your code contains no unsafe blocks, you can improve performance by running with the --sanitizer none flag.
What should I do if my harness panics?
The fuzzer treats panics as crashes. Ensure your code handles errors gracefully instead of panicking, or only panic when you intend to signal a bug.

How it compares

Unlike manual test writing which checks predefined cases, cargo-fuzz generates thousands of mutations to explore deep state paths automatically, revealing unexpected edge-case crashes that human-written tests often miss.

Source & trust

⭐ 5.7k starsπŸ“„ CC-BY-SA-4.0πŸ•’ Updated 2026-06-15
πŸ“„ Full skill instructions β€” original source: trailofbits/skills
# cargo-fuzz

cargo-fuzz is the de facto choice for fuzzing Rust projects when using Cargo. It uses libFuzzer as the backend and provides a convenient Cargo subcommand that automatically enables relevant compilation flags for your Rust project, including support for sanitizers like AddressSanitizer.

## When to Use

cargo-fuzz is currently the primary and most mature fuzzing solution for Rust projects using Cargo.

| Fuzzer | Best For | Complexity |
|--------|----------|------------|
| cargo-fuzz | Cargo-based Rust projects, quick setup | Low |
| AFL++ | Multi-core fuzzing, non-Cargo projects | Medium |
| LibAFL | Custom fuzzers, research, advanced use cases | High |

**Choose cargo-fuzz when:**
- Your project uses Cargo (required)
- You want simple, quick setup with minimal configuration
- You need integrated sanitizer support
- You're fuzzing Rust code with or without unsafe blocks

## Quick Start

#![no_main]

use libfuzzer_sys::fuzz_target;

fn harness(data: &[u8]) {
your_project::check_buf(data);
}

fuzz_target!(|data: &[u8]| {
harness(data);
});


Initialize and run:
cargo fuzz init
# Edit fuzz/fuzz_targets/fuzz_target_1.rs with your harness
cargo +nightly fuzz run fuzz_target_1


## Installation

cargo-fuzz requires the nightly Rust toolchain because it uses features only available in nightly.

### Prerequisites

- Rust and Cargo installed via [rustup](https://rustup.rs/)
- Nightly toolchain

### Linux/macOS

# Install nightly toolchain
rustup install nightly

# Install cargo-fuzz
cargo install cargo-fuzz


### Verification

cargo +nightly --version
cargo fuzz --version


## Writing a Harness

### Project Structure

cargo-fuzz works best when your code is structured as a library crate. If you have a binary project, split your main.rs into:

src/main.rs  # Entry point (main function)
src/lib.rs # Code to fuzz (public functions)
Cargo.toml


Initialize fuzzing:
cargo fuzz init


This creates:
fuzz/
β”œβ”€β”€ Cargo.toml
└── fuzz_targets/
└── fuzz_target_1.rs


### Harness Structure

#![no_main]

use libfuzzer_sys::fuzz_target;

fn harness(data: &[u8]) {
// 1. Validate input size if needed
if data.is_empty() {
return;
}

// 2. Call target function with fuzz data
your_project::target_function(data);
}

fuzz_target!(|data: &[u8]| {
harness(data);
});


### Harness Rules

| Do | Don't |
|----|-------|
| Structure code as library crate | Keep everything in main.rs |
| Use fuzz_target! macro | Write custom main function |
| Handle Result::Err gracefully | Panic on expected errors |
| Keep harness deterministic | Use random number generators |

> **See Also:** For detailed harness writing techniques and structure-aware fuzzing with the
> arbitrary crate, see the **fuzz-harness-writing** technique skill.

## Structure-Aware Fuzzing

cargo-fuzz integrates with the [arbitrary](https://github.com/rust-fuzz/arbitrary) crate for structure-aware fuzzing:

// In your library crate
use arbitrary::Arbitrary;

#[derive(Debug, Arbitrary)]
pub struct Name {
data: String
}


// In your fuzz target
#![no_main]
use libfuzzer_sys::fuzz_target;

fuzz_target!(|data: your_project::Name| {
data.check_buf();
});


Add to your library's Cargo.toml:
[dependencies]
arbitrary = { version = "1", features = ["derive"] }


## Running Campaigns

### Basic Run

cargo +nightly fuzz run fuzz_target_1


### Without Sanitizers (Safe Rust)

If your project doesn't use unsafe Rust, disable sanitizers for 2x performance boost:

cargo +nightly fuzz run --sanitizer none fuzz_target_1


Check if your project uses unsafe code:
cargo install cargo-geiger
cargo geiger


### Re-executing Test Cases

# Run a specific test case (e.g., a crash)
cargo +nightly fuzz run fuzz_target_1 fuzz/artifacts/fuzz_target_1/crash-<hash>

# Run all corpus entries without fuzzing
cargo +nightly fuzz run fuzz_target_1 fuzz/corpus/fuzz_target_1 -- -runs=0


### Using Dictionaries

cargo +nightly fuzz run fuzz_target_1 -- -dict=./dict.dict


### Interpreting Output

| Output | Meaning |
|--------|---------|
| NEW | New coverage-increasing input discovered |
| pulse | Periodic status update |
| INITED | Fuzzer initialized successfully |
| Crash with stack trace | Bug found, saved to fuzz/artifacts/ |

Corpus location: fuzz/corpus/fuzz_target_1/
Crashes location: fuzz/artifacts/fuzz_target_1/

## Sanitizer Integration

### AddressSanitizer (ASan)

ASan is enabled by default and detects memory errors:

cargo +nightly fuzz run fuzz_target_1


### Disabling Sanitizers

For pure safe Rust (no unsafe blocks in your code or dependencies):

cargo +nightly fuzz run --sanitizer none fuzz_target_1


**Performance impact:** ASan adds ~2x overhead. Disable for safe Rust to improve fuzzing speed.

### Checking for Unsafe Code

cargo install cargo-geiger
cargo geiger


> **See Also:** For detailed sanitizer configuration, flags, and troubleshooting,
> see the **address-sanitizer** technique skill.

## Coverage Analysis

cargo-fuzz integrates with Rust's coverage tools to analyze fuzzing effectiveness.

### Prerequisites

rustup toolchain install nightly --component llvm-tools-preview
cargo install cargo-binutils
cargo install rustfilt


### Generating Coverage Reports

# Generate coverage data from corpus
cargo +nightly fuzz coverage fuzz_target_1


Create coverage generation script:

cat <<'EOF' > ./generate_html
#!/bin/sh
if [ $# -lt 1 ]; then
echo "Error: Name of fuzz target is required."
echo "Usage: $0 fuzz_target [sources...]"
exit 1
fi
FUZZ_TARGET="$1"
shift
SRC_FILTER="$@"
TARGET=$(rustc -vV | sed -n 's|host: ||p')
cargo +nightly cov -- show -Xdemangler=rustfilt \
"target/$TARGET/coverage/$TARGET/release/$FUZZ_TARGET" \
-instr-profile="fuzz/coverage/$FUZZ_TARGET/coverage.profdata" \
-show-line-counts-or-regions -show-instantiations \
-format=html -o fuzz_html/ $SRC_FILTER
EOF
chmod +x ./generate_html


Generate HTML report:
./generate_html fuzz_target_1 src/lib.rs


HTML report saved to: fuzz_html/

> **See Also:** For detailed coverage analysis techniques and systematic coverage improvement,
> see the **coverage-analysis** technique skill.

## Advanced Usage

### Tips and Tricks

| Tip | Why It Helps |
|-----|--------------|
| Start with a seed corpus | Dramatically speeds up initial coverage discovery |
| Use --sanitizer none for safe Rust | 2x performance improvement |
| Check coverage regularly | Identifies gaps in harness or seed corpus |
| Use dictionaries for parsers | Helps overcome magic value checks |
| Structure code as library | Required for cargo-fuzz integration |

### libFuzzer Options

Pass options to libFuzzer after --:

# See all options
cargo +nightly fuzz run fuzz_target_1 -- -help=1

# Set timeout per run
cargo +nightly fuzz run fuzz_target_1 -- -timeout=10

# Use dictionary
cargo +nightly fuzz run fuzz_target_1 -- -dict=dict.dict

# Limit maximum input size
cargo +nightly fuzz run fuzz_target_1 -- -max_len=1024


### Multi-Core Fuzzing

# Experimental forking support (not recommended)
cargo +nightly fuzz run --jobs 1 fuzz_target_1


Note: The multi-core fuzzing feature is experimental and not recommended. For parallel fuzzing, consider running multiple instances manually or using AFL++.

## Real-World Examples

### Example: ogg Crate

The [ogg crate](https://github.com/RustAudio/ogg) parses Ogg media container files. Parsers are excellent fuzzing targets because they handle untrusted data.

# Clone and initialize
git clone https://github.com/RustAudio/ogg.git
cd ogg/
cargo fuzz init


Harness at fuzz/fuzz_targets/fuzz_target_1.rs:

#![no_main]

use ogg::{PacketReader, PacketWriter};
use ogg::writing::PacketWriteEndInfo;
use std::io::Cursor;
use libfuzzer_sys::fuzz_target;

fn harness(data: &[u8]) {
let mut pck_rdr = PacketReader::new(Cursor::new(data.to_vec()));
pck_rdr.delete_unread_packets();

let output = Vec::new();
let mut pck_wtr = PacketWriter::new(Cursor::new(output));

if let Ok(_) = pck_rdr.read_packet() {
if let Ok(r) = pck_rdr.read_packet() {
match r {
Some(pck) => {
let inf = if pck.last_in_stream() {
PacketWriteEndInfo::EndStream
} else if pck.last_in_page() {
PacketWriteEndInfo::EndPage
} else {
PacketWriteEndInfo::NormalPacket
};
let stream_serial = pck.stream_serial();
let absgp_page = pck.absgp_page();
let _ = pck_wtr.write_packet(
pck.data, stream_serial, inf, absgp_page
);
}
None => return,
}
}
}
}

fuzz_target!(|data: &[u8]| {
harness(data);
});


Seed the corpus:
mkdir fuzz/corpus/fuzz_target_1/
curl -o fuzz/corpus/fuzz_target_1/320x240.ogg \
https://commons.wikimedia.org/wiki/File:320x240.ogg


Run:
cargo +nightly fuzz run fuzz_target_1


Analyze coverage:
cargo +nightly fuzz coverage fuzz_target_1
./generate_html fuzz_target_1 src/lib.rs


## Troubleshooting

| Problem | Cause | Solution |
|---------|-------|----------|
| "requires nightly" error | Using stable toolchain | Use cargo +nightly fuzz |
| Slow fuzzing performance | ASan enabled for safe Rust | Add --sanitizer none flag |
| "cannot find binary" | No library crate | Move code from main.rs to lib.rs |
| Sanitizer compilation issues | Wrong nightly version | Try different nightly: rustup install nightly-2024-01-01 |
| Low coverage | Missing seed corpus | Add sample inputs to fuzz/corpus/fuzz_target_1/ |
| Magic value not found | No dictionary | Create dictionary file with magic values |

## Related Skills

### Technique Skills

| Skill | Use Case |
|-------|----------|
| **fuzz-harness-writing** | Structure-aware fuzzing with arbitrary crate |
| **address-sanitizer** | Understanding ASan output and configuration |
| **coverage-analysis** | Measuring and improving fuzzing effectiveness |
| **fuzzing-corpus** | Building and managing seed corpora |
| **fuzzing-dictionaries** | Creating dictionaries for format-aware fuzzing |

### Related Fuzzers

| Skill | When to Consider |
|-------|------------------|
| **libfuzzer** | Fuzzing C/C++ code with similar workflow |
| **aflpp** | Multi-core fuzzing or non-Cargo Rust projects |
| **libafl** | Advanced fuzzing research or custom fuzzer development |

## Resources

**[Rust Fuzz Book - cargo-fuzz](https://rust-fuzz.github.io/book/cargo-fuzz.html)**
Official documentation for cargo-fuzz covering installation, usage, and advanced features.

**[arbitrary crate documentation](https://docs.rs/arbitrary/latest/arbitrary/)**
Guide to structure-aware fuzzing with automatic derivation for Rust types.

**[cargo-fuzz GitHub Repository](https://github.com/rust-fuzz/cargo-fuzz)**
Source code, issue tracker, and examples for cargo-fuzz.

How to Use This Skill Unit

Option A: Project-Specific (Recommended)

  1. Click "Download" above
  2. In your project, create the directory: .agent/skills/cargo-fuzz/
  3. Save the file as SKILL.md
  4. The agent will automatically discover the skill based on its description.

Option B: Global Installation (All Agents)

Save the file to these locations to make it available across all projects:

  • Claude Code: ~/.claude/skills/trailofbits/skills/cargo-fuzz/SKILL.md
  • Cursor: ~/.cursor/skills/trailofbits/skills/cargo-fuzz/SKILL.md
  • Antigravity: ~/.gemini/antigravity/skills/trailofbits/skills/cargo-fuzz/SKILL.md

πŸš€ Install with CLI:
npx skills add trailofbits/skills

Read the Master Guide: Mastering Agent Skills β†’

Recommended Rules

View more rules β†’

Recommended Workflows

View more workflows β†’

Recommended MCP Servers

View more MCP servers β†’

Take It Further

Maximize your productivity with these powerful resources

πŸ“‹

Define Your Standards

Set up coding standards to ensure this workflow produces consistent, high-quality results.

Browse Rules Library
πŸ“–

Master Workflows

Learn how to create custom workflows, use Turbo Mode, and build your automation library.

Complete Guide

How to use this Skill in Claude Code & Cursor

For Claude Code (CLI)

To use this skill in Claude Code, copy the rule content into your project's custom instructions or follow our Add-Skill CLI guide. This ensures Claude follows your standards during every code generation.

For Cursor & Windsurf

For Cursor or Windsurf, individual skills are best used in the "Rules for AI" section. This specific unit helps the agent avoid security & vulnerability analysis issues, leading to cleaner, more efficient code.

Why the skill format matters: the standardized Agent Skills format lets your AI agent load detailed instructions only when they are relevant, keeping your prompt clean while improving results.

Source & attribution

This skill is categorized under Security & Vulnerability Analysis and is published by Trail of Bits, maintained in trailofbits/skills.

← Browse All Agent Skills
Sponsored AI assistant. Recommendations may be paid.