Published: June 2023
Affected Component: jackson-databind (up to 2.15.2)
Impact: Denial of Service (DoS), Unspecified issue via cyclic dependencies
Status: Debated (vendor disagrees it is a real “vulnerability”)
Introduction
Jackson is one of the most popular Java libraries for processing JSON data. If you’ve worked with Spring Boot or any Java REST API, you’ve probably used Jackson—usually through its jackson-databind module. It can serialize Java objects to JSON and back again.
In June 2023, a new security advisory—CVE-2023-35116—was published, suggesting that all versions of jackson-databind through 2.15.2 are possibly vulnerable to a denial-of-service attack. The gist is: if Jackson serializes an object with cyclic (circular) references, it may go into an infinite loop or stack overflow, potentially causing application crashes.
But is this an actual vulnerability exploitable by hackers? Below, we break down the details, code examples, exploitation scenario, and the official vendor response.
Cyclic Dependencies
A cyclic (or circular) dependency means objects reference each other, either directly or indirectly, forming a loop. For example, if object A refers to object B, and object B refers back to object A, Jackson might get stuck serializing back and forth forever.
CVE Summary
> _“jackson-databind through 2.15.2 allows attackers to cause a denial of service or other unspecified impact via a crafted object that uses cyclic dependencies.
> NOTE: the vendor's perspective is that this is not a valid vulnerability report, because the steps of constructing a cyclic data structure and trying to serialize it cannot be achieved by an external attacker.”_
In other words: if an attacker can get the system to serialize a circular data structure, it could crash your app (DoS).
Let’s show what happens with simple code.
import com.fasterxml.jackson.databind.ObjectMapper;
class Node {
public String name;
public Node next;
}
public class CyclicDemo {
public static void main(String[] args) throws Exception {
Node first = new Node();
first.name = "First";
Node second = new Node();
second.name = "Second";
first.next = second;
second.next = first; // creates a loop!
ObjectMapper mapper = new ObjectMapper();
// This will throw a StackOverflowError!
String json = mapper.writeValueAsString(first);
System.out.println(json);
}
}
What happens?
When mapper.writeValueAsString(first) is called, Jackson tries to serialize first, then finds second (through next), then finds first again through second.next, and so on—forever, until the stack overflows.
This is the tricky part.
- If an attacker can make your API serialize a user-controlled, cyclic data structure, they could crash your app.
Vendor’s Response
> _“…the vendor's perspective is that this is not a valid vulnerability report, because the steps of constructing a cyclic data structure and trying to serialize it cannot be achieved by an external attacker.”_
Translation: There’s no vulnerability unless you’re already letting attackers execute arbitrary Java code or otherwise build arbitrary object graphs on your system—in which case, you have far worse problems!
Source:
- GitHub issue
- CVE Record
Is it practical? Here’s the only scenario where this could apply
1. You have an endpoint that echoes user-provided JSON by parsing and serializing it without validation.
2. Attacker submits JSON designed to deserialize as a circular structure (may require special deserializers and no security restrictions).
Almost all real-life Java backends do not expose such functionality.
When the API serializes this object, it crashes with a StackOverflowError.
However, standard Jackson behavior and Java security prevent most exploit attempts. Also, Java's object references in JSON don't natively support cyclic structures. Custom deserializers might create such cycles, but again, these need to be written by application code—not by attackers.
Guard against infinite recursion:
Add Jackson annotations such as @JsonIdentityInfo or @JsonIgnore on recursive fields.
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "name")
class Node { /* ... */ }
Validate user input:
Never deserialize arbitrary data without validation.
Upgrade libraries:
Always keep Jackson and other dependencies updated.
Test with cycles:
Write tests trying to serialize cyclic structures to catch StackOverflowErrors early.
References
- GitHub issue discussing CVE-2023-35116
- Official CVE Record
- Jackson Official Annotations for Handling Cycles
Conclusion
CVE-2023-35116 isn’t a classic remote vulnerability. While it's technically possible for cyclic dependencies to crash servers running jackson-databind, a real-world attacker cannot usually exploit this unless your application already performs very unsafe actions. Jackson’s authors say this is not a “real” security issue for most apps.
Takeaway: Always sanitize what you deserialize, don’t echo complex objects blindly, and use Jackson’s features for handling recursion if your object models have cycles.
Timeline
Published on: 06/14/2023 14:15:10 UTC
Last modified on: 11/07/2023 04:15:53 UTC