CVE-2026-91777

Denial of Service
Affects
jackson-databind
in
Jackson
No items found.
Versions
com.fasterxml.jackson.core:jackson-databind: >=2.5.0 <=2.18.10, >=2.19.0 <=2.21.6, >=2.22.0 <=2.22.2; tools.jackson.core:jackson-databind: >=3.0.0 <=3.1.6, >=3.2.0 <=3.2.2

Patch Available.

Exclamation circle icon
Patch Available

This Vulnerability has been fixed in the Never-Ending Support (NES) version offered by HeroDevs.

Overview

jackson-databind is the data-binding package of the FasterXML Jackson suite. It provides the ObjectMapper API that converts JSON and other supported formats to and from Java objects, together with the tree model and the standard serializers and deserializers for common JDK types, and it builds on the low-level streaming parser and generator supplied by jackson-core.

A Denial of Service (DoS) vulnerability (CVE-2026-91777) has been identified in the Collection and Map deserializers of jackson-databind, which allows attackers to force quadratic CPU work during deserialization by submitting a shallow, syntactically ordinary JSON document whose object identity references resolve in reverse order.

Per OWASP: The Denial of Service (DoS) attack is focused on making a resource (site, application, server) unavailable for the purpose it was designed. There are many ways to make a service unavailable for legitimate users by manipulating network packets, programming, logical, or resources handling vulnerabilities, among others. If a service receives a very large number of requests, it may cease to be available to legitimate users. In the same way, a service may stop if a programming vulnerability is exploited, or the way the service handles resources it uses.

This issue affects the forward-reference resolution path of the Collection and Map deserializers of Jackson.

Details

Module Info

Vulnerability Info

This High-severity vulnerability is found in the com.fasterxml.jackson.core:jackson-databind package in the Collection and Map deserializers of Jackson.

When a collection or map is deserialized into a value type annotated with @JsonIdentityInfo, and an element refers to an object id whose definition has not been read yet, the deserializer parks the element as a pending forward reference. CollectionDeserializer.CollectionReferringAccumulator keeps those pending references in an ArrayList, and every value read after an unresolved reference is buffered on that reference's own next list rather than added to the result collection:

public static class CollectionReferringAccumulator {
    private final Class<?> _elementType;
    private final Collection<Object> _result;

    /**
     * A list of {@link CollectionReferring} to maintain ordering.
     */
    private List<CollectionReferring> _accumulator = new ArrayList<CollectionReferring>();

    public void add(Object value)
    {
        if (_accumulator.isEmpty()) {
            _result.add(value);
        } else {
            CollectionReferring ref = _accumulator.get(_accumulator.size() - 1);
            ref.next.add(value);
        }
    }

    public Referring handleUnresolvedReference(UnresolvedForwardReference reference)
    {
        CollectionReferring id = new CollectionReferring(this, reference, _elementType);
        _accumulator.add(id);
        return id;
    }

    public void resolveForwardReference(Object id, Object value) throws IOException
    {
        Iterator<CollectionReferring> iterator = _accumulator.iterator();
        // Resolve ordering after resolution of an id. This mean either:
        // 1- adding to the result collection in case of the first unresolved id.
        // 2- merge the content of the resolved id with its previous unresolved id.
        Collection<Object> previous = _result;
        while (iterator.hasNext()) {
            CollectionReferring ref = iterator.next();
            if (ref.hasId(id)) {
                iterator.remove();
                previous.add(value);
                previous.addAll(ref.next);
                return;
            }
            previous = ref.next;
        }

        throw new IllegalArgumentException("Trying to resolve a forward reference with id [" + id
                + "] that wasn't previously seen as unresolved.");
    }
}

Resolution is a linear search: resolveForwardReference walks the pending list from the front, comparing the resolved id against every pending entry until it finds a match, then merges that entry's buffered next list into its predecessor with previous.addAll(ref.next). Both the search and the merge are unbounded by anything except the number of references the document contains, and neither is memoized. A document that first emits N references and then defines those same ids in reverse order makes each resolution match the last pending entry, so the scan traverses the whole remaining list every time and the buffered values are copied repeatedly. The total cost is roughly N * (N + 1) / 2 id comparisons for an input that grows only linearly. At 2,000 references a run performs 2,003,000 id comparisons, and the work grows fourfold each time the attacker doubles the document size, while the JSON itself stays flat, small and free of deep nesting or unusual syntax.

MapDeserializer carries the same design for map values in its own MapReferringAccumulator, with an identical _accumulator list and the same linear scan in its resolveForwardReference method, so identity-enabled maps are affected in exactly the same way.

Exploitation requires an application that deserializes attacker-influenced JSON into a collection or map whose value type enables object identity. No authentication, no deep nesting and no oversized payload are needed: the request is an ordinary flat array or object, and the cost is paid by the worker thread handling it, so a modest number of concurrent requests can exhaust a request-time or worker-capacity budget. Confidentiality and integrity are not affected.

This vulnerability was introduced in 2014 with jackson-databind 2.4.0.

Steps to Reproduce

1. Add jackson-databind 2.15.4 (or 2.13.5, or 2.14.3) to a test project.

2. Define a value type that enables object identity on a property, and give the id type an equals implementation that counts calls so the work is measured deterministically rather than by timing:

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public static class Node {
    public CountingId id;
    public String name;
}

3. Build a shallow JSON array that first lists N bare object ids as references, then defines those same N objects in reverse order, for example ["0","1","2", ... ,{"id":"2", ...},{"id":"1", ...},{"id":"0", ...}].

4. Deserialize it into a list of the value type:

List<Node> result = new ObjectMapper()
        .readValue(json, new TypeReference<List<Node>>() { });

5. Read the equals counter. With N of 2,000 the run reports 2,003,000 id comparisons; doubling N to 4,000 quadruples the count, confirming quadratic growth against a linearly growing input. A control document in which every reference is already resolved performs no comparisons in this path at all.

Mitigation

The affected 2.13.x, 2.14.x, and 2.15.x release lines are End-of-Life and will not receive community updates addressing this issue. Branch status is published on the project's own Jackson Releases page.

Users of the affected components should apply one of the following mitigations:

  • Upgrade jackson-databind to a currently supported release containing the fix, such as 2.18.11 or later.
  • Leverage a commercial support partner like HeroDevs for post-EOL security support.

Credits

Vulnerability Details
Severity
Level
CVSS Assessment
Low
>=0 <4
Medium
>=4 <6
High
>=6 <8
Critical
>=8 <10
High
ID
CVE-2026-91777
PROJECT Affected
jackson-databind
Versions Affected
com.fasterxml.jackson.core:jackson-databind: >=2.5.0 <=2.18.10, >=2.19.0 <=2.21.6, >=2.22.0 <=2.22.2; tools.jackson.core:jackson-databind: >=3.0.0 <=3.1.6, >=3.2.0 <=3.2.2
NES Versions Affected
Published date
September 28, 2026
≈ Fix date
September 24, 2026
Category
Denial of Service
Vex Document
Download VEXHow do I use it?
Sign up for the latest vulnerability alerts fixed in
NES for Jackson
Rss feed icon
Subscribe via RSS
or

By submitting the form I acknowledge receipt of our Privacy Policy.

Thanks for signing up for our Newsletter! We look forward to connecting with you.
Oops! Something went wrong while submitting the form.