Screenshot of the GitHub Security Lab Fuzzing Taskflow dashboard
GitHub Security Lab / GitHub Blog
by VibecodedThis

GitHub Security Lab open-sources an autonomous fuzzing agent for C and C++

The new Fuzzing Taskflow writes harnesses, runs AFL++, chases coverage, and triages crashes into reports with suggested fixes, all without a human babysitting it.

Share

GitHub's Security Lab wants to automate the most tedious part of continuous fuzzing, and it just published the agent to do it. The Fuzzing Taskflow, introduced by researcher Antonio Morales, is a fully autonomous fuzzing pipeline for C and C++ projects. Point it at a GitHub repo and it handles everything downstream: finding entrypoints, analyzing the build system, writing fuzz harnesses, running AFL++, reading coverage reports, improving the harnesses, triaging crashes, and writing a vulnerability report for each unique bug.

The pipeline is built on the lab's Taskflow Agent framework, which expresses security workflows as explicit staged taskflows instead of one open-ended prompt. The design rule is a clean separation of responsibility: the LLM agent owns the decisions, and the tools own the execution. An MCP toolset exposes primitives like compiling a harness or running AFL; the agent never calls AFL or clang directly. All state flows through a SQLite database, so the stages never hand data to each other in memory.

The centerpiece is a coverage-feedback loop. Each iteration, the agent runs AFL for a time budget, replays the queue against a coverage-instrumented build to get a real source-line report, then reads the uncovered branches and picks a fix: craft a new seed, edit the harness to call another API, auto-enrich the AFL dictionary with the magic constants sitting near the guards it missed, or skip a cold error path not worth chasing. Budgets double every iteration, from 30 seconds up to about 32 minutes per target, and plateau detection stops the loop when two consecutive rounds each gain less than a percent of absolute line coverage.

Fuzzing lives or dies on inputs, so the pipeline ships four structure-aware mechanisms: prebuilt dictionaries and custom mutators for recognized formats like JSON, XML, and regex (the XML one knows billion-laughs tokens; the regex one carries real ReDoS patterns); a source-level dictionary mined from the target's own .c and .h files, on the theory that the magic values a parser checks usually appear somewhere in its own source; coverage-driven enrichment that grows the dictionary toward code the fuzzer cannot reach yet; and a corpus-splice operator that recombines saved inputs.

Triage is where the time goes

Finding a crash is only half the job. Every crash is minimized with afl-tmin, replayed under AddressSanitizer, and deduplicated by a stack-top hash so semantically identical crashes collapse together. The agent then replays previously known crashes against the current binary to check whether an upstream fix resolved them, and writes a per-crash markdown report with a verdict: real vulnerability, library hardening issue, harness bug, OOM, timeout, assertion failure, or duplicate. Each report carries root-cause analysis with file and line references, a reachability argument, an exploitability assessment, a suggested fix as a unified diff, and a regression-test sketch. The patches are marked review required for good reason: an agent's verdict is a well-prepared starting point for a human, not a conclusion.

One warning should be taken literally. The pipeline runs afl-fuzz, clang, and arbitrary build commands chosen by the LLM directly on the host with no container in between, so it should run only in a disposable environment like a Codespace or throwaway VM, without elevated privileges. The code is open source at GitHubSecurityLab/seclab-taskflows-fuzzing, and the quickest smoke test is a one-liner against cJSON. The default model is Claude Sonnet 5, chosen because it passed the lab's internal tests without tripping output guardrails.