Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
jackson — This repository provides a comprehensive security remediation of denial-of-service and allocation of resources without limits or throttling security vulnerabilities reported in CVE-2025-52999, GHSA-2m67-wjpj-xhg9 and sonatype-2022-6438 while maintaining full compatibility with jackson‑core 2.13.5. | Kitploit
Tools/GitHubGitHub/sassoftware/jackson
General Purpose UtilitiesStatic AnalysisVulnerability AnalysisCode AnalysisSupply Chain Security
GitHubsassoftware/jackson

jackson

View Repository
14 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →

About

This repository provides a comprehensive security remediation of denial-of-service and allocation of resources without limits or throttling security vulnerabilities reported in CVE-2025-52999, GHSA-2m67-wjpj-xhg9 and sonatype-2022-6438 while maintaining full compatibility with jackson‑core 2.13.5.

Share

Analysis and Remediation of Security Vulnerabilities in Jackson core 2.13.5

  • CVE-2025-52999
  • SNYK-JAVA-COMFASTERXMLJACKSONCORE-15365924
  • SNYK-JAVA-COMFASTERXMLJACKSONCORE-15907551 (GHSA-2m67-wjpj-xhg9)
  • SNYK-JAVA-COMFASTERXMLJACKSONCORE-7569538 (Sonatype-2022-6438)

This branch (2.13.5-CVE-2025-52999-sonatype-2022-6438-GHSA-2m67-wjpj-xhg9) contains a comprehensive security remediation of denial-of-service (DoS) and Allocation of Resources Without Limits or Throttling vulnerabilities targeting jackson-core 2.13.5. It introduces the StreamReadConstraints API — aligned with the API introduced in jackson-core 2.15.0 but extended with broader parser coverage and additional attack-vector protections — addressing a nesting-depth exhaustion attack (CVE-2025-52999), Allocation of Resources Without Limits or Throttling (SNYK-JAVA-COMFASTERXMLJACKSONCORE-15365924), a document length constraint bypass (SNYK-JAVA-COMFASTERXMLJACKSONCORE-15907551 / GHSA-2m67-wjpj-xhg9), and a numeric token length exhaustion attack (Sonatype-2022-6438) while remaining compatible with the public API surface of jackson-core version 2.13.5.

Branch History

BranchVulnerabilities Addressed
2.13.5-CVE-2025-52999-sonatype-2022-6438CVE-2025-52999, Sonatype-2022-6438, SNYK-JAVA-COMFASTERXMLJACKSONCORE-15365924
2.13.5-CVE-2025-52999-sonatype-2022-6438-GHSA-2m67-wjpj-xhg9All of the above + GHSA-2m67-wjpj-xhg9 (document length constraint bypass)

The original branch (2.13.5-CVE-2025-52999-sonatype-2022-6438) remediates three vulnerabilities and is preserved on the sasso remote. This branch extends it with the additional remediation of GHSA-2m67-wjpj-xhg9, which enforces maxDocumentLength across all parser paths.


Vulnerability Overview


Affected and Remediated Versions


Vulnerability Description

CVE-2025-52999 — Unbounded JSON Nesting Depth

NVD Entry

Official NVD Description

jackson-core contains core low-level incremental ("streaming") parser and generator abstractions used by Jackson Data Processor. In versions prior to 2.15.0, if a user parses an input file and it has deeply nested data, Jackson could end up throwing a StackOverflowError if the depth is particularly large. jackson-core 2.15.0 contains a configurable limit for how deep Jackson will traverse in an input document, defaulting to an allowable depth of 1,000. jackson-core will throw a StreamConstraintsException if the limit is reached. jackson-databind also benefits from this change because it uses jackson-core to parse JSON inputs. As a workaround, users should avoid parsing input files from untrusted sources.

Workaround: avoid parsing JSON input from untrusted sources until the remediated version is deployed.


Root cause: Prior to 2.15.0, JsonParser imposed no limit on how deeply nested a JSON document could be. Every array [ or object { token caused JsonReadContext.createChildArrayContext() / createChildObjectContext() to allocate a new context node on the heap and increment a reference chain. An attacker can craft a document with tens of thousands of nested levels, causing the Java Virtual Machine to exhaust its thread-stack or heap memory.

Vulnerable code path:

The same missing check is reached through each of the four parser implementations:

root@kitploit:~
JsonParser.nextToken()                         // common entry point
  │
  ├─ ReaderBasedJsonParser          → _parsePunctuationMark()
  ├─ UTF8StreamJsonParser           → _parsePunctuationMark()
  ├─ UTF8DataInputJsonParser        → _parsePunctuationMark()
  └─ NonBlockingJsonParserBase      → _startArrayScope() / _startObjectScope()
                    │
                    ▼
  _parsingContext.createChildArrayContext()     // '[' encountered
  _parsingContext.createChildObjectContext()    // '{' encountered
  ⚠  no depth check — context chain grows without bound

All four JsonParser implementations share this flaw. The attack is equally exploitable through any of them — whether input arrives via InputStream, Reader, DataInput, or the async non-blocking feeder API.

Attack vectors:

Key observations:

  • Array nesting — minimal overhead: only [ and ] tokens are required; no keys, values, or whitespace. A 2,002-byte payload of 1,001 bracket pairs is sufficient to exceed the default limit of 1,000.
  • Object nesting — amplified heap pressure: each { additionally allocates a JsonReadContext key slot on top of the depth-chain node, compounding memory consumption at extreme depths.
  • Alternating nesting — Web Application Firewall (WAF) evasion: pattern-matching defences that detect repeated [[[ or {{{ sequences are blind to alternating-token nesting; the parser's depth counter increments identically regardless of token type.
  • Non-blocking feeder — same payload, distinct delivery surface: all three nesting strategies are equally exploitable via NonBlockingJsonParser and the ByteArrayFeeder API. The document may be delivered in arbitrarily small chunks; NonBlockingJsonParserBase._startArrayScope() / _startObjectScope() increment the depth counter on every context-opening token regardless of how the bytes arrive, accumulating depth across multiple calls.

All three nesting strategies are reachable through any of the four JsonParser implementations. With 2.13.5, parsing succeeds silently; with this remediation, all three vectors throw StreamConstraintsException: Depth (1001) exceeds the maximum allowed nesting depth (1000).


Sonatype-2022-6438 — Unbounded Numeric Token Length

Security Details

Vulnerable Methods (as identified by Sonatype)

Each of these methods processes the raw digit buffer without first validating its length. Passing a sufficiently long numeric token triggers unbounded heap allocation and CPU exhaustion when the JVM attempts to instantiate a BigInteger or BigDecimal from the unconstrained buffer contents.


Root cause: Prior to 2.15.0, JsonParser imposed no limit on the byte length of integer, scientific notation, simple floating-point, or compound floating-point tokens. When a parser allocates its internal _textBuffer to accumulate digits, an attacker can provide a number with millions of digits, causing the buffer to grow without bound and eventually exhaust heap memory.

Vulnerable code paths:

There are two structurally distinct vulnerable paths — one shared by the three synchronous parsers, and a second independent path through the async parser.

Path A — synchronous parsers (three implementations, one shared sink):

root@kitploit:~
JsonParser.nextToken()                         // common entry point
  │
  ├─ ReaderBasedJsonParser   ─┐
  ├─ UTF8StreamJsonParser     ├─→ ParserBase.resetInt() / resetFloat()
  └─ UTF8DataInputJsonParser ─┘         │
                                        ▼
                               _textBuffer.contentsAsString()
                               ⚠  no length check — buffer grows without bound

Path B — async parser (independent code path, separately unprotected):

root@kitploit:~
NonBlockingJsonParser.nextToken()
  │
  ├─ _startPositiveNumber() / _startNegativeNumber()    // integer paths
  ├─ _finishNumberIntegralPart()
  ├─ _startFloat()                                      // floating-point paths
  ├─ _finishFloatFraction()
  └─ _finishFloatExponent()
            │
            ▼
  writes _intLength / _fractLength / _expLength directly
  ⚠  never calls ParserBase.resetInt() / resetFloat()
  ⚠  constraint validation bypassed entirely

The non-blocking (async) parser is a particularly notable attack surface: it contains its own digit-accumulation loops in _startPositiveNumber, _startNegativeNumber, _finishNumberIntegralPart, _startFloat, _finishFloatFraction, and _finishFloatExponent that set _intLength / _fractLength / _expLength directly without ever going through ParserBase.resetInt() or resetFloat(). This means the upstream PR #827 fix (which added validation only to ParserBase) left NonBlockingJsonParser completely unprotected. This was discovered during extended attack-surface analysis and remediated in this branch.

Attack vectors:

Key observations:

  • Integer — sign character is not a digit: the leading - is excluded from digit accumulation; -999… and 999… produce identical intLen values and trip the constraint at the same threshold.
  • Decimal fraction — short integer, unbounded fraction: the integer part may be a single digit (0) while the fractional part grows without limit; the decimal point itself is excluded from the count.
  • Scientific notation — compact yet catastrophic: at ~1,004 bytes this is the smallest effective payload; it forces instantiation of a BigDecimal with scale ±10^1001, demanding unbounded intermediate heap allocation despite the token's small size.
  • Compound floating-point — split-limit evasion: with fractLen = 500 and expLen = 500, neither component individually reaches the 1,000-digit threshold. The unified check validateFPLength(intLen + fractLen + expLen) is the only defence that closes this gap.
  • Non-blocking parser — independent bypass: all four token shapes above are independently exploitable through NonBlockingJsonParser via ByteArrayFeeder. Unlike the synchronous parsers, accumulates digits in private loops (, , , , ) that write / / directly, bypassing and entirely. The upstream PR #827 — which only modified — therefore left this parser fully unprotected, requiring six independent call-site patches in this remediation.

All four token shapes and the non-blocking bypass are rejected at tokenization time — before any BigDecimal or BigInteger is constructed — by validateIntegerLength and validateFPLength in ParserBase (synchronous parsers) and at six dedicated call sites in NonBlockingJsonParser (async parser). With 2.13.5, all four token shapes are accepted silently; with this remediation, every parser throws StreamConstraintsException: Number length (N) exceeds the maximum length (1000).

Note on UTF8DataInputJsonParser with large payloads: The DataInput parser has a pre-existing internal buffer limit of 65 536 bytes (jackson-core#493). Documents exceeding this size (e.g., 199,999-digit PoC payloads ≈ 200 KB) trigger an ArrayIndexOutOfBoundsException before the length constraint can fire. The numeric length protection for UTF8DataInputJsonParser is therefore verified with shorter payloads (≤ 1,001 digits) where the bug is still reproducible.


SNYK-JAVA-COMFASTERXMLJACKSONCORE-15907551 / GHSA-2m67-wjpj-xhg9 — Document Length Constraint Bypass

Security Details

Root cause: Even when StreamReadConstraints.maxDocumentLength is configured, versions prior to 2.18.7 / 2.21.2 do not enforce the document length limit in any parser path. The blocking parsers (UTF8StreamJsonParser, ReaderBasedJsonParser) never validate cumulative bytes read against the configured limit. The async parser (NonBlockingJsonParser) similarly lacks validation in feedInput(). The UTF8DataInputJsonParser has no mechanism to track total bytes consumed.

In jackson-core 2.13.5, maxDocumentLength did not exist at all, meaning there was no way to constrain document size. This remediation introduces the maxDocumentLength field in StreamReadConstraints and enforces it across all parser paths.

Vulnerable parser paths:

Attack scenario: An attacker sends a valid but oversized JSON document (e.g., a deeply nested or highly repetitive structure spanning gigabytes) to a service that has configured maxDocumentLength to prevent resource exhaustion. Without enforcement, the parser processes the entire document regardless of the configured limit, consuming unbounded memory and CPU.


Security Impact

All four vulnerabilities are remotely exploitable with no authentication required:

  • Any service that parses attacker-controlled JSON via a JsonParser (directly or through Jackson Databind, which wraps jackson-core) is at risk.
  • The attack is trivially constructible — a few hundred bytes of JSON are sufficient to trigger unbounded resource consumption.
  • No confidentiality or integrity impact; availability (DoS) is the sole impact class.

Remediation Details

Official Upgrade (Recommended)

Upgrade to jackson-core 2.15.4 or any later stable release. All 2.15.x and 2.16+ releases include the StreamReadConstraints API with safe defaults.

root@kitploit:~
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.15.4</version>
</dependency>

This Branch (Security Remediation for 2.13.5)

If upgrading to a later release is not immediately feasible, this branch applies a comprehensive fix to the 2.13.5 codebase. It introduces StreamReadConstraints and StreamConstraintsException with an API compatible with 2.15.x, hooks the constraints into all four JsonParser implementations — including the non-blocking parser, which was not covered by the upstream fix — and enforces the following default limits:

ConstraintDefault Limit
Maximum nesting depth1,000
Maximum numeric token length1,000 digits
Maximum string token length1,000,000 characters
Maximum BigDecimal scale magnitude100,000

Fix Implementation Details

New Classes

StreamReadConstraints (356 lines)

Immutable value object holding per-parser stream-read limits, constructed via a Builder:

root@kitploit:~
// Default constraints (used by all parsers unless overridden)
StreamReadConstraints defaults = StreamReadConstraints.defaults();

// Custom constraints
StreamReadConstraints custom = StreamReadConstraints.builder()
    .maxNestingDepth(500)
    .maxNumberLength(2000)
    .maxStringLength(5000000)
    .build();

Validation methods (called by parsers on each new token):

root@kitploit:~
void validateNestingDepth(int depth) throws StreamConstraintsException;
void validateIntegerLength(int length) throws StreamConstraintsException;
void validateFPLength(int length) throws StreamConstraintsException;
void validateStringLength(int length) throws StreamConstraintsException;
void validateBigIntegerScale(int scale) throws StreamConstraintsException;

Exception message format:

  • Depth: "Depth (%d) exceeds the maximum allowed nesting depth (%d)"
  • Number length: "Number length (%d) exceeds the maximum length (%d)"
  • String length: "String length (%d) exceeds the maximum length (%d)"
  • BigDecimal scale: "BigDecimal scale (%d) magnitude exceeds maximum allowed (%d)"

StreamConstraintsException (52 lines)

Extends StreamReadException (itself a JsonProcessingException). Thrown exclusively by StreamReadConstraints validation methods.


Modified Files

base/ParserBase.java

Added _streamReadConstraints field (defaults to StreamReadConstraints.defaults()).

resetInt() and resetFloat() now validate numeric token length immediately after the token has been accumulated:

root@kitploit:~
protected void resetInt(boolean negative, int intLen) throws IOException {
    _streamReadConstraints.validateIntegerLength(intLen);
    // … existing reset logic …
}

protected void resetFloat(boolean negative, int intLen, int decLen, int expLen) throws IOException {
    int totalLen = intLen + decLen + expLen;
    _streamReadConstraints.validateFPLength(totalLen);
    // … existing reset logic …
}

New helper methods _createChildArrayContext() and _createChildObjectContext() wrap context creation with a depth check:

root@kitploit:~
protected JsonReadContext _createChildArrayContext(int line, int col) throws IOException {
    _streamReadConstraints.validateNestingDepth(_parsingContext.getNestingDepth() + 1);
    return _parsingContext.createChildArrayContext(line, col);
}

Parser Implementations

All four parsers now call the new depth-checking helpers instead of accessing _parsingContext.createChild*() directly:

  • json/ReaderBasedJsonParser.java
  • json/UTF8StreamJsonParser.java
  • json/UTF8DataInputJsonParser.java
  • json/async/NonBlockingJsonParserBase.java

JsonStreamContext.java

Added getNestingDepth() that walks the parent chain to compute absolute depth:

root@kitploit:~
public int getNestingDepth() {
    int depth = 0;
    JsonStreamContext curr = this;
    while ((curr = curr.getParent()) != null) {
        depth++;
    }
    return depth;
}

json/JsonReadContext.java

createChildArrayContext() and createChildObjectContext() signatures updated to propagate throws IOException.

json/async/NonBlockingJsonParser.java (Sonatype-2022-6438 only)

This is the principal additional fix discovered beyond the upstream PR #827 scope. Six number-completion sites that bypassed ParserBase.resetInt() were individually remediated:

All sites are reachable: the fast-path methods handle the case where the full number is available in a single feedInput() call; the MINOR_* resume-state cases handle the chunked case where number digits arrive across multiple calls. Both paths must be guarded.


Test Coverage

CVE-2025-52999 — Nesting Depth Tests

Sonatype-2022-6438 — Numeric Length Tests

Parser modes key:

  • ALL_STREAMING_MODES = UTF8StreamJsonParser (stream), UTF8StreamJsonParser (throttled), ReaderBasedJsonParser
  • ALL_MODES = above three + UTF8DataInputJsonParser
  • non-blocking = NonBlockingJsonParser via ByteArrayFeeder
  • stream = UTF8StreamJsonParser (default JsonFactory.createParser)

SNYK-JAVA-COMFASTERXMLJACKSONCORE-15907551 — Document Length Tests


Full Test Suite Results

root@kitploit:~
Tests run: 957, Failures: 0, Errors: 0, Skipped: 0

All 957 tests pass on the remediated build. Breakdown of new security tests added:

Build command:

root@kitploit:~
./mvnw test

Validation Results

Regression Test Against jackson-core 2.13.5

The CVE test methods were designed to fail on the 2.13.5 codebase and pass on the remediated build.

NumberOverflowTest#testSonatype_2022_6438 against 2.13.5:

root@kitploit:~
FAIL — Sonatype-2022-6438 VULNERABILITY PRESENT: parser returned VALUE_NUMBER_INT
       for a 1001-digit integer — number length limit is not enforced

ArrayParsingTest#testCVE_2025_52999 against 2.13.5:

root@kitploit:~
FAIL — CVE-2025-52999 VULNERABILITY PRESENT: StackOverflowError after 20000 nesting
       levels — parser enforces no depth limit (2.13.5)

Both tests on the remediated build: PASS.


Proof of Concept

CVE-2025-52999 — Nesting Depth DoS

root@kitploit:~
// Build a 1001-level nested array document (just over the limit)
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1001; i++) sb.append('[');
for (int i = 0; i < 1001; i++) sb.append(']');

JsonFactory factory = new JsonFactory();
JsonParser parser = factory.createParser(sb.toString());
try {
    while (parser.nextToken() != null) { }       // ← throws on 1001st '['
    System.err.println("VULNERABLE: no exception thrown");
} catch (StreamConstraintsException e) {
    System.out.println("REMEDIATED: " + e.getMessage());
    // Depth (1001) exceeds the maximum allowed nesting depth (1000)
} finally {
    parser.close();
}

Sonatype-2022-6438 — Numeric Token Length DoS

All four token shapes trigger validateFPLength / validateIntegerLength before any BigDecimal / BigInteger conversion is attempted.

root@kitploit:~
JsonFactory factory = new JsonFactory();

// ── 1. Long integer ──────────────────────────────────────────────────────────
String longInt = "9".repeat(1001);          // 1001-digit integer
// Negative form works identically: "-" + "9".repeat(1001)

// ── 2. Long fractional part (floating-point) ─────────────────────────────────
// intLen=1, fractLen=1001, total=1002
String longFloat = "0." + "9".repeat(1001);

// ── 3. Long exponent / scientific notation ───────────────────────────────────
// intLen=1, fractLen=0, expLen=1001, total=1002  — only 1,004 bytes on the wire
String longExp = "1e" + "9".repeat(1001);

// ── 4. Combined fractional + exponent ────────────────────────────────────────
// intLen=1, fractLen=500, expLen=500, total=1001 — neither part alone is over the limit
String combined = "0." + "9".repeat(500) + "e" + "9".repeat(500);

for (String payload : new String[]{ longInt, longFloat, longExp, combined }) {
    JsonParser parser = factory.createParser("[" + payload + "]");
    try {
        parser.nextToken();                  // START_ARRAY
        parser.nextToken();                  // ← throws on the number token
        System.err.println("VULNERABLE: " + payload.substring(0, 20) + "…");
    } catch (StreamConstraintsException e) {
        System.out.println("REMEDIATED:    " + e.getMessage());
        // Number length (N) exceeds the maximum length (1000)
    } finally {
        parser.close();
    }
}

Migration Guide

Option 1: Upgrade to jackson-core 2.15.4+ (Recommended)

root@kitploit:~
<!-- Maven -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.15.4</version>
</dependency>

<!-- Or with Jackson BOM -->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.fasterxml.jackson</groupId>
            <artifactId>jackson-bom</artifactId>
            <version>2.15.4</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

With 2.15+, you can also adjust limits at runtime if your application legitimately needs deeper nesting or longer numbers:

root@kitploit:~
JsonFactory factory = JsonFactory.builder()
    .streamReadConstraints(StreamReadConstraints.builder()
        .maxNestingDepth(2000)
        .maxNumberLength(10000)
        .maxDocumentLength(50_000_000L)
        .build())
    .build();

Option 2: Apply This Security Remediation

root@kitploit:~
git clone https://github.com/sassoftware/jackson-core.git
cd jackson-core
git checkout 2.13.5-CVE-2025-52999-sonatype-2022-6438-GHSA-2m67-wjpj-xhg9
./mvnw install -DskipTests

Then update your project's dependency to use the locally installed 2.13.5-SNAPSHOT artifact, or deploy it to your internal artifact repository.


Key Changed Files Summary

Total: 16 files changed, 1,606 insertions (as reported by git diff jackson-core-2.13.5 --stat).


References

CVE-2025-52999

  • NVD entry: https://nvd.nist.gov/vuln/detail/CVE-2025-52999
  • GitHub Security Advisory: https://github.com/FasterXML/jackson-core/security/advisories/GHSA-h46c-h94j-95f3
  • CWE-121: Stack-based Buffer Overflow (per NVD / GitHub CNA)

Sonatype-2022-6438

  • Sonatype advisory: https://guide.sonatype.com/vulnerability/sonatype-2022-6438
  • CWE-770: Allocation of Resources Without Limits or Throttling

SNYK-JAVA-COMFASTERXMLJACKSONCORE-15907551 / GHSA-2m67-wjpj-xhg9

  • Snyk advisory: https://security.snyk.io/vuln/SNYK-JAVA-COMFASTERXMLJACKSONCORE-15907551
  • GitHub Security Advisory: https://github.com/FasterXML/jackson-core/security/advisories/GHSA-2m67-wjpj-xhg9
  • GitHub Issue: https://github.com/FasterXML/jackson-core/issues/1570
  • CWE-770: Allocation of Resources Without Limits or Throttling
  • Fix commits: 74c9ee25 (3.x), 7ce3622f (2.18.x)

Jackson Core

  • Release notes: https://github.com/FasterXML/jackson-core/blob/2.15/release-notes/VERSION-2.x
  • StreamReadConstraints API (2.15 javadoc): https://javadoc.io/doc/com.fasterxml.jackson.core/jackson-core/2.15.4/com/fasterxml/jackson/core/StreamReadConstraints.html

Security Considerations

Who Is at Risk

Any application that:

  1. Parses JSON from an untrusted/external source (HTTP request bodies, message queue payloads, file uploads, third-party API responses), AND
  2. Uses jackson-core 2.x prior to 2.15.0 (directly or transitively through jackson-databind)

is vulnerable to both attacks.

Defense in Depth

Even after remediation, consider:

  • Input size limits at the HTTP/transport layer (e.g., maxRequestSize in Servlet containers) to reject extremely large request bodies before the parser is invoked.
  • Request timeouts to bound the total processing time per request.
  • Custom StreamReadConstraints if your application legitimately requires larger or deeper documents — tune limits to the minimum necessary for your use case.

Compatibility

DimensionRequirement
Build JDKJava 8 (JDK 1.8) or later — this branch requires Java 8+ for build and test
Minimum runtime JREJava 8 or later
Maven3.6.3 or later (bundled wrapper ./mvnw satisfies this automatically)

Note: The original jackson-core 2.13.5 release targeted Java 6 (-source 1.6 -target 1.6). As of this security branch, Java 8 or later is required for both build and runtime. No Jackson 2.13 public API surface is changed; only JDK 6/7 runtimes lose compatibility due to Maven and JDK requirements.


Development Environment

Build and Test

root@kitploit:~
# Full build and test
./mvnw test

# Install to local Maven repository
./mvnw install -DskipTests


License

Licensed under the Apache License, Version 2.0.

root@kitploit:~
Copyright 2024–2025 The Jackson Authors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Contact

Security Vulnerability Research and Remediation Author : Jinwoo Hwang (https://JinwooHwang.com)

Download Tool
IDTypeSeverityCVSSUpstream Fix
CVE-2025-52999Denial of Service — unbounded nesting depthHigh7.5 (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)jackson-core 2.15.0
Sonatype-2022-6438 / SNYK-JAVA-COMFASTERXMLJACKSONCORE-7569538Denial of Service — unbounded numeric token lengthHigh7.5 (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)jackson-core 2.15.0
SNYK-JAVA-COMFASTERXMLJACKSONCORE-15365924Allocation of Resources Without Limits or ThrottlingHigh8.7 (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)jackson-core 2.18.6, 2.21.1 or higher.
SNYK-JAVA-COMFASTERXMLJACKSONCORE-15907551 / GHSA-2m67-wjpj-xhg9Allocation of Resources Without Limits or Throttling — document length constraint bypassHigh8.7 (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)jackson-core 2.18.7, 2.21.2 or higher.
VersionCVE-2025-52999Sonatype-2022-6438 / SNYK-JAVA-COMFASTERXMLJACKSONCORE-7569538SNYK-JAVA-COMFASTERXMLJACKSONCORE-15365924SNYK-JAVA-COMFASTERXMLJACKSONCORE-15907551
2.13.5VulnerableVulnerableVulnerableVulnerable
2.13.5-CVE-2025-52999-sonatype-2022-6438RemediatedRemediatedRemediatedVulnerable
2.13.5-CVE-2025-52999-sonatype-2022-6438-GHSA-2m67-wjpj-xhg9RemediatedRemediatedRemediatedRemediated
2.14.xVulnerableVulnerableVulnerableVulnerable
2.15.xRemediatedRemediatedVulnerableVulnerable
2.16.xRemediatedRemediatedVulnerableVulnerable
2.17.xRemediatedRemediatedVulnerableVulnerable
2.18.6+RemediatedRemediatedRemediatedVulnerable
2.18.7+RemediatedRemediatedRemediatedRemediated
2.21.1+RemediatedRemediatedRemediatedVulnerable
2.21.2+RemediatedRemediatedRemediatedRemediated
FieldValue
CVE IDCVE-2025-52999
Published2025-06-25
Last Modified2025-06-26
Source (CNA)GitHub, Inc.
CVSS v4.0 Score8.7 HIGH — CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N
CWECWE-121 — Stack-based Buffer Overflow
GitHub AdvisoryGHSA-h46c-h94j-95f3
Upstream Fix PRjackson-core#943
#StrategyExample payloadDepth incrementAffected parsers
1Array nesting[[[…]]] — 1,001 consecutive [ tokens+1 per [All four
2Object nesting{"k":{"k":{…}}} — 1,001 consecutive { tokens+1 per {All four
3Alternating nesting[{"k":[{"k":…}]}] — 1,001 mixed [/{ tokens+1 per [ or {All four
feedInput()
FieldValue
Sonatype IDsonatype-2022-6438
Descriptionjackson-core — Denial of Service (DoS)
Published2022-12-07
SourceSonatype
CVSS v3.1 Score7.5 HIGH — CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
CWECWE-770 — Allocation of Resources Without Limits or Throttling
EPSS Score0%
Upstream Fix PRsjackson-core#827, jackson-core#846
MethodNotes
com.fasterxml.jackson.core.base.ParserBase._parseSlowInt(I)VVulnerable param: index 0
com.fasterxml.jackson.core.base.ParserBase.convertNumberToBigDecimal()V
com.fasterxml.jackson.core.base.ParserMinimalBase.getValueAsDouble(D)DVulnerable param: index 0
com.fasterxml.jackson.core.util.TextBuffer.contentsAsDecimal()Returns BigDecimal
com.fasterxml.jackson.core.util.TextBuffer.contentsAsDouble(Z)D
com.fasterxml.jackson.core.util.TextBuffer.contentsAsFloat(Z)F
#Token shapeExample payloadintLenfractLenexpLenTotalConstraint
1Integer999… — 199,999 consecutive digits199,99900199,999validateIntegerLength
2Decimal fraction0.999… — 1-digit integer, 1,001-digit fraction11,00101,002validateFPLength
3Scientific notation1e999… — 1-digit significand, 1,001-digit exponent101,0011,002validateFPLength
4Compound floating-point0.999…e999… — 500-digit fraction, 500-digit exponent15005001,001validateFPLength
NonBlockingJsonParser
_startPositiveNumber
_finishNumberIntegralPart
_startFloat
_finishFloatFraction
_finishFloatExponent
_intLength
_fractLength
_expLength
ParserBase.resetInt()
resetFloat()
ParserBase
FieldValue
Snyk IDSNYK-JAVA-COMFASTERXMLJACKSONCORE-15907551
GitHub AdvisoryGHSA-2m67-wjpj-xhg9
DescriptionAllocation of Resources Without Limits or Throttling
Disclosed2026-04-04
CVSS v4.0 Score8.7 HIGH
CWECWE-770 — Allocation of Resources Without Limits or Throttling
Affected Versions[2.8.0, 2.21.2)
Upstream Fixjackson-core 2.18.7, 2.21.2 or higher
Fix Commits74c9ee25 (3.x), 7ce3622f (2.18.x)
ParserPathEnforcement Point
UTF8StreamJsonParserInputStream → _loadMore()Validates _currInputProcessed + count after each buffer refill and at EOF
ReaderBasedJsonParserReader → _loadMore()Same pattern as UTF8StreamJsonParser
NonBlockingJsonParserfeedInput()Validates _currInputProcessed + _origBufferLen after each input chunk
UTF8DataInputJsonParserDataInputFail-fast: throws StreamConstraintsException if maxDocumentLength is configured
MethodValidation added
_startPositiveNumber() — fast-path returnvalidateIntegerLength(_intLength)
_startNegativeNumber() — fast-path returnvalidateIntegerLength(_intLength)
_finishNumberIntegralPart() — final returnvalidateIntegerLength(_intLength)
_finishToken() case MINOR_NUMBER_INTEGER_DIGITSvalidateIntegerLength(_intLength)
_startFloat() / _finishFloatFraction() / _finishFloatExponent() final returnsvalidateFPLength(_intLength + _fractLength + _expLength)
_finishToken() cases MINOR_NUMBER_FRACTION_DIGITS / MINOR_NUMBER_EXPONENT_DIGITSvalidateFPLength(...)
Test FileTest MethodParser modesCovers
read/ArrayParsingTest.javatestCVE_2025_52999streamRecursive traversal simulating real app use; confirms StreamConstraintsException at depth 1001 (remediated) and StackOverflowError at depth 20,000 (2.13.5)
read/ArrayParsingTest.javatestCustomNestingDepthConstraintdirect APIStreamReadConstraints.builder().maxNestingDepth(5) — accessor, at-limit pass, over-limit throws
read/ArrayParsingTest.javatestObjectNestingDepthLimitstreamObjects exactly at limit 1000 (pass), 1001-level objects throw
read/ArrayParsingTest.javatestDataInputParserDepthLimitUTF8DataInputJsonParserUTF8DataInputJsonParser enforces 1001-level depth limit
read/ArrayParsingTest.javatestNonBlockingParserDepthLimitnon-blockingNonBlockingJsonParser enforces 1001-level depth limit
Test FileTest MethodParser modesCovers
read/NumberOverflowTest.javatestSonatype_2022_6438ALL_MODESInteger at limit (pass), integer over limit (fail), float at limit (pass), float over limit (fail), scientific notation exponent at limit (pass), exponent over limit (fail) — all four parsers
read/NumberOverflowTest.javatestNonBlockingParserNumericLengthLimitnon-blockingNonBlockingJsonParser enforces numeric length
read/NumberOverflowTest.javatestNonBlockingParserExponentLengthLimitnon-blockingNonBlockingJsonParser enforces scientific notation exponent length via validateFPLength
read/NumberOverflowTest.javatestCustomMaxNumberLengthConstraintdirect APIStreamReadConstraints.builder().maxNumberLength(5) — accessor, at-limit pass, over-limit throws for both validateIntegerLength() and validateFPLength(), error message format
Test FileTest MethodParser modesCovers
constraints/LargeDocReadTest.javatestInputStreamExceedsLimitUTF8StreamJsonParserInputStream parser enforces maxDocumentLength — 20K doc rejected with 10K limit
constraints/LargeDocReadTest.javatestInputStreamUnderLimitSucceedsUTF8StreamJsonParserInputStream parser accepts doc within limit
constraints/LargeDocReadTest.javatestReaderExceedsLimitReaderBasedJsonParserReader parser enforces maxDocumentLength — 20K doc rejected with 10K limit
constraints/LargeDocReadTest.javatestReaderUnderLimitSucceedsReaderBasedJsonParserReader parser accepts doc within limit
constraints/LargeDocReadTest.javatestAsyncExceedsLimitNonBlockingJsonParserAsync parser enforces maxDocumentLength — 20K doc rejected in feedInput()
constraints/LargeDocReadTest.javatestAsyncUnderLimitSucceedsNonBlockingJsonParserAsync parser accepts doc within limit
constraints/LargeDocReadTest.javatestDataInputWithDocLengthLimitFailsUTF8DataInputJsonParserDataInput parser fails fast when maxDocumentLength is configured
constraints/LargeDocReadTest.javatestDataInputWithoutDocLengthLimitWorksUTF8DataInputJsonParserDataInput parser works normally without maxDocumentLength configured
constraints/LargeDocReadTest.javatestDefaultFactoryNoLimitUTF8StreamJsonParserDefault factory (no limit) accepts large documents
Test FileNew / Extended Methods
read/ArrayParsingTest.javatestCVE_2025_52999, testCustomNestingDepthConstraint, testObjectNestingDepthLimit, testDataInputParserDepthLimit, testNonBlockingParserDepthLimit
read/NumberOverflowTest.javatestSonatype_2022_6438 (extended to include exponent cases), testNonBlockingParserNumericLengthLimit, testCustomMaxNumberLengthConstraint, testNonBlockingParserExponentLengthLimit
constraints/LargeDocReadTest.javatestInputStreamExceedsLimit, testInputStreamUnderLimitSucceeds, testReaderExceedsLimit, testReaderUnderLimitSucceeds, testAsyncExceedsLimit, testAsyncUnderLimitSucceeds, testDataInputWithDocLengthLimitFails, testDataInputWithoutDocLengthLimitWorks, testDefaultFactoryNoLimit
FileChange TypeLines ChangedDescription
src/main/java/.../StreamReadConstraints.javaNew+356Constraint config + 5 validation methods
src/main/java/.../exc/StreamConstraintsException.javaNew+52Exception type for constraint violations
src/main/java/.../base/ParserBase.javaModified+44Depth/length hooks in reset and context helpers
src/main/java/.../json/JsonReadContext.javaModified+6throws IOException propagation
src/main/java/.../json/ReaderBasedJsonParser.javaModified+30Use depth-checking _createChild* helpers
src/main/java/.../json/UTF8StreamJsonParser.javaModified+26Use depth-checking _createChild* helpers
src/main/java/.../json/UTF8DataInputJsonParser.javaModified+26Use depth-checking _createChild* helpers
src/main/java/.../json/async/NonBlockingJsonParserBase.javaModified+4Use depth-checking _createChild* helpers
src/main/java/.../json/async/NonBlockingJsonParser.javaModified+9NEW — validateIntegerLength / validateFPLength at 6 number-completion sites; validateDocumentLength in feedInput()
src/main/java/.../JsonStreamContext.javaModified+20Added getNestingDepth()
src/main/java/.../TSFBuilder.javaModified+15Added _streamReadConstraints field and streamReadConstraints() setter
src/main/java/.../JsonFactory.javaModified+12Wire builder constraints into constructors; DataInput fail-fast for maxDocumentLength
src/test/java/.../read/NumberOverflowTest.javaModified+241testSonatype_2022_6438 (incl. exponent cases), testNonBlockingParserNumericLengthLimit, testNonBlockingParserExponentLengthLimit, testCustomMaxNumberLengthConstraint
src/test/java/.../read/NumberParsingTest.javaModified+39Updated 3 verifyException call sites
src/test/java/.../read/ArrayParsingTest.javaModified+143testCVE_2025_52999, testCustomNestingDepthConstraint
src/test/java/.../constraints/LargeDocReadTest.javaNew+2009 tests for maxDocumentLength enforcement across all parser paths
ComponentVersion
Base tagjackson-core-2.13.5
Branch2.13.5-CVE-2025-52999-sonatype-2022-6438-GHSA-2m67-wjpj-xhg9
Build toolMaven (wrapper: ./mvnw)
Test frameworkJUnit 3 / TestCase-style
Test count957