New to Claude Skills? Learn how to install them →

mukul975 on GitHub

Fuzz Testing in CI/CD with AFL++

Free

Integrate AFL++ fuzz testing into your CI/CD pipeline.

Get this skill

Free · Opens the source repo

What Fuzz Testing in CI/CD with AFL++ does

This skill provides a comprehensive integration of AFL++ (American Fuzzy Lop Plus Plus) into CI/CD pipelines, aimed at enhancing the security testing of C/C++ applications. AFL++ is a powerful fuzz testing tool that employs coverage-guided techniques to discover vulnerabilities by mutating inputs and tracking code paths. By using this skill, developers can automate the process of identifying memory corruption and input handling vulnerabilities, significantly improving the security posture of their applications.

The skill walks users through the necessary steps to set up AFL++ in a CI/CD environment, including harness construction, instrumentation builds, and configuration for persistent fuzzing. It covers essential prerequisites such as the need for a Linux-based CI runner, a compatible compiler toolchain, and a seed corpus of valid inputs. The detailed workflows provided in the skill guide users through building fuzzing harnesses, compiling with AFL++ instrumentation, and integrating fuzz testing into their CI/CD processes using tools like GitHub Actions.

By leveraging AFL++'s capabilities, this skill enables continuous testing of various components such as parsers and protocol handlers, ensuring that any untrusted input is rigorously tested. This proactive approach to security testing allows teams to catch vulnerabilities early in the development cycle, thereby reducing the risk of security issues in production environments.

Overall, this skill is particularly beneficial for developers and security engineers looking to enhance their CI/CD workflows with automated fuzz testing, ensuring robust security measures are in place throughout the software development lifecycle.

When to use it

Use this skill when you need to implement fuzz testing in your CI/CD pipeline, particularly for C/C++ applications.

When not to use it

This skill is not suitable for projects that do not use C/C++ or for CI/CD environments that are not Linux-based.

What you can build with it

Automating Security Testing

Integrate fuzz testing into your CI/CD pipeline to automatically identify vulnerabilities during the development process.

Enhancing Compliance Measures

Use this skill to implement security controls that align with compliance requirements for software development.

Improving Application Security

Conduct security assessments by incorporating fuzz testing to discover memory-safety bugs in your applications.

How to install Fuzz Testing in CI/CD with AFL++

View source

1. Install with the skills CLI

npx skills add mukul975/anthropic-cybersecurity-skills/implementing-fuzz-testing-in-cicd-with-aflplusplus --agent claude-code

2. Or install it manually

Download the skill folder and drop it into ~/.claude/skills/ for all projects, or .claude/skills/ to scope it to one repo. Restart Claude Code so it picks up the new skill.

Anthropic's agentic coding CLI, and the reference implementation of Agent Skills. Drop a skill folder into ~/.claude/skills and Claude Code loads it automatically whenever a task matches the skill's description. Claude Code docs

Inside SKILL.md

Written by mukul975

Implementing Fuzz Testing in CI/CD with AFL++

Overview

AFL++ (American Fuzzy Lop Plus Plus) is a community-maintained fork of AFL that provides state-of-the-art coverage-guided fuzz testing for discovering vulnerabilities in compiled applications. AFL++ uses genetic algorithms to mutate inputs, tracking code coverage to find new execution paths that trigger crashes, hangs, and undefined behavior. In CI/CD environments, AFL++ can be integrated to continuously test parsers, protocol handlers, file format processors, and any code that handles untrusted input. AFL++ supports persistent mode for high-speed fuzzing (up to 100,000+ executions per second), custom mutators, QEMU mode for binary-only fuzzing, and CmpLog/RedQueen for automatic dictionary extraction.

When to Use

  • When deploying or configuring implementing fuzz testing in cicd with aflplusplus capabilities in your environment
  • When establishing security controls aligned to compliance requirements
  • When building or improving security architecture for this domain
  • When conducting security assessments that require this implementation

Prerequisites

  • Linux-based CI runners (AFL++ does not support Windows natively)
  • GCC or Clang compiler toolchain
  • AFL++ installed (apt install aflplusplus or built from source)
  • Target application with harness functions isolating input processing
  • Seed corpus of valid input samples

Core Concepts

Coverage-Guided Fuzzing

AFL++ instruments the target binary at compile time (or via QEMU/Frida for binary-only targets) to track which code paths each input exercises. When a mutated input triggers a new code path, it is saved to the corpus for further mutation. This feedback loop enables AFL++ to systematically explore program state space.

Instrumentation Modes

ModeUse CasePerformance
afl-clang-fast (LTO)Source available, best performanceHighest
afl-clang-fastSource available, standardHigh
afl-gcc-fastGCC-based projectsHigh
QEMU modeBinary-only, no sourceMedium
Frida modeBinary-only, cross-platformMedium
Unicorn modeFirmware, embeddedLow

Persistent Mode

Persistent mode avoids fork overhead by fuzzing within a loop:

#include <unistd.h>

__AFL_FUZZ_INIT();

int main() {
    __AFL_INIT();
    unsigned char *buf = __AFL_FUZZ_TESTCASE_BUF;

    while (__AFL_LOOP(10000)) {
        int len = __AFL_FUZZ_TESTCASE_LEN;
        // Process buf[0..len-1]
        parse_input(buf, len);
    }
    return 0;
}

Workflow

Step 1 --- Build the Fuzzing Harness

Create a harness that feeds AFL++ input to the target function:

// fuzz_harness.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "target_parser.h"

__AFL_FUZZ_INIT();

int main() {
    __AFL_INIT();
    unsigned char *buf = __AFL_FUZZ_TESTCASE_BUF;

    while (__AFL_LOOP(10000)) {
        int len = __AFL_FUZZ_TESTCASE_LEN;
        if (len < 4) continue;

        // Reset state between iterations
        parser_context_t ctx;
        parser_init(&ctx);
        parser_process(&ctx, buf, len);
        parser_cleanup(&ctx);
    }
    return 0;
}

Step 2 --- Compile with AFL++ Instrumentation

# Standard instrumentation
export CC=afl-clang-fast
export CXX=afl-clang-fast++

# Enable AddressSanitizer for better crash detection
export AFL_USE_ASAN=1

# Build the target with instrumentation
$CC -o fuzz_harness fuzz_harness.c -ltarget_parser -fsanitize=address

# Build a CmpLog binary for better coverage
$CC -o fuzz_harness_cmplog fuzz_harness.c -ltarget_parser \
  -fsanitize=address -DCMPLOG

Step 3 --- Prepare Seed Corpus

mkdir -p corpus/
# Add valid input samples
cp test_inputs/* corpus/
# Minimize the corpus
afl-cmin -i corpus/ -o corpus_min/ -- ./fuzz_harness @@
# Further minimize individual inputs
mkdir -p corpus_tmin/
for f in corpus_min/*; do
    afl-tmin -i "$f" -o "corpus_tmin/$(basename $f)" -- ./fuzz_harness @@
done

Step 4 --- Configure CI/CD Integration

GitHub Actions:

name: Fuzz Testing
on:
  push:
    branches: [main]
  schedule:
    - cron: '0 2 * * *'  # Nightly fuzzing

jobs:
  fuzz:
    runs-on: ubuntu-latest
    timeout-minutes: 120
    steps:
      - uses: actions/checkout@v4

      - name: Install AFL++
        run: |
          sudo apt-get update
          sudo apt-get install -y aflplusplus

      - name: Restore corpus cache
        uses: actions/cache@v4
        with:
          path: corpus/
          key: fuzz-corpus-${{ github.sha }}
          restore-keys: fuzz-corpus-

      - name: Build fuzzing harness
        run: |
          export CC=afl-clang-fast
          export AFL_USE_ASAN=1
          make fuzz_harness

      - name: Run AFL++ fuzzing (CI mode)
        env:
          AFL_CMPLOG_ONLY_NEW: 1
          AFL_FAST_CAL: 1
          AFL_NO_STARTUP_CALIBRATION: 1
        run: |
          mkdir -p findings/
          timeout 7200 afl-fuzz \
            -S ci_fuzzer \
            -i corpus/ \
            -o findings/ \
            -t 5000 \
            -- ./fuzz_harness @@ || true

      - name: Check for crashes
        run: |
          CRASHES=$(find findings/ -path "*/crashes/*" -not -name "README.txt" | wc -l)
          echo "Found $CRASHES unique crashes"
          if [ "$CRASHES" -gt 0 ]; then
            echo "::error::AFL++ found $CRASHES crashes"
            for crash in findings/*/crashes/*; do
              [ -f "$crash" ] && echo "Crash: $crash ($(wc -c < $crash) bytes)"
            done
            exit 1
          fi

      - name: Update corpus cache
        if: always()
        run: |
          afl-cmin -i findings/ci_fuzzer/queue/ -o corpus/ -- ./fuzz_harness @@

Step 5 --- Parallel Fuzzing for Nightly Runs

# Launch multiple secondary instances for better coverage
for i in $(seq 1 $(nproc)); do
    afl-fuzz -S fuzzer_$i \
      -i corpus/ \
      -o findings/ \
      -- ./fuzz_harness @@ &
done

# Wait for all fuzzers
wait

# Merge and minimize corpus
afl-cmin -i findings/*/queue/ -o corpus_merged/ -- ./fuzz_harness @@

Step 6 --- Crash Triage

# Reproduce and categorize crashes
for crash in findings/*/crashes/*; do
    echo "=== Testing: $crash ==="
    timeout 5 ./fuzz_harness_asan "$crash" 2>&1 | head -20
    echo "---"
done

# Deduplicate crashes by stack trace
afl-collect findings/ crashes_deduped/ -- ./fuzz_harness @@

CI/CD Best Practices for AFL++

SettingCI Short RunNightly Long Run
Duration30-60 min4-24 hours
Mode-S (secondary only)-S (no -M for CI)
AFL_CMPLOG_ONLY_NEW11
AFL_FAST_CAL10
AFL_NO_STARTUP_CALIBRATION10
Corpus cachingRequiredRequired
Parallel instances1-2nproc

Monitoring Fuzzing Campaigns

# View fuzzing statistics
afl-whatsup findings/

# Key metrics to track:
# - Total paths found (code coverage indicator)
# - Unique crashes / unique hangs
# - Stability percentage (should be >90%)
# - Exec speed (execs/sec)
# - Cycles done (full corpus cycles completed)

References

Frequently asked questions about Fuzz Testing in CI/CD with AFL++

Similar skills