© 2017 Synopsys, Inc. | www.synopsys.com | a j b r
3
Summary
Fuzzing is well established as an excellent technique for locating vulnerabilities in software. The basic premise
is to deliver intentionally malformed input to target software and detect failure. A complete fuzzer has three
components. A poet creates the malformed inputs or test cases. A courier delivers test cases to the target
software. Finally, an oracle detects if a failure has occurred in the target. Fuzzing is a crucial tool in software
vulnerability management, both for organizations that build software as well as organizations that use software.
1. Fuzzing in the context of software
Fuzz testing, or fuzzing, is a type of software testing in which deliberately malformed or unexpected inputs are
delivered to target software to see if failure occurs.
In this paper, we use software to mean anything that is compiled from source code into executable code that
runs on some sort of processor, including operating systems, desktop applications, server applications, mobile
applications, embedded system rmware, systems on a chip, and more.
When a piece of software fails accidentally due to unexpected or malformed input, it is a robustness problem.
In addition, a diverse cast of miscreants actively seeks to make software fail by delivering unexpected or
malformed inputs. When software fails due to deliberate attack, it is a security problem.
A software failure that causes harm or death to humans is a safety problem.
Robustness, security, and safety are three faces of the same hobgoblin, software bugs. A bug is a mistake made
by a developer; under the right conditions, the bug is triggered and the software does something it was not
supposed to do. Improving robustness, security, and safety is a matter of nding and xing bugs.
1.1. Positive and negative testing
Historically, software testing has focused on functionality. Does the software work the way it’s supposed to
work? In functional testing, a type of positive testing, test developers create code and frameworks that deliver
valid inputs to the target software and check for the correct output. For example, if we press the big red button
(deliver an input), does the software turn on the city’s power grid (correct output)?
In a traditional software development methodology, the software design is a list of requirements for the target
software. The test development team has a fairly straightforward task of translating the design requirements into
test cases to verify that the software is performing as described in the specication.
Functional testing is certainly important—the target software must behave as expected when presented with
valid inputs. However, software that is only subjected to positive testing will fail easily when released into a
chaotic and hostile world.
The real world is a mess. It is full of unexpected conditions and badly formed inputs. Software must be able to
deal with other software and people who will supply poorly formed inputs, perform actions in unexpected order,
and generally misuse the software. Negative testing is the process of sending incorrect or unexpected inputs to
software and checking for failure.
Be aware that different negative test tools will produce different results for the same test target. Each tool works
differently and will test different kinds of badly formed inputs on the target software.