Fuzzing is a testing technique that automatically feeds unexpected inputs to software to find flaws. This page explains how it works and how to start on your own code (it does not cover testing other people's systems).
What fuzzing is
OWASP describes fuzzing as a software testing technique aimed at identifying bugs, vulnerabilities, or unexpected behavior. It automatically supplies invalid, unexpected, or partly invalid inputs and watches whether the program misbehaves. The NIST glossary (citing NIST SP 800-95) likewise describes fuzz testing as tools called fuzzers submitting combinations of inputs to a test target to reveal how it responds.
Its strength is that it makes few assumptions about how the system should behave. Tests written by hand cover only the cases someone thought of. A fuzzer can find places that break on inputs nobody imagined.
How it works
Most modern fuzzers are coverage-guided. They measure which code ran, keep inputs that reached new code, and mutate those to create the next inputs. That gets deeper into the program than random input alone. LLVM's libFuzzer is documented as an in-process, coverage-guided, evolutionary fuzzing engine that is linked into the library under test.
Common tools
| Tool | Main targets | Notes |
|---|---|---|
| libFuzzer | C/C++ and others (LLVM) | Linked into the target. Per its documentation, the original authors moved to the Centipede engine and it now gets only important bug fixes |
| AFL++ | C/C++ and others | A widely used coverage-guided fuzzer |
| Go built-in fuzzing | Go (1.18 or later) | Run with go test -fuzz. Failing inputs are saved under testdata and replayed by normal tests |
| OSS-Fuzz | Open source software | Google's free continuous fuzzing service, using several engines and sanitizers |
A libFuzzer fuzz target is a function (LLVMFuzzerTestOneInput) that receives the input bytes and their length. In Go you write a test function named FuzzXxx that takes a *testing.F and add seed inputs with f.Add.
How to start on your own software
- Pick a function that parses input (a file-format parser, config loader, protocol handler)
- Write a small fuzz target that just passes the input to it. Keep it fast and deterministic, with no state carried between calls
- Add a few typical valid inputs as seeds
- Turn on a sanitizer such as AddressSanitizer and run for a set time (in Go,
-fuzztimesets the length) - Turn each failing input into a reproducible test, and keep it as a regression test after the fix
- To keep going, run short sessions in CI, or for open source, consider joining OSS-Fuzz
Go's fuzzing has a 1-second limit per execution, and coverage guidance works on AMD64 and ARM64. Check the official documentation for limits in your environment.
Only fuzz software you manage
Fuzzing keeps sending large volumes of malformed input. Doing that to a service or server you have no permission to test may count as unauthorized access or disruption of service. Limit it to software you develop or manage, in your own environment.
What it can and can't do
OWASP says fuzzing complements, rather than replaces, manual code review and debugging. It also notes that fuzzers tend to find simple bugs, and that with black-box testing it is harder to judge the impact of a finding.
So fuzzing is strong at "letting a machine search for ways the code breaks," and weak at design-level problems such as missing authorization. For those, such as IDOR, rely on tests that check the intended rules.
This site's view: finding the input is half the job; keep it as a regression test
What matters is not just running a fuzzer but saving what it finds as a regression test. Go's built-in fuzzing, which stores a failing input under testdata and replays it in normal tests, follows this idea. It keeps a fixed bug from coming back after a later change. If you own code that parses input, a realistic first step is to fuzz a single function.
Sources (primary)
- OWASP Community, "Fuzzing" — owasp.org (definition, characteristics, limits)
- NIST CSRC Glossary, "fuzz testing" — csrc.nist.gov (source: NIST SP 800-95)
- LLVM, "libFuzzer" — llvm.org (how it works, fuzz target, maintenance status)
- Go, "Fuzzing" — go.dev (Go 1.18 or later, how to run, limits)
- Google, "OSS-Fuzz" — google.github.io (overview, supported engines). Bug counts change over time, so none are quoted here. For AFL++, check its official documentation for current usage