Fuzzing (fuzz testing) is an automated technique that feeds a program large volumes of invalid, unexpected or random input and watches for crashes, hangs, failed assertions and memory errors. Those failures often point to security bugs such as buffer overflows, use-after-free errors and parsing flaws that ordinary unit tests miss, because nobody thought to write that input by hand.
This guide covers what fuzzing is, where it came from, how a fuzzer works, the main types, the tools teams use, how to run a first fuzz test, and where fuzzing fits next to other application security testing.
What Fuzzing Does in a Security Program
Most security controls are reactive. A firewall or intrusion detection system reacts to traffic that has already reached a system. Fuzzing is proactive: you attack your own code with hostile and malformed input before anyone else does, then fix what breaks.
Know what matters before your first meeting.
Weekday mornings. Five minutes. What changed in security, why it matters.
By subscribing you agree to our Privacy Policy.
Free. Weekday mornings. 5 minutes or less.
Fuzzers are usually described by how much they know about the target:
- Black-box fuzzing sends input with no view of the code and judges only by crashes or responses. It is quick to start and works on closed-source programs, but it can miss paths that need specific input to reach.
- White-box fuzzing uses the program’s logic and structure to steer inputs toward code that has not run yet. It costs more time and compute, but it can reach deeper code.
- Grey-box (coverage-guided) fuzzing sits in between. It adds light instrumentation so the fuzzer can see which code each input reached. Most modern tools, including AFL++ and libFuzzer, work this way.
Not every crash is a security vulnerability. Some are harmless robustness bugs, and a timeout can come from a slow test setup rather than a flaw, so findings still need triage.
Where Fuzz Testing Came From
The term comes from Professor Barton Miller’s Advanced Operating Systems class at the University of Wisconsin-Madison. The fuzz project was assigned in fall 1988, and the results were published in December 1990 in Communications of the ACM as “An Empirical Study of the Reliability of UNIX Utilities.” The method was simple: pipe random characters into command-line utilities and record which ones crashed or hung. The same group repeated the work in 1995, 2000 (Windows NT), 2006 (Mac OS X) and 2020 (UW-Madison fuzz project page).
How a Fuzzer Works
- Pick a target. A function or program that takes untrusted input, such as a file parser, network protocol handler, image decoder or API endpoint.
- Give it seeds. A small set of valid sample inputs, called the seed corpus.
- Generate or mutate inputs. The fuzzer flips bits, truncates, repeats and splices inputs, or builds new ones from a grammar.
- Watch for failures. Crashes, timeouts and sanitizer reports, for example AddressSanitizer catching an out-of-bounds read.
- Keep what is interesting. Coverage-guided fuzzers save any input that reaches new code, so the corpus grows into deeper paths over time.
- Minimize and triage. The failing input is shrunk to the smallest case that still fails, then saved as a regression test. Teams deduplicate crashes and judge which ones are exploitable.
Types of Fuzz Testing
| Type | How it builds inputs | Good for |
|---|---|---|
| Mutation-based | Changes existing valid samples (bit flips, byte insertions, splicing) | File formats and parsers where good samples exist |
| Generation-based (grammar or model-based) | Builds inputs from a specification, grammar or protocol model | Highly structured input such as compilers, SQL and protocols |
| Coverage-guided (grey-box) | Mutates inputs and keeps those that reach new code, using instrumentation | Most modern library and application fuzzing (AFL++, libFuzzer, Go fuzzing) |
| Black-box | Sends input with no view of the code, judging only by crashes or responses | Closed-source binaries, devices and remote services |
| Protocol or network fuzzing | Sends malformed packets or message sequences to a running service | Network daemons, IoT and ICS protocols |
| API or web fuzzing | Sends malformed parameters, headers and request sequences | REST and GraphQL APIs and web apps |
Coverage guidance is the reason modern fuzzing is so effective. Read more in our glossary entry on coverage-guided fuzzing.
Common Fuzz Testing Tools
- AFL++: the community-maintained successor to American Fuzzy Lop, a coverage-guided fuzzer for C and C++ binaries.
- libFuzzer: LLVM’s in-process, coverage-guided fuzzing engine, usually paired with Clang sanitizers.
- Honggfuzz and Centipede: other fuzzing engines supported by OSS-Fuzz.
- Boofuzz: a fork of the Sulley framework, often used for network protocol fuzzing.
- Go native fuzzing: built into the standard Go toolchain since Go 1.18. Run it with
go test -fuzz=FuzzName(Go docs). - OSS-Fuzz and ClusterFuzzLite: Google’s free continuous fuzzing service for open-source projects, and a lighter option for running fuzzers in your own CI.
How to Run Your First Fuzz Test (Go Example)
Go is the easiest place to start because nothing extra needs installing. In a _test.go file, write a function named FuzzXxx that takes *testing.F, add a few seed values with f.Add(...), and call f.Fuzz with your target. Then run:
go test -fuzz=FuzzParse -fuzztime=60s
If it finds a failing input, Go writes it to testdata/fuzz/FuzzParse/, and a plain go test replays it from then on as a regression test. Keep fuzz targets fast and deterministic, and run them on AMD64 or ARM64 so coverage instrumentation works.
Benefits and Limits of Fuzzing
Benefits
- Finds what humans miss. Fuzzers try edge cases no one writes tests for, which is why they excel at memory-safety and parser bugs.
- Reproducible findings. A crash comes with the input that caused it, so debugging and confirming a bug is easier, and false alarms are fewer than with many scanners.
- Cheap to keep running. Once a harness exists, it can run in CI on every change.
- Broad reach. It applies to software, network protocols and APIs.
Limits
- Fuzzing only finds bugs that produce an observable failure.
- It struggles with checksums and deeply structured input unless you give it a grammar.
- It needs a harness written for each target, and long runs can need real compute and storage.
- It finds bugs but does not fix them. Developers still have to patch what it reports, and triage takes time.
- It complements code review and static testing. It does not replace them.
Real-World Examples of Fuzzing
Google built ClusterFuzz, a distributed fuzzing infrastructure, and launched OSS-Fuzz in 2016. It is a free service that continuously fuzzes open-source projects and privately alerts maintainers to the bugs it finds. According to the OSS-Fuzz documentation, as of August 2023 it had helped identify and fix over 10,000 vulnerabilities and 36,000 bugs across 1,000 projects. It supports C/C++, Rust, Go, Python, Java/JVM, JavaScript and Lua.
OSS-Fuzz was created in response to Heartbleed, the 2014 OpenSSL vulnerability. Google’s documentation describes Heartbleed as a relatively simple memory buffer overflow bug that fuzzing could have detected, at a time when fuzzing was not widely used and took a lot of manual effort.
Fuzzing has also moved into mainstream languages. Go has included native fuzzing in its standard toolchain since Go 1.18, so developers can run a fuzz test with the same go test command they already use.
Know what matters before your first meeting.
Weekday mornings. Five minutes. What changed in security, why it matters.
By subscribing you agree to our Privacy Policy.
Free. Weekday mornings. 5 minutes or less.
Fuzzing FAQ
What is fuzzing in cyber security?
Fuzzing is an automated testing technique that sends a program large amounts of invalid, unexpected or random input and watches for crashes, hangs and memory errors that can point to security vulnerabilities.
Is fuzz testing the same as brute force testing?
No. Brute forcing tries every value in a space, such as every password. Fuzzing samples malformed and unexpected inputs, and modern fuzzers use code coverage to choose which inputs to explore next.
Is fuzzing black-box or white-box testing?
It can be either. Classic fuzzing is black-box. Coverage-guided fuzzers such as AFL++ and libFuzzer are grey-box because they use instrumentation from the code.
Does every crash a fuzzer finds mean a security vulnerability?
No. Some crashes are harmless robustness bugs, and timeouts can come from a slow test setup. Each finding needs triage to decide whether it is exploitable.
What languages can be fuzzed?
Any, but tooling is most mature for C and C++. Go has built-in fuzzing, and OSS-Fuzz also supports Rust, Python, Java/JVM, JavaScript and Lua.
Further Reading
To see how fuzzing compares with code scanning and runtime testing, read SAST vs DAST vs IAST vs RASP and our list of the best SAST tools.
Newer CyberExperts coverage on this topic
This article still works as background. If you want the current picture, start with the freshest related coverage below and today's brief.
CMMC After the Phase 2 Suspension: What Contractors Still Have to Do in 2026
Short answer: on July 13, 2026, the Department of War suspended the move to CMMC Phase 2, which was due on November...
Blue Team Certifications (2026): CySA+, GCIA, BTL1 and SC-200 Compared
Blue team certifications compared from the issuers' own pages: CompTIA CySA+ V4, GIAC GCIA, BTL1 from Centri (Security Blue Team) and Microsoft...
Digital Forensics Certifications (2026): GCFA, CHFI, EnCE and CCE Compared
Digital forensics certifications compared from the issuers' own pages: GIAC GCFA and GCFE, EC-Council CHFI, OpenText EnCE and ISFCE CCE, with exam...
Thursday’s brief: APT can install a swapped package, then Rails uploads, Xen hosts and old phones
The fastest way to catch up on what changed after this article was published.
Start your morning with the signal that matters.
Get the biggest cybersecurity developments, why they matter, and where to go deeper on CyberExperts.
By subscribing you agree to our Privacy Policy.
Free. Weekdays. Built for operators.