Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
Maven

GHSA-2m67-wjpj-xhg9

HIGH

Jackson Core: Document length constraint bypass in blocking, async, and DataInput parsers

Published
Apr 4, 2026
Updated
Apr 9, 2026
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed

Blast Radius

1 pkg affected
tools.jackson.core:jackson-core

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects Maven packages — download data is not available via public APIs for these ecosystems.

Description

Summary

Jackson Core 3.x does not consistently enforce StreamReadConstraints.maxDocumentLength. Oversized JSON documents can be accepted without a StreamConstraintsException in multiple parser entry points, which allows configured size limits to be bypassed and weakens denial-of-service protections.

Details

Three code paths where maxDocumentLength is not fully enforced:

1. Blocking parsers skip validation of the final in-memory buffer

Blocking parsers validate only previously processed buffers, not the final in-memory buffer:

  • ReaderBasedJsonParser.java:255
  • UTF8StreamJsonParser.java:208

Relevant code:

_currInputProcessed += bufSize;
_streamReadConstraints.validateDocumentLength(_currInputProcessed);

This means the check occurs only when a completed buffer is rolled over. If an oversized document is fully contained in the final buffer, parsing can complete without any document-length exception.

2. Async parsers skip validation of the final chunk on end-of-input

Async parsers validate previously processed chunks, but do not validate the final chunk on end-of-input:

  • NonBlockingByteArrayJsonParser.java:49
  • NonBlockingByteBufferJsonParser.java:57
  • NonBlockingUtf8JsonParserBase.java:75

Relevant code:

_currInputProcessed += _origBufferLen;
_streamReadConstraints.validateDocumentLength(_currInputProcessed);

public void endOfInput() {
    _endOfInput = true;
}

endOfInput() marks EOF but does not perform a final validateDocumentLength(...) call, so an oversized last chunk is accepted.

3. DataInput parser path does not enforce maxDocumentLength at all

  • JsonFactory.java:457

Relevant construction path:

int firstByte = ByteSourceJsonBootstrapper.skipUTF8BOM(input);
return new UTF8DataInputJsonParser(readCtxt, ioCtxt,
        readCtxt.getStreamReadFeatures(_streamReadFeatures),
        readCtxt.getFormatReadFeatures(_formatReadFeatures),
        input, can, firstByte);

UTF8DataInputJsonParser does not call StreamReadConstraints.validateDocumentLength(...), so maxDocumentLength is effectively disabled for createParser(..., DataInput) users.

Note: This issue appears distinct from the recently published nesting-depth and number-length constraint advisories because it affects document-length enforcement.

PoC

Async path reproducer

import java.nio.charset.StandardCharsets;
import tools.jackson.core.JsonParser;
import tools.jackson.core.ObjectReadContext;
import tools.jackson.core.StreamReadConstraints;
import tools.jackson.core.async.ByteArrayFeeder;
import tools.jackson.core.json.JsonFactory;

public class Poc {
    public static void main(String[] args) throws Exception {
        JsonFactory factory = JsonFactory.builder()
                .streamReadConstraints(StreamReadConstraints.builder()
                        .maxDocumentLength(10L)
                        .build())
                .build();

        byte[] doc = "{\"a\":1,\"b\":2}".getBytes(StandardCharsets.UTF_8);

        try (JsonParser p = factory.createNonBlockingByteArrayParser(ObjectReadContext.empty())) {
            ByteArrayFeeder feeder = (ByteArrayFeeder) p.nonBlockingInputFeeder();
            feeder.feedInput(doc, 0, doc.length);
            feeder.endOfInput();

            while (p.nextToken() != null) { }
        }

        System.out.println("Parsed successfully");
    }
}
  • Expected result: Parsing should fail because the configured document-length limit is 10, while the input is longer than 10 bytes.
  • Actual result: The document is accepted and parsing completes.

Blocking path reproducer

import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
import tools.jackson.core.JsonParser;
import tools.jackson.core.StreamReadConstraints;
import tools.jackson.core.json.JsonFactory;

public class Poc2 {
    public static void main(String[] args) throws Exception {
        JsonFactory factory = JsonFactory.builder()
                .streamReadConstraints(StreamReadConstraints.builder()
                        .maxDocumentLength(10L)
                        .build())
                .build();

        byte[] doc = "{\"a\":1,\"b\":2}".getBytes(StandardCharsets.UTF_8);

        try (JsonParser p = factory.createParser(new ByteArrayInputStream(doc))) {
            while (p.nextToken() != null) { }
        }

        System.out.println("Parsed successfully");
    }
}

Impact

Applications that rely on maxDocumentLength as a safety control for untrusted JSON can accept oversized inputs without error. In network-facing services this weakens an explicit denial-of-service protection and can increase CPU and memory consumption by allowing larger-than-configured request bodies to be processed.

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
Maventools.jackson.core:jackson-core3.0.0&&< 3.1.13.1.1

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for tools.jackson.core:jackson-core. O3's reachability analysis confirms whether the vulnerable code path is actually invoked in your application, so you act on real exposure instead of every transitive match.

  2. Fix

    Update tools.jackson.core:jackson-core to 3.1.1 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-2m67-wjpj-xhg9 is resolved across your whole dependency graph.

  3. Workarounds

    If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.

  4. How O3 protects you

    O3 pinpoints whether GHSA-2m67-wjpj-xhg9 is reachable in your code and exactly where to fix it, then blocks exploitation in production at runtime until the patched version is deployed.

Tailored to GHSA-2m67-wjpj-xhg9. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.

Frequently Asked Questions

## Summary Jackson Core 3.x does not consistently enforce `StreamReadConstraints.maxDocumentLength`. Oversized JSON documents can be accepted without a `StreamConstraintsException` in multiple parser entry points, which allows configured size limits to be bypassed and weakens denial-of-service protections. ## Details Three code paths where `maxDocumentLength` is not fully enforced: ### 1. Blocking parsers skip validation of the final in-memory buffer Blocking parsers validate only previously processed buffers, not the final in-memory buffer: - `ReaderBasedJsonParser.java:255` - `UTF8Stre
O3 Security · Impact-Aware SCA

Is GHSA-2m67-wjpj-xhg9 in your dependencies?

O3 detects GHSA-2m67-wjpj-xhg9 across Maven dependencies and uses function-level reachability to confirm whether the vulnerable code path is actually reachable — not just present. No false positives.