aflpp
AFL++ is an advanced fuzzer that extends the original AFL with improved performance and multi-core fuzzing capabilities, making it ideal for comprehensive testing of mature codebases. Use AFL++ when you need parallel fuzzing across multiple cores, have projects compilable with Clang or GCC, and require diverse mutation strategies beyond what simpler fuzzers offer.
git clone --depth 1 https://github.com/trailofbits/skills /tmp/aflpp && cp -r /tmp/aflpp/plugins/testing-handbook-skills/skills/aflpp ~/.claude/skills/aflppSKILL.md
# AFL++
AFL++ is a fork of the original AFL fuzzer that offers better fuzzing performance and more advanced features while maintaining stability. A major benefit over libFuzzer is that AFL++ has stable support for running fuzzing campaigns on multiple cores, making it ideal for large-scale fuzzing efforts.
## When to Use
| Fuzzer | Best For | Complexity |
|--------|----------|------------|
| AFL++ | Multi-core fuzzing, diverse mutations, mature projects | Medium |
| libFuzzer | Quick setup, single-threaded, simple harnesses | Low |
| LibAFL | Custom fuzzers, research, advanced use cases | High |
**Choose AFL++ when:**
- You need multi-core fuzzing to maximize throughput
- Your project can be compiled with Clang or GCC
- You want diverse mutation strategies and mature tooling
- libFuzzer has plateaued and you need more coverage
- You're fuzzing production codebases that benefit from parallel execution
## Quick Start
```c++
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
// Call your code with fuzzer-provided data
check_buf((char*)data, size);
return 0;
}
```
Compile and run:
```bash
# Setup AFL++ wrapper script first (see Installation)
./afl++ docker afl-clang-fast++ -DNO_MAIN=1 -O2 -fsanitize=fuzzer harness.cc main.cc -o fuzz
mkdir seeds && echo "aaaa" > seeds/minimal_seed
./afl++ docker afl-fuzz -i seeds -o out -- ./fuzz
```
## Installation
AFL++ has many dependencies including LLVM, Python, and Rust. We recommend using a current Debian or Ubuntu distribution for fuzzing with AFL++.
| Method | When to Use | Supported Compilers |
|--------|-------------|---------------------|
| Ubuntu/Debian repos | Recent Ubuntu, basic features only | Ubuntu 23.10: Clang 14 & GCC 13<br>Debian 12: Clang 14 & GCC 12 |
| Docker (from Docker Hub) | Specific AFL++ version, Apple Silicon support | As of 4.35c: Clang 19 & GCC 11 |
| Docker (from source) | Test unreleased features, apply patches | Configurable in Dockerfile |
| From source | Avoid Docker, need specific patches | Adjustable via `LLVM_CONFIG` env var |
### Ubuntu/Debian
Prior to installing afl++, check the clang version dependency of the packge with `apt-cache show afl++`, and install the matching `lld` version (e.g., `lld-17`).
```bash
apt install afl++ lld-17
```
### Docker (from Docker Hub)
```bash
docker pull aflplusplus/aflplusplus:stable
```
### Docker (from source)
```bash
git clone --depth 1 --branch stable https://github.com/AFLplusplus/AFLplusplus
cd AFLplusplus
docker build -t aflplusplus .
```
### From source
Refer to the [Dockerfile](https://github.com/AFLplusplus/AFLplusplus/blob/stable/Dockerfile) for Ubuntu version requirements and dependencies. Set `LLVM_CONFIG` to specify Clang version (e.g., `llvm-config-18`).
### Wrapper Script Setup
Create a wrapper script to run AFL++ on host or Docker:
```bash
cat <<'EOF' > ./afl++
#!/bin/sh
AFL_VERSION="${AFL_VERSION:-"stable"}"
case "$1" in
host)
shift
bash -c "$*"
;;
docker)
shift
/usr/bin/env docker run -i \
--privileged \
-v ./:/src \
--rm \
--name "afl_fuzzing_$$" \
"aflplusplus/aflplusplus:$AFL_VERSION" \
bash -c "cd /src && bash -c \"$*\""
;;
*)
echo "Usage: $0 {host|docker}"
exit 1
;;
esac
EOF
chmod +x ./afl++
```
The examples below use `docker` mode, apart from the system configuration commands that have to reach the host kernel. Swap in `host` to run any of them against an AFL++ installed on the machine itself. The wrapper joins everything after the mode argument into a single shell string, so quoting does not survive: an argument containing a space (`-x "my dict.dict"`) arrives word-split. Rename such files without spaces, or edit the wrapper for that run.
The missing `-t` is deliberate. `docker run -ti` aborts with `the input device is not a TTY` whenever stdin is not a terminal, which covers CI jobs and anything an agent or script drives. `afl-fuzz` notices there is no terminal and prints plain status lines in place of the full-screen UI. A program that insists on a terminal, such as `watch`, has to run on the host side of the wrapper instead. `$$` expands to the wrapper's PID, so parallel instances get distinct container names rather than colliding on a single `afl_fuzzing`. `docker ps` truncates the COMMAND column, so every row looks alike; use `docker ps --no-trunc` to tell the instances apart before stopping one.
**Security Warning:** The `afl-system-config` and `afl-persistent-config` scripts require root privileges and disable OS security features. Do not fuzz on production systems or your development environment. Use a dedicated VM instead.
### System Configuration
Run after each reboot for up to 15% more executions per second:
```bash
./afl++ host afl-system-config
```
`afl-system-config` tunes the kernel it runs against, so run it on the machine that hosts the campaign. `./afl++ docker afl-system-config` reaches the same settings through the wrapper's `--privileged` container, which is the only route when AFL++ is installed via Docker alone.
For maximum performance, disable kernel security mitigations (requires grub bootloader, not supported in Docker):
```bash
./afl++ host afl-persistent-config
update-grub
reboot
./afl++ host afl-system-config
```
Verify with `cat /proc/cmdline` - output should include `mitigations=off`.
## Writing a Harness
### Harness Structure
AFL++ supports libFuzzer-style harnesses:
```c++
#include <stdint.h>
#include <stddef.h>
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
// 1. Validate input size if needed
if (size < MIN_SIZE || size > MAX_SIZE) return 0;
// 2. Call target function with fuzz data
target_function(data, size);
// 3. Return 0 (non-zero reserved for future use)
return 0;
}
```
### Harness Rules
| Do | Don't |
|----|-------|
| Reset global state bAudits GitHub Actions workflows for security vulnerabilities in AI agent integrations including Claude Code Action, Gemini CLI, OpenAI Codex, and GitHub AI Inference. Detects attack vectors where attacker-controlled input reaches AI agents running in CI/CD pipelines, including env var intermediary patterns, direct expression injection, dangerous sandbox configurations, and wildcard user allowlists. Use when reviewing workflow files that invoke AI coding agents, auditing CI/CD pipeline security for prompt injection risks, or evaluating agentic action configurations.
Clarify requirements before implementing. Use when serious doubts arise.
Understand a codebase before looking for bugs in it - what each function assumes, what it guarantees, and what it depends on elsewhere. Use when starting an audit, threat model, or architecture review on unfamiliar code, and before any vulnerability-hunting pass.
Scans Algorand smart contracts for 11 common vulnerabilities including rekeying attacks, unchecked transaction fees, missing field validations, and access control issues. Use when auditing Algorand projects (TEAL/PyTeal).
Prepares codebases for security review using Trail of Bits' checklist. Helps set review goals, runs static analysis tools, increases test coverage, removes dead code, ensures accessibility, and generates documentation (flowcharts, user stories, inline comments). Use when preparing your own codebase to be audited by someone else, getting a repository review-ready before an external security review, deciding what to fix before auditors start, or asking what assessors need from a project. For understanding unfamiliar code you are about to audit, use audit-context-building instead.
Scans Cairo/StarkNet smart contracts for 6 critical vulnerabilities including felt252 arithmetic overflow, L1-L2 messaging issues, address conversion problems, and signature replay. Use when auditing StarkNet projects.
Systematic code maturity assessment using Trail of Bits' 9-category framework. Analyzes codebase for arithmetic safety, auditing practices, access controls, complexity, decentralization, documentation, MEV risks, low-level code, and testing, then produces a scorecard with evidence-based ratings and a priority-ordered roadmap. Use when assessing or scoring the maturity of a smart contract or blockchain codebase, producing a maturity scorecard or evaluation, or judging how mature, well-tested, or well-documented such a project is against a rubric.
Scans Cosmos SDK blockchain modules and CosmWasm contracts for consensus-critical vulnerabilities — chain halts, fund loss, state divergence. 25 core + 16 IBC + 10 EVM + 3 CosmWasm patterns. Use when auditing custom x/ modules, reviewing IBC integrations, or assessing pre-launch chain security. Updated for SDK v0.53.x.