Testland
Browse all skills & agents

fuzz-toolkit-dispatcher

Toolkit / dispatcher skill that routes a fuzz-target authoring task to the correct per-language fuzzer skill based on detected language. Decision tree: C/C++ → libfuzzer-cpp + afl-plus-plus; Rust → cargo-fuzz-rust (or libfuzzer-cpp via FFI); Go → go-native-fuzzing; Python → atheris-python-fuzzing; JVM → jazzer-jvm-fuzzing; closed-source binary → afl-plus-plus in QEMU mode; mature open-source project → ossfuzz-integration. Composes with corpus-management-reference + sanitiser-integration-reference. Use as the dispatcher backing fuzz-target-author.

fuzz-toolkit-dispatcher

Overview

Decision tree routing a fuzz-target authoring task to the right per-language fuzzer skill. Composes the seven per-language skills + the two references in the plugin. Picks based on target language, source-availability, and OSS-Fuzz eligibility.

When to use

  • Authoring a fuzz target - pick the right fuzzer before writing the harness.
  • Reviewing an existing fuzz target - verify the right fuzzer was selected.
  • Backing the fuzz-target-author agent's per-language routing.

Decision tree

Step 1: Identify target language(s).

+-------+----------+--------+--------+-------+--------+--------+
| C/C++ |   Rust   |   Go   | Python |  JVM  | Other  | Binary |
|       |          |        |        |       |        | (no    |
|       |          |        |        |       |        | source)|
+-------+----------+--------+--------+-------+--------+--------+
    ↓        ↓         ↓        ↓        ↓        ↓        ↓
  Step 2:                                            AFL++
  Library    cargo-    go test  Atheris  Jazzer    Choose    -Q mode
  function?   fuzz     -fuzz                       per LLVM
   YES                                              -fsanitize
    ↓                                                support
  libFuzzer
  (in-process)
   OR
  AFL++ (file-driven)

Step 3: Is this a mature open-source project?

        YES → also submit to OSS-Fuzz

                                          ossfuzz-integration

Routing rules

Target characteristicRoute to
C / C++ library with callable function APIlibfuzzer-cpp
C / C++ binary processing filesafl-plus-plus
C / C++ source unavailableafl-plus-plus (-Q QEMU)
Rust cratecargo-fuzz-rust
Rust binary processing filesafl-plus-plus
Go packagego-native-fuzzing
Pure Python or CPython native extensionatheris-python-fuzzing
Java / Kotlin / Scala / Groovy libraryjazzer-jvm-fuzzing
Swift librarylibfuzzer-cpp (Swift wraps libFuzzer natively)
Mature open-source project (any of the above languages)Also: ossfuzz-integration (continuous 24x7 campaign)

Routing rationale

C/C++

Prefer libFuzzer for callable APIs (parsers, validators, decoders). In-process iteration is fastest. Pair with ASan + UBSan per sanitiser-integration-reference.

Switch to AFL++ when:

  • The target reads input via stdin or file argument (file-format tools, command-line utilities)
  • You need QEMU mode for closed-source binaries
  • You want a different mutation engine - AFL++ and libFuzzer find different bugs

Many mature projects run both libFuzzer and AFL++ targets in parallel.

Rust

Prefer cargo-fuzz - integrates with cargo, supports Arbitrary for structured input. Requires nightly toolchain.

For Rust binaries (not callable library APIs), AFL++ works similarly to C/C++ - wrap the binary with AFL++.

Go

Use Go native fuzzing - built into the standard testing package as of Go 1.18. Failing inputs auto-save as regression fixtures.

For binary-level Go fuzzing or fuzzing CGo dependencies, AFL++ in -Q mode works.

Python

Use Atheris - Google's libFuzzer-backed Python fuzzer. Supports both pure-Python and CPython native extensions.

For pure property-based testing in Python (without coverage guidance), consider Hypothesis in qa-property-based - complementary, not competing.

JVM

Use Jazzer - Code Intelligence's libFuzzer-backed JVM fuzzer. JUnit 5 integration via @FuzzTest. Ships JVM-level sanitisers (deserialization, SSRF, ReDoS, OS command injection).

Other languages

Languages with libFuzzer-compatible sanitiser-coverage support (Swift, Objective-C, some Haskell setups): use libFuzzer directly via the language's FFI / wrapper.

Languages without native fuzzer support (e.g., Erlang, OCaml): test via AFL++ on the compiled binary.

OSS-Fuzz overlay

Independent of the per-language choice: if the project is open-source, mature, and security-relevant, also onboard to ossfuzz-integration. OSS-Fuzz runs the existing libFuzzer / AFL++ / Jazzer harness 24x7 on Google infrastructure with automatic crash reports.

Anti-patterns

Anti-patternWhy it failsFix
Picking AFL++ for a callable C/C++ library APIOut-of-process overhead 10-100xUse libFuzzer for in-process
Picking libFuzzer for a file-processing binaryAdapter glue is complex; AFL++ handles @@ cleanlyUse AFL++
Picking cargo-fuzz on stable RustWon't compileUse nightly toolchain
Skipping OSS-Fuzz for a mature open-source projectMisses continuous 24x7 fuzzingSubmit alongside in-house CI fuzz
Mixing fuzzer outputs without considering corpus formatlibFuzzer / AFL++ corpora aren't directly compatibleUse one fuzzer's corpus; convert if needed
Routing based on language alone, ignoring "source available"Closed-source need QEMU regardless of source languageAlways factor in availability

Limitations

  • Doesn't replace per-language expertise. Knowing libFuzzer's flags vs AFL++'s requires reading the linked skill.
  • Doesn't handle cross-language targets. A JNI library: Java side via Jazzer, C side via libFuzzer; two separate campaigns.
  • OSS-Fuzz eligibility heuristic. "Mature open-source" is judgemental; OSS-Fuzz acceptance committee has the final say.

References