Everything you Need to Know about Fuzz Testing

By John King, CISSP, PMP, CISM   Published: 01/01/23   Updated: 10/21/26   5 min read

Fuzz testing (fuzzing) is an automated testing 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 page is the practical guide: the main types of fuzzing, the tools teams actually use, and how to run your first fuzz test. For the concept and where fuzzing fits in a security program, see What Is Fuzzing in Cybersecurity?

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 1990 as “An Empirical Study of the Reliability of UNIX Utilities” in Communications of the ACM. The method was simple: pipe random characters into command-line utilities and record which ones crashed or hung. The same group repeated the study in 1995, 2000 (Windows NT), 2006 (macOS) and 2020 (UW-Madison fuzz project page).

How a fuzzer works

  1. Pick a target. A function or program that takes untrusted input: a file parser, network protocol handler, image decoder or API endpoint.
  2. Give it seeds. A small set of valid sample inputs (the seed corpus).
  3. Generate or mutate inputs. The fuzzer flips bits, truncates, repeats and splices inputs, or builds new ones from a grammar.
  4. Watch for failures. Crashes, timeouts and sanitizer reports (for example AddressSanitizer catching an out-of-bounds read).
  5. Keep what is interesting. Coverage-guided fuzzers save any input that reaches new code, so the corpus grows into deeper paths over time.
  6. Minimize and triage. The failing input is shrunk to the smallest case that still fails, then saved as a regression test.

Types of fuzz testing

TypeHow it builds inputsGood for
Mutation-basedChanges 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 modelHighly structured input such as compilers, SQL, protocols
Coverage-guided (grey-box)Mutates inputs and keeps those that reach new code, using instrumentationMost modern library and application fuzzing (AFL++, libFuzzer, Go fuzzing)
Black-boxSends input with no view of the code, judging only by crashes or responsesClosed-source binaries, devices, remote services
Protocol / network fuzzingSends malformed packets or message sequences to a running serviceNetwork daemons, IoT and ICS protocols
API / web fuzzingSends malformed parameters, headers and request sequencesREST and GraphQL APIs, 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

Google launched OSS-Fuzz in 2016 in response to Heartbleed, a simple OpenSSL buffer over-read that fuzzing could have caught. 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.

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 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

To see where fuzzing sits next to other AppSec testing, read SAST, DAST, IAST and RASP explained and our list of the best SAST tools.

Fuzz testing FAQ

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.

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.

Stay Current

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.

Latest Daily Brief

Monday’s brief: ConnectWise Cloud Backup comes back, then Aruba Wi-Fi fixes, a Brotli update and Nextcloud’s KEV deadline

The fastest way to catch up on what changed after this article was published.

Read Today's Brief

John King, CISSP, PMP, CISM

John King currently works in the greater Los Angeles area as a ISSO (Information Systems Security Officer). John has a passion for learning and developing his cyber security skills through education, hands on work, and studying for IT certifications.