xref: /aosp_15_r20/external/jazzer-api/README.md (revision 33edd6723662ea34453766bfdca85dbfdd5342b8)
1*33edd672SMark<div align="center">
2*33edd672SMark  <a href="https://code-intelligence.com"><img src="https://www.code-intelligence.com/hubfs/Logos/CI%20Logos/Jazzer_einfach.png" height=150px alt="Jazzer by Code Intelligence">
3*33edd672SMark</a>
4*33edd672SMark  <h1>Jazzer</h1>
5*33edd672SMark  <p>Fuzz Testing for the JVM</p>
6*33edd672SMark  <a href="https://github.com/CodeIntelligenceTesting/jazzer/releases">
7*33edd672SMark    <img src="https://img.shields.io/github/v/release/CodeIntelligenceTesting/jazzer" alt="Releases">
8*33edd672SMark  </a>
9*33edd672SMark  <a href="https://search.maven.org/search?q=g:com.code-intelligence%20a:jazzer">
10*33edd672SMark    <img src="https://img.shields.io/maven-central/v/com.code-intelligence/jazzer" alt="Maven Central">
11*33edd672SMark  </a>
12*33edd672SMark  <a href="https://github.com/CodeIntelligenceTesting/jazzer/actions/workflows/run-all-tests.yml?query=branch%3Amain">
13*33edd672SMark    <img src="https://img.shields.io/github/actions/workflow/status/CodeIntelligenceTesting/jazzer/run-all-tests.yml?branch=main&logo=github" alt="CI status">
14*33edd672SMark  </a>
15*33edd672SMark  <a href="https://github.com/CodeIntelligenceTesting/jazzer/blob/main/LICENSE">
16*33edd672SMark    <img src="https://img.shields.io/github/license/CodeIntelligenceTesting/jazzer" alt="License">
17*33edd672SMark  </a>
18*33edd672SMark  <a href="https://github.com/CodeIntelligenceTesting/jazzer/blob/main/CONTRIBUTING.md">
19*33edd672SMark    <img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" alt="PRs welcome" />
20*33edd672SMark  </a>
21*33edd672SMark
22*33edd672SMark  <br />
23*33edd672SMark
24*33edd672SMark<a href="https://www.code-intelligence.com/" target="_blank">Website</a>
25*33edd672SMark|
26*33edd672SMark<a href="https://www.code-intelligence.com/blog" target="_blank">Blog</a>
27*33edd672SMark|
28*33edd672SMark<a href="https://twitter.com/CI_Fuzz" target="_blank">Twitter</a>
29*33edd672SMark</div>
30*33edd672SMark
31*33edd672SMarkJazzer is a coverage-guided, in-process fuzzer for the JVM platform developed by [Code Intelligence](https://code-intelligence.com).
32*33edd672SMarkIt is based on [libFuzzer](https://llvm.org/docs/LibFuzzer.html) and brings many of its instrumentation-powered mutation features to the JVM.
33*33edd672SMark
34*33edd672SMarkJazzer currently supports the following platforms:
35*33edd672SMark* Linux x86_64
36*33edd672SMark* macOS 12+ x86_64 & arm64
37*33edd672SMark* Windows x86_64
38*33edd672SMark
39*33edd672SMark## Quick start
40*33edd672SMark
41*33edd672SMarkYou can use Docker to try out Jazzer's Autofuzz mode, in which it automatically generates arguments to a given Java function and reports unexpected exceptions and detected security issues:
42*33edd672SMark
43*33edd672SMark```
44*33edd672SMarkdocker run -it cifuzz/jazzer-autofuzz \
45*33edd672SMark   com.mikesamuel:json-sanitizer:1.2.0 \
46*33edd672SMark   com.google.json.JsonSanitizer::sanitize \
47*33edd672SMark   --autofuzz_ignore=java.lang.ArrayIndexOutOfBoundsException
48*33edd672SMark```
49*33edd672SMark
50*33edd672SMarkHere, the first two arguments are the Maven coordinates of the Java library and the fully qualified name of the Java function to be fuzzed in "method reference" form.
51*33edd672SMarkThe optional `--autofuzz_ignore` flag takes a list of uncaught exception classes to ignore.
52*33edd672SMark
53*33edd672SMarkAfter a few seconds, Jazzer should trigger an `AssertionError`, reproducing a bug it found in this library that has since been fixed.
54*33edd672SMark
55*33edd672SMark## Using Jazzer via...
56*33edd672SMark
57*33edd672SMark### JUnit 5
58*33edd672SMark
59*33edd672SMarkThe following steps assume that JUnit 5 is set up for your project, for example based on the official [junit5-samples](https://github.com/junit-team/junit5-samples).
60*33edd672SMark
61*33edd672SMark1. Add a dependency on `com.code-intelligence:jazzer-junit:<latest version>`.
62*33edd672SMark   All Jazzer Maven artifacts are signed with [this key](deploy/maven.pub).
63*33edd672SMark2. Add a new *fuzz test* to a new or existing test class: a method annotated with [`@FuzzTest`](https://codeintelligencetesting.github.io/jazzer-docs/jazzer-junit/com/code_intelligence/jazzer/junit/FuzzTest.html) and at least one parameter.
64*33edd672SMark   Using a single parameter of type [`FuzzedDataProvider`](https://codeintelligencetesting.github.io/jazzer-docs/jazzer-api/com/code_intelligence/jazzer/api/FuzzedDataProvider.html), which provides utility functions to produce commonly used Java values, or `byte[]` is recommended for optimal performance and reproducibility of findings.
65*33edd672SMark3. Assuming your test class is called `com.example.MyFuzzTests`, create the *inputs directory* `src/test/resources/com/example/MyFuzzTestsInputs`.
66*33edd672SMark4. Run a fuzz test with the environment variable `JAZZER_FUZZ` set to `1` to let the fuzzer rapidly try new sets of arguments.
67*33edd672SMark   If the fuzzer finds arguments that make your fuzz test fail or even trigger a security issue, it will store them in the inputs directory.
68*33edd672SMark5. Run the fuzz test without `JAZZER_FUZZ` set to execute it only on the inputs in the inputs directory.
69*33edd672SMark   This mode, which behaves just like a traditional unit test, ensures that issues previously found by the fuzzer remain fixed and can also be used to debug the fuzz test on individual inputs.
70*33edd672SMark
71*33edd672SMarkA simple property-based fuzz test could look like this (excluding imports):
72*33edd672SMark
73*33edd672SMark```java
74*33edd672SMarkclass ParserTests {
75*33edd672SMark   @Test
76*33edd672SMark   void unitTest() {
77*33edd672SMark      assertEquals("foobar", SomeScheme.decode(SomeScheme.encode("foobar")));
78*33edd672SMark   }
79*33edd672SMark
80*33edd672SMark   @FuzzTest
81*33edd672SMark   void fuzzTest(FuzzedDataProvider data) {
82*33edd672SMark      String input = data.consumeRemainingAsString();
83*33edd672SMark      assertEquals(input, SomeScheme.decode(SomeScheme.encode(input)));
84*33edd672SMark   }
85*33edd672SMark}
86*33edd672SMark```
87*33edd672SMark
88*33edd672SMarkA complete Maven example project can be found in [`examples/junit`](examples/junit).
89*33edd672SMark
90*33edd672SMark### CI Fuzz
91*33edd672SMark
92*33edd672SMarkThe open-source CLI tool [cifuzz](https://github.com/CodeIntelligenceTesting/cifuzz) makes
93*33edd672SMarkit easy to set up Maven and Gradle projects for fuzzing with Jazzer.
94*33edd672SMarkIt provides a command-line UI for fuzzing runs, deduplicates and manages findings, and
95*33edd672SMarkprovides coverage reports for fuzz tests. Moreover, you can use CI Fuzz to run your fuzz
96*33edd672SMarktests at scale in the [CI App](https://app.code-intelligence.com).
97*33edd672SMark
98*33edd672SMark### GitHub releases
99*33edd672SMark
100*33edd672SMarkYou can also use GitHub release archives to run a standalone Jazzer binary that starts its own JVM configured for fuzzing:
101*33edd672SMark
102*33edd672SMark1. Download and extract the latest release from the [GitHub releases page](https://github.com/CodeIntelligenceTesting/jazzer/releases).
103*33edd672SMark2. Add a new class to your project with a <code>public static void fuzzerTestOneInput(<a href="https://codeintelligencetesting.github.io/jazzer-docs/jazzer-api/com/code_intelligence/jazzer/api/FuzzedDataProvider.html">FuzzedDataProvider</a> data)</code> method.
104*33edd672SMark3. Compile your fuzz test with `jazzer_standalone.jar` on the classpath.
105*33edd672SMark4. Run the `jazzer` binary (`jazzer.exe` on Windows), specifying the classpath and fuzz test class:
106*33edd672SMark
107*33edd672SMark```shell
108*33edd672SMark./jazzer --cp=<classpath> --target_class=<fuzz test class>
109*33edd672SMark```
110*33edd672SMark
111*33edd672SMarkIf you see an error saying that `libjvm.so` has not been found, make sure that `JAVA_HOME` points to a JDK.
112*33edd672SMark
113*33edd672SMarkThe [`examples`](examples/src/main/java/com/example) directory includes both toy and real-world examples of fuzz tests.
114*33edd672SMark
115*33edd672SMark### Docker
116*33edd672SMark
117*33edd672SMarkThe "distroless" Docker image [cifuzz/jazzer](https://hub.docker.com/r/cifuzz/jazzer) includes a recent Jazzer release together with OpenJDK 17.
118*33edd672SMarkMount a directory containing your compiled fuzz target into the container under `/fuzzing` and use it like a GitHub release binary by running:
119*33edd672SMark
120*33edd672SMark```sh
121*33edd672SMarkdocker run -v path/containing/the/application:/fuzzing cifuzz/jazzer --cp=<classpath> --target_class=<fuzz test class>
122*33edd672SMark```
123*33edd672SMark
124*33edd672SMarkIf Jazzer produces a finding, the input that triggered it will be available in the same directory.
125*33edd672SMark
126*33edd672SMark### Bazel
127*33edd672SMark
128*33edd672SMarkSupport for Jazzer is available in [rules_fuzzing](https://github.com/bazelbuild/rules_fuzzing), the official Bazel rules for fuzzing.
129*33edd672SMarkSee [the README](https://github.com/bazelbuild/rules_fuzzing#java-fuzzing) for instructions on how to use Jazzer in a Java Bazel project.
130*33edd672SMark
131*33edd672SMark### OSS-Fuzz
132*33edd672SMark
133*33edd672SMark[Code Intelligence](https://code-intelligence.com) and Google have teamed up to bring support for Java, Kotlin, and other JVM-based languages to [OSS-Fuzz](https://github.com/google/oss-fuzz), Google's project for large-scale fuzzing of open-souce software.
134*33edd672SMarkRead [the OSS-Fuzz guide](https://google.github.io/oss-fuzz/getting-started/new-project-guide/jvm-lang/) to learn how to set up a Java project.
135*33edd672SMark
136*33edd672SMark## Further documentation
137*33edd672SMark
138*33edd672SMark* [Common options and workflows](docs/common.md)
139*33edd672SMark* [Advanced techniques](docs/advanced.md)
140*33edd672SMark
141*33edd672SMark## Findings
142*33edd672SMark
143*33edd672SMarkA list of security issues and bugs found by Jazzer is maintained [here](docs/findings.md).
144*33edd672SMarkIf you found something interesting and the information is public, please send a PR to add it to the list.
145*33edd672SMark
146*33edd672SMark## Credit
147*33edd672SMark
148*33edd672SMarkThe following developers have contributed to Jazzer before its public release:
149*33edd672SMark
150*33edd672SMark[Sergej Dechand](https://github.com/serj),
151*33edd672SMark[Christian Hartlage](https://github.com/dende),
152*33edd672SMark[Fabian Meumertzheim](https://github.com/fmeum),
153*33edd672SMark[Sebastian Pöplau](https://github.com/sebastianpoeplau),
154*33edd672SMark[Mohammed Qasem](https://github.com/mohqas),
155*33edd672SMark[Simon Resch](https://github.com/simonresch),
156*33edd672SMark[Henrik Schnor](https://github.com/henrikschnor),
157*33edd672SMark[Khaled Yakdan](https://github.com/kyakdan)
158*33edd672SMark
159*33edd672SMarkThe LLVM-style edge coverage instrumentation for JVM bytecode used by Jazzer relies on [JaCoCo](https://github.com/jacoco/jacoco).
160*33edd672SMarkPreviously, Jazzer used AFL-style coverage instrumentation as pioneered by [kelinci](https://github.com/isstac/kelinci).
161*33edd672SMark
162*33edd672SMark<p align="center">
163*33edd672SMark<a href="https://www.code-intelligence.com"><img src="https://www.code-intelligence.com/hubfs/Logos/CI%20Logos/CI_Header_GitHub_quer.jpeg" height=50px alt="Code Intelligence logo"></a>
164*33edd672SMark</p>
165*33edd672SMark
166*33edd672SMark[`FuzzedDataProvider`]: https://codeintelligencetesting.github.io/jazzer-docs/jazzer-api/com/code_intelligence/jazzer/api/FuzzedDataProvider.html
167