Fuzzing Java Applications
JVM applications need to be particularly reliable and secure. In this context, automated fuzzing is currently the most effective approach to find security vulnerabilities and system defects.
What Is Java Fuzzing?
Fuzzing is an automated testing technique that can be used to detect bugs and vulnerabilities in Java applications. During fuzz testing, random inputs are fed to the software under test until a crash happens, or the inputs reach a new program state. Afterward, the input that resulted in a crash can be analyzed to fix the discovered bug. If the given inputs did not produce a crash, they are mutated to produce further inputs, that dig deeper into the system under test. Unlike static analysis, fuzzing produces almost no false positives.
4 Reasons Why You Should Fuzz Java Applications
Java is one of the most used programming languages in the industry. It is employed for a wide spectrum of applications ranging from GUIs and databases to servers, web and mobile applications, and IoT software. Due to their complexity and interconnectivity, these applications need to be tested extensively. In this context, automated security testing for Java is becoming more and more popular among developers, as it helps to uncover critical bugs, like SQL-Injections, or Remote Code Executions.
1. Java Is Not Inherently Secure
Due to their runtime error prevention mechanisms, memory-safe languages, such as Java or Go, are mostly immune to memory corruption. In some cases, this has led to the misconception that memory-safe languages are secure by nature. Nonetheless, memory-safe languages have to be tested thoroughly, since there are a variety of vulnerabilities that they are susceptible to. Common security vulnerabilities in memory-safe languages are Cross-Site-Scripting, Denial of Service, Out of Memory Errors, and many more, including devastating OWASP Top 10 bugs.
2. CI/CD Integration
Modern fuzzing platforms such as CI Fuzz can be configured to conduct automated security tests at each pull request. This allows developers to ensure the security of their code without the presence of security experts. By enabling development teams to fix bugs immediately after they were made, continuous fuzzing speeds up software development noticeably. Automated bug finding also has a cultural effect, as it strengthens the awareness of software security within the team.
3. Java Fuzzing Is Available Open Source
Since the release of Jazzer in early 2021, the open-source community has access to a powerful fuzzing tool for JVM-based languages. Compared to other JVM fuzzing tools, Jazzer offers significantly more executions per second, can find far more bug classes, and provides support for system-level testing, REST web apps, and gRPC web apps. Jazzer can also be used within Google's open-source fuzzing framework OSS-Fuzz.
4. Getting Started With Java Fuzzing Is Easy
For a long time, fuzzing was a technology with high barriers to entry, as it required expert knowledge to write test harnesses. Nowadays fuzzing can be fully automated. Thanks to autofuzz, writing test harnesses manually is no longer required, which enables every developer to run a Java fuzz test within a couple of clicks. Autofuzz is currently only available in CI Fuzz for enterprise use, and in Jazzer for open-source use.
“Code Intelligence's new Java fuzzer enabled us to quickly discover bug
and vulnerabilities in Java applications."
Abhishek Arya
Principal Software Engineer, Google
Main Benefits of Applying Fuzz Testing for Java Applications
Many security testing specialists consider fuzz testing a best practice for Java security testing. During a Java fuzz test, the fuzz target and its dependencies are instrumented with so-called Java agents. These Java agents ensure that information about code coverage can be reported back to the fuzzer. The fuzzer then uses this information to mutate test inputs in order to reach further parts of the software under test. Through repetition of this process, the fuzzer then improves test inputs rapidly, until they become highly accurate at detecting even highly complex bugs.
Common Java Vulnerabilities That Can Be Found With Java Fuzzing
Fuzz testing is also an effective approach for finding security vulnerabilities in memory-safe languages. With common Java Fuzzers, like Jazzer, it's possible to uncover all kinds of bugs in Java Applications, e.g.:
Data Validation Errors
- Injections (e.g. SQL Injections)
- Exposure of Sensitive Information to an Unauthorized Actor
- XML External Entities (XXE)
- Sensitive Data Exposure
- Generation of Error Message Containing Sensitive Information
- Cross-Site Scripting (XSS)
Logic Issues
- Logic issue: bypass security features
Audit/Logging Errors
- Logging of Excessive Data
- Insufficient Logging
- Insufficient Logging & Monitoring
- Broken Authentication
- Broken Access Control
Cookie Issues
- Sensitive Cookie with Improper SameSite Attribute
- Sensitive Cookie Without 'HttpOnly' Flag
- Sensitive Cookie in HTTPS Session Without 'Secure' Attribute
Uncaught Exceptions
- Runtime Exceptions
- NullPointerExceptions
- ArrayIndexOutOfBounds Exceptions
- BufferOverflow Exceptions
- NumberFormatExceptions
- ParseException (when reading user data).
Other Issues
- Denial of Service (DoS)
- Infinite Loop
- Security Misconfiguration
- Insecure Deserialization
- Using Components with Known Vulnerabilities
Fuzz Testing for Functional Bugs
Fuzzing can also be used to uncover functional bugs, which is a valuable addition to classical unit testing. To uncover functional bugs with fuzzing, developers must define invariants, i.e. properties that must be maintained under all circumstances. For example, compressing data, uncompressing the output, and then compressing it again should always result in the same data. With fuzzing, developers can analyze the program state by creating inputs that maximize code coverage and flag those that cause violations of the invariants. This approach is highly effective at finding corner cases that are often missed with manual approaches.
Fuzz Your Own Java Applications
Check out CI Fuzz, our open-source fuzzing tool for Java projects in Maven and Gradle. CI Fuzz comes with a JUnit integration and only requires a few simple commands to get your fuzzer up and running.
Use Case: Fuzzing a Java Library With Jazzer
Code Intelligence open-source security team was able to find more than 19 Bugs and a CVE (CVE-2021-37714) in the popular Java library jsoup. They used the open-source testing tool Jazzer, which is a coverage-guided fuzzing engine for Java and other JVM-based languages. Jazzer enabled them to increase their test coverage of jsoup and to uncover unlikely edge cases, that would have made the application vulnerable to attackers.
jsoup is used to extract and manipulate data from URL or HTML files using DOM, CSS, and jQuery-like methods. It can handle old and bad HTML, but it is also equipped for HTML5. Moreover, jsoup has powerful support for manipulation and easy addition or removal of HTML, and is able to clean HTML, both to protect against XSS attacks and in the sense that it improves structure and formatting.
By fuzzing jsoup, our security researchers found, that jsoup was vulnerable to Denial of Service attacks. If the parser is run on user-supplied input, an attacker could have supplied content that causes the parser to get stuck (loop indefinitely until canceled), to complete more slowly than usual, or to throw an unexpected exception. Click here to read the full jsoup bug report.
== Java Exception: com.code_intelligence.jazzer.api.FuzzerSecurityIssueLow: Stack overflow (truncated to likely cause)
at org.jsoup.parser.HtmlTreeBuilder.process(HtmlTreeBuilder.Java:149)
at org.jsoup.parser.HtmlTreeBuilderState$14.process(HtmlTreeBuilderState.java:1222)
Caused by: java.lang.StackOverflowError
at java.base/java.util.Arrays.binarySearch0(Arrays.java:2233)
at java.base/java.util.Arrays.binarySearch(Arrays.java:2173)
at org.jsoup.internal.StringUtil.inSorted(StringUtil.java:243)
at org.jsoup.parser.HtmlTreeBuilder.inSpecificScope(HtmlTreeBuilder.java:501)
at org.jsoup.parser.HtmlTreeBuilder.inSpecificScope(HtmlTreeBuilder.java:490)
at org.jsoup.parser.HtmlTreeBuilder.inTableScope(HtmlTreeBuilder.java:535)
at org.jsoup.parser.HtmlTreeBuilderState$14.process(HtmlTreeBuilderState.java:1207)
at org.jsoup.parser.HtmlTreeBuilder.process(HtmlTreeBuilder.java:149)
at org.jsoup.parser.TreeBuilder.processEndTag(TreeBuilder.java:108)
at org.jsoup.parser.HtmlTreeBuilderState$14.process(HtmlTreeBuilderState.java:1221)
at org.jsoup.parser.HtmlTreeBuilder.process(HtmlTreeBuilder.java:149)
Example Stack Overflow (see Gist)
Fuzzing Java libraries is a very common example, of how fuzzing can help developers to secure their Java applications against unexpected edge cases and unknown unknowns. Especially testing methods and Java libraries becomes very easy to secure with Jazzer, and with new features, like the autofuzz-mode, every developer is now able to perform security tests, on their applications.
Java Fuzzing Tutorial
If you want to learn more about this specific Java use case, Patrick Ventuzelo from Fuzzing Labs, has created a YouTube tutorial that explains how to secure any Java library in less than 3 minutes.