{"id":"GHSA-2m67-wjpj-xhg9","aliases":[],"url":"https://o3.security/vulnerability/GHSA-2m67-wjpj-xhg9","summary":"Jackson Core: Document length constraint bypass in blocking, async, and DataInput parsers","details":"## Summary\n\nJackson 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.\n\n## Details\n\nThree code paths where `maxDocumentLength` is not fully enforced:\n\n### 1. Blocking parsers skip validation of the final in-memory buffer\n\nBlocking parsers validate only previously processed buffers, not the final in-memory buffer:\n\n- `ReaderBasedJsonParser.java:255`\n- `UTF8StreamJsonParser.java:208`\n\nRelevant code:\n\n```java\n_currInputProcessed += bufSize;\n_streamReadConstraints.validateDocumentLength(_currInputProcessed);\n```\n\nThis 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.\n\n### 2. Async parsers skip validation of the final chunk on end-of-input\n\nAsync parsers validate previously processed chunks, but do not validate the final chunk on end-of-input:\n\n- `NonBlockingByteArrayJsonParser.java:49`\n- `NonBlockingByteBufferJsonParser.java:57`\n- `NonBlockingUtf8JsonParserBase.java:75`\n\nRelevant code:\n\n```java\n_currInputProcessed += _origBufferLen;\n_streamReadConstraints.validateDocumentLength(_currInputProcessed);\n\npublic void endOfInput() {\n    _endOfInput = true;\n}\n```\n\n`endOfInput()` marks EOF but does not perform a final `validateDocumentLength(...)` call, so an oversized last chunk is accepted.\n\n### 3. DataInput parser path does not enforce `maxDocumentLength` at all\n\n- `JsonFactory.java:457`\n\nRelevant construction path:\n\n```java\nint firstByte = ByteSourceJsonBootstrapper.skipUTF8BOM(input);\nreturn new UTF8DataInputJsonParser(readCtxt, ioCtxt,\n        readCtxt.getStreamReadFeatures(_streamReadFeatures),\n        readCtxt.getFormatReadFeatures(_formatReadFeatures),\n        input, can, firstByte);\n```\n\n`UTF8DataInputJsonParser` does not call `StreamReadConstraints.validateDocumentLength(...)`, so `maxDocumentLength` is effectively disabled for `createParser(..., DataInput)` users.\n\n> **Note:** This issue appears distinct from the recently published nesting-depth and number-length constraint advisories because it affects document-length enforcement.\n\n## PoC\n\n### Async path reproducer\n\n```java\nimport java.nio.charset.StandardCharsets;\nimport tools.jackson.core.JsonParser;\nimport tools.jackson.core.ObjectReadContext;\nimport tools.jackson.core.StreamReadConstraints;\nimport tools.jackson.core.async.ByteArrayFeeder;\nimport tools.jackson.core.json.JsonFactory;\n\npublic class Poc {\n    public static void main(String[] args) throws Exception {\n        JsonFactory factory = JsonFactory.builder()\n                .streamReadConstraints(StreamReadConstraints.builder()\n                        .maxDocumentLength(10L)\n                        .build())\n                .build();\n\n        byte[] doc = \"{\\\"a\\\":1,\\\"b\\\":2}\".getBytes(StandardCharsets.UTF_8);\n\n        try (JsonParser p = factory.createNonBlockingByteArrayParser(ObjectReadContext.empty())) {\n            ByteArrayFeeder feeder = (ByteArrayFeeder) p.nonBlockingInputFeeder();\n            feeder.feedInput(doc, 0, doc.length);\n            feeder.endOfInput();\n\n            while (p.nextToken() != null) { }\n        }\n\n        System.out.println(\"Parsed successfully\");\n    }\n}\n```\n\n- **Expected result:** Parsing should fail because the configured document-length limit is 10, while the input is longer than 10 bytes.\n- **Actual result:** The document is accepted and parsing completes.\n\n### Blocking path reproducer\n\n```java\nimport java.io.ByteArrayInputStream;\nimport java.nio.charset.StandardCharsets;\nimport tools.jackson.core.JsonParser;\nimport tools.jackson.core.StreamReadConstraints;\nimport tools.jackson.core.json.JsonFactory;\n\npublic class Poc2 {\n    public static void main(String[] args) throws Exception {\n        JsonFactory factory = JsonFactory.builder()\n                .streamReadConstraints(StreamReadConstraints.builder()\n                        .maxDocumentLength(10L)\n                        .build())\n                .build();\n\n        byte[] doc = \"{\\\"a\\\":1,\\\"b\\\":2}\".getBytes(StandardCharsets.UTF_8);\n\n        try (JsonParser p = factory.createParser(new ByteArrayInputStream(doc))) {\n            while (p.nextToken() != null) { }\n        }\n\n        System.out.println(\"Parsed successfully\");\n    }\n}\n```\n\n## Impact\n\nApplications 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.","published":"2026-04-04T04:17:07Z","modified":"2026-04-09T18:29:26.441905070Z","cvss":{"score":7.5,"severity":"HIGH","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"},"epss":null,"cisaKev":null,"exploitsKnown":0,"affectedPackages":[{"ecosystem":"Maven","name":"tools.jackson.core:jackson-core","fixedVersion":"3.1.1"}],"fix":{"url":"https://github.com/FasterXML/jackson-core/commit/74c9ee255d1534c179bc7d3de48941bf39a9079c","label":"FasterXML/jackson-core@74c9ee2"},"references":[{"type":"WEB","url":"https://github.com/FasterXML/jackson-core/security/advisories/GHSA-2m67-wjpj-xhg9"},{"type":"WEB","url":"https://github.com/FasterXML/jackson-core/commit/74c9ee255d1534c179bc7d3de48941bf39a9079c"},{"type":"PACKAGE","url":"https://github.com/FasterXML/jackson-core"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-04-09T18:29:26.441905070Z"}}