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.
Best use case
cargo-fuzz is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
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.
Teams using cargo-fuzz should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/cargo-fuzz/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How cargo-fuzz Compares
| Feature / Agent | cargo-fuzz | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
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.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# 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
```rust
#![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:
```bash
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
```bash
# Install nightly toolchain
rustup install nightly
# Install cargo-fuzz
cargo install cargo-fuzz
```
### Verification
```bash
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:
```text
src/main.rs # Entry point (main function)
src/lib.rs # Code to fuzz (public functions)
Cargo.toml
```
Initialize fuzzing:
```bash
cargo fuzz init
```
This creates:
```text
fuzz/
├── Cargo.toml
└── fuzz_targets/
└── fuzz_target_1.rs
```
### Harness Structure
```rust
#![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:
```rust
// In your library crate
use arbitrary::Arbitrary;
#[derive(Debug, Arbitrary)]
pub struct Name {
data: String
}
```
```rust
// 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`:
```toml
[dependencies]
arbitrary = { version = "1", features = ["derive"] }
```
## Running Campaigns
### Basic Run
```bash
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:
```bash
cargo +nightly fuzz run --sanitizer none fuzz_target_1
```
Check if your project uses unsafe code:
```bash
cargo install cargo-geiger
cargo geiger
```
### Re-executing Test Cases
```bash
# 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
```bash
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:
```bash
cargo +nightly fuzz run fuzz_target_1
```
### Disabling Sanitizers
For pure safe Rust (no unsafe blocks in your code or dependencies):
```bash
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
```bash
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
```bash
rustup toolchain install nightly --component llvm-tools-preview
cargo install cargo-binutils
cargo install rustfilt
```
### Generating Coverage Reports
```bash
# Generate coverage data from corpus
cargo +nightly fuzz coverage fuzz_target_1
```
Create coverage generation script:
```bash
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:
```bash
./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 `--`:
```bash
# 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
```bash
# 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.
```bash
# 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`:
```rust
#![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:
```bash
mkdir fuzz/corpus/fuzz_target_1/
curl -o fuzz/corpus/fuzz_target_1/320x240.ogg \
https://commons.wikimedia.org/wiki/File:320x240.ogg
```
Run:
```bash
cargo +nightly fuzz run fuzz_target_1
```
Analyze coverage:
```bash
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.Related Skills
fuzzing-apis
This skill enables Claude to perform automated fuzz testing on APIs to discover vulnerabilities, crashes, and unexpected behavior. It leverages malformed inputs, boundary values, and random payloads to generate comprehensive fuzz test suites. Use this skill when you need to identify potential SQL injection, XSS, command injection vulnerabilities, input validation failures, and edge cases in APIs. Trigger this skill by requesting fuzz testing, vulnerability scanning, or security analysis of an API. The skill is invoked using the `/fuzz-api` command.
OSS-Fuzz
[OSS-Fuzz](https://google.github.io/oss-fuzz/) is an open-source project developed by Google that provides free distributed infrastructure for continuous fuzz testing. It streamlines the fuzzing process and facilitates simpler modifications. While only select projects are accepted into OSS-Fuzz, the project's core is open-source, allowing anyone to host their own instance for private projects.
Writing Fuzzing Harnesses
A fuzzing harness is the entrypoint function that receives random data from the fuzzer and routes it to your system under test (SUT). The quality of your harness directly determines which code paths get exercised and whether critical bugs are found. A poorly written harness can miss entire subsystems or produce non-reproducible crashes.
Overcoming Fuzzing Obstacles
Codebases often contain anti-fuzzing patterns that prevent effective coverage. Checksums, global state (like time-seeded PRNGs), and validation checks can block the fuzzer from exploring deeper code paths. This technique shows how to patch your System Under Test (SUT) to bypass these obstacles during fuzzing while preserving production behavior.
Fuzzing Dictionary
A fuzzing dictionary provides domain-specific tokens to guide the fuzzer toward interesting inputs. Instead of purely random mutations, the fuzzer incorporates known keywords, magic numbers, protocol commands, and format-specific strings that are more likely to reach deeper code paths in parsers, protocol handlers, and file format processors.
api-fuzzing-for-bug-bounty
This skill should be used when the user asks to "test API security", "fuzz APIs", "find IDOR vulnerabilities", "test REST API", "test GraphQL", "API penetration testing", "bug bounty API testing", or needs guidance on API security assessment techniques.
api-fuzzing-bug-bounty
This skill should be used when the user asks to "test API security", "fuzz APIs", "find IDOR vulnerabilities", "test REST API", "test GraphQL", "API penetration testing", "bug b...
rust-cargo-assistant
Cargo build system, crate management, and Rust project configuration assistance.
ffuf (Fuzz Faster U Fool)
## Overview
SKILL: Fuzzing
## Metadata
SKILL: Week 2: Finding Vulnerabilities Through Fuzzing
## Metadata
Daily Logs
Record the user's daily activities, progress, decisions, and learnings in a structured, chronological format.