- Notifications
You must be signed in to change notification settings - Fork163
Coverage-guided, in-process fuzzing for the JVM
License
CodeIntelligenceTesting/jazzer
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Jazzer is a coverage-guided, in-process fuzzer for the JVM platform developed byCode Intelligence.It is based onlibFuzzer and brings many of its instrumentation-powered mutation features to the JVM.
Jazzer currently supports the following platforms:
- Linux x86_64 & arm64 (aarch64)
- macOS 12+ x86_64 & arm64
- Windows x86_64
Jazzer integrates seamlessly with JUnit (version 5.9.0 or newer), allowing you to write fuzz tests alongside your regular unit tests.The recommended way to get started is by adding thejazzer-junit dependency to your project.This package is available onMaven Central and is signed withthis key.
You can use Jazzer with popular build tools:
Add the following to yourpom.xml:
<dependency> <groupId>com.code-intelligence</groupId> <artifactId>jazzer-junit</artifactId> <version>LATEST VERSION</version></dependency>
A complete example project using Maven is available inexamples/junit.
Include Jazzer in yourbuild.gradle:
implementationgroup:'com.code-intelligence',name:'jazzer-junit',version:'<LATEST VERSION>'
Jazzer is supported viarules_fuzzing, the official Bazel rules for fuzzing.For setup instructions, seethe README.
It is also possible to use Jazzer+JUnit5 integration directly in Bazel.An example project can be foundhere.TheBUILD file showcases how to set up corpus directories for fuzzing and regression and how to pass arguments to Jazzer and libFuzzer.
To write a fuzz test, add a method to your test class and annotate it with@FuzzTest.Jazzer will automatically generate and mutate inputs for your method parameters.You can use primitives, strings, arrays, and many standard library classes.See themutation framework documentation for details.To run a fuzz test infuzzing mode, set environment variableJAZZER_FUZZ to a truthy value:
JAZZER_FUZZ=1 mvntest org.example.ParserTestsHere is an example that demonstrates fuzzing security-relevant logic:
packageorg.example;importcom.code_intelligence.jazzer.junit.FuzzTest;importcom.code_intelligence.jazzer.mutation.annotation.NotNull;importcom.code_intelligence.jazzer.mutation.annotation.InRange;importcom.code_intelligence.jazzer.mutation.annotation.WithUtf8Length;importorg.junit.jupiter.api.Test;importstaticorg.junit.jupiter.api.Assertions.*;classParserTests {@TestvoidunitTest() {assertEquals("foobar",SomeScheme.decode(SomeScheme.encode("foobar"))); }@FuzzTestvoidfuzzTest_decode(@NotNullStringinput) {assertEquals(input,SomeScheme.decode(SomeScheme.encode(input))); }@FuzzTestvoidfuzzTest_decodeWithN(@NotNull@WithUtf8Length(min=10,max=200)Stringinput,@InRange(min=-10,max=10)intn) {assertEquals(input,SomeScheme.decode(SomeScheme.encode(input)));assertTrue(n >= -10 &&n <=10); }}
A complete Maven example project can be found inexamples/junit.
Jazzer can be run in two ways: using the JUnit integration or by using Jazzer standalone.
To run fuzz tests, use your build system as you would for regular tests.Methods annotated with@FuzzTest can be executed in two modes: regression mode and fuzzing mode.
In regression mode, Jazzer runs each fuzz test with crashing inputs found in its correspondinginputs directory.This mode behaves like a traditional unit test: it verifies that previously discovered issues remain fixed and helps debug the fuzz test with specific inputs.By default, Jazzer operates in regression mode unless fuzzing mode is explicitly enabled.
If you want that Jazzer also uses the inputs from thegenerated corpus directory, set the environment variableJAZZER_COVERAGE=1.
This mode helps uncover new bugs and improve test coverage.Enable fuzzing mode by setting the environment variableJAZZER_FUZZ=1 before running your tests.Jazzer will execute a single fuzz test, automatically generating and mutating inputs to maximize code coverage and find bugs.If Jazzer discovers an input that generates new coverage, it is stored in thegenerated corpus directory of the fuzz test.If Jazzer discovers an input that causes a fuzz test to fail (such as an uncaught exception or a triggered sanitizer), it stores the crashing input in theinputs directory.
There are two ways to use Jazzer standalone: by calling the Jazzer main class directly or by using thejazzer binary.
To call Jazzer directly you need to pass it the project classpath, the path to thejazzer.jar andjazzer-junit.jaralong with the Jazzer main classcom.code_intelligence.jazzer.Jazzer and target class that contains the Fuzz Test.
java -cp<classpath>;<path/to/jazzer.jar>;<path/to/jazzer-junit.jar> com.code_intelligence.jazzer.Jazzer --target_class=<fuzz-test-class> [args...]
Optionally you can add other Jazzer arguments with double dash command-line flags.Because Jazzer is based on libFuzzer, all available libFuzzer arguments can be added with single dash command-line flags.Please refer tolibFuzzer for documentation.
Jazzer is available as a standalone binary from the GitHub release archives that starts its own JVM configured for fuzzing:
- Download and extract the latest release from theGitHub releases page.
- Add a new class to your project with a
public static void fuzzerTestOneInput(String par1, int par2, int[] par3, ...)method, with the parameters you want to use in the fuzz test. - Compile your fuzz test with
jazzer_standalone.jaron the classpath. - Run the
jazzerbinary (jazzer.exeon Windows), specifying the classpath and fuzz test class:
./jazzer --cp=<classpath> --target_class=<fuzztest class>
If you see an error saying thatlibjvm.so has not been found, make sure thatJAVA_HOME points to a JDK.
Jazzer uses two main directories to store inputs: thegenerated corpus directory and theinputs directory.
Important
If you are using Git and want to add the inputs and corpus directories to the repository, mark them asbinary in your.gitattributes file:
src/test/resources/**binary.cifuzz-corpus/**binary
Thegenerated corpus directory is where Jazzer saves inputs that generate new coverage during fuzzing.It is located in.cifuzz-corpus/<package>.<FuzzTestClass>/<fuzzTestMethod>, where<package>,<FuzzTestClass>, and<fuzzTestMethod> correspond to the package name, class name, and method name of the fuzz test, respectively.For example, if the fuzz test is in the classsrc/test/java/com/example/ValidFuzzTests.java, methodbyteFuzz, the corpus directory is located in.cifuzz-corpus/com.example.ValidFuzzTests/byteFuzz.
Any input that triggers a crash during fuzzing is saved to theinputs directory.This directory is derived from the package and class name of the fuzz test.For example, if the fuzz test is in the classsrc/test/java/com/example/ValidFuzzTests.java, methodbyteFuzz, theinputs directory is located insrc/test/resources/com/example/ValidFuzzTestsInputs/byteFuzz.If this directory does not exist, Jazzer will save crash inputs in the directory from which the tests are executed.
You can provide initial seed inputs for a@FuzzTest using standard JUnit parameter sources such as@MethodSource,@CsvSource,@ValueSource, or custom@ArgumentsSource. Inregression mode, Jazzer executes thefuzz test once for each provided argument set, similar to a JUnit@ParameterizedTest.Infuzzing mode, the seed inputs are additionally used for further mutations.
An example showcasing JUnit’s@MethodSource for a@FuzzTest can be found inJavaSeedFuzzTest.java.
Note that classes without corresponding getter functions (i.e. that are mutated by theCachedConstructorMutatorFactory)can not be serialized when used in a@MethodSource method. Test cases including such objects will be ignored with awarning during Jazzer startup.
Sanitizers (also calledbug detectors) are built-in checks that help Jazzer find security issues in your application while fuzzing.They automatically monitor the program under test for risky behaviors, such as unsafe file access or network requests, and report them back with detailed information.This way, you don’t just learn that an input caused a crash, but you also get insight into what kind of vulnerability it triggered.
If you've worked with C or C++ before, you may know sanitizers likeAddressSanitizer orUndefinedBehaviorSanitizer.Jazzer sanitizers serve a similar purpose, but they are designed specifically for Java and JVM applications.Instead of low-level memory errors, they focus on common security issues in Java software, such asServer-Side Request Forgery (SSRF),File Path Traversal,Os Command Injection, etc.
Sanitizers not only detect dangerous conditions but also make fuzzing smarter.By providing feedback to the fuzzer about what they detect, they can guide input generation towards the kinds of values most likely to trigger vulnerabilities.This makes it possible to find complex bugs more quickly and with less manual effort.
You can browse all available sanitizers in theJazzer codebase.Each sanitizer can be disabled usingdisabled_hooks.
Some sanitizers can also be configured at runtime using the BugDetectorsAPI to adjust how they detect vulnerabilities.Currently, this applies to Server-Side Request Forgery and File Path Traversal sanitizers.For details, check out theAPI documentation.
Code Intelligence and Google have teamed up to bring support for Java, Kotlin, and other JVM-based languages toOSS-Fuzz, Google's project for large-scale fuzzing of open-source software.Readthe OSS-Fuzz guide to learn how to set up a Java project.
A list of security issues and bugs found by Jazzer is maintainedhere.If you found something interesting and the information is public, please send a PR to add it to the list.
- Arguments and configuration options
- Mutation framework
- Advanced techniques
- Building Jazzer from source
- JUnit integration implementation details
- Autofuzz (DEPRECATED)
The following developers have contributed to Jazzer before its public release:
Sergej Dechand,Christian Hartlage,Fabian Meumertzheim,Sebastian Pöplau,Mohammed Qasem,Simon Resch,Henrik Schnor,Khaled Yakdan
The LLVM-style edge coverage instrumentation for JVM bytecode used by Jazzer relies onJaCoCo.Previously, Jazzer used AFL-style coverage instrumentation as pioneered bykelinci.
About
Coverage-guided, in-process fuzzing for the JVM
Topics
Resources
License
Contributing
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Uh oh!
There was an error while loading.Please reload this page.

