Skip to content

Commit f729c1e

Browse files
1 parent 833696d commit f729c1e

1 file changed

Lines changed: 53 additions & 0 deletions

File tree

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
{
2+
"schema_version": "1.4.0",
3+
"id": "GHSA-2m67-wjpj-xhg9",
4+
"modified": "2026-04-04T04:17:07Z",
5+
"published": "2026-04-04T04:17:07Z",
6+
"aliases": [],
7+
"summary": "Jackson Core: Document length constraint bypass in blocking, async, and DataInput parsers",
8+
"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.",
9+
"severity": [
10+
{
11+
"type": "CVSS_V3",
12+
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
13+
}
14+
],
15+
"affected": [
16+
{
17+
"package": {
18+
"ecosystem": "Maven",
19+
"name": "tools.jackson.core:jackson-core"
20+
},
21+
"ranges": [
22+
{
23+
"type": "ECOSYSTEM",
24+
"events": [
25+
{
26+
"introduced": "3.0.0"
27+
},
28+
{
29+
"last_affected": "3.1.0"
30+
}
31+
]
32+
}
33+
]
34+
}
35+
],
36+
"references": [
37+
{
38+
"type": "WEB",
39+
"url": "https://github.com/FasterXML/jackson-core/security/advisories/GHSA-2m67-wjpj-xhg9"
40+
},
41+
{
42+
"type": "PACKAGE",
43+
"url": "https://github.com/FasterXML/jackson-core"
44+
}
45+
],
46+
"database_specific": {
47+
"cwe_ids": [],
48+
"severity": "HIGH",
49+
"github_reviewed": true,
50+
"github_reviewed_at": "2026-04-04T04:17:07Z",
51+
"nvd_published_at": null
52+
}
53+
}

0 commit comments

Comments
 (0)