What Is Fuzzing in Cybersecurity?

By Mark Hill   Published: 11/04/23   Updated: 11/02/26   7 min read

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.

Fuzzers are usually described by how much they know about the target:

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

  1. Pick a target. A function or program that takes untrusted input, such as a file parser, network protocol handler, image decoder or API endpoint.
  2. Give it seeds. A small set of valid sample inputs, called 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. Teams deduplicate crashes and judge which ones are exploitable.

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 and 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 and remote services
Protocol or network fuzzingSends malformed packets or message sequences to a running serviceNetwork daemons, IoT and ICS protocols
API or web fuzzingSends malformed parameters, headers and request sequencesREST 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

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

Limits

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.

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.

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

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.

Read Today's Brief