A AegiFlow
HIGHCVSS 8.7

GHSA-r7wm-3cxj-wff9

jackson-core: Async parser maxNumberLength bypass via chunked digit accumulation (incomplete fix for GHSA-72hv-8253-57qq)

Published
2026-07-21
Modified
2026-07-21
Sources
github-advisory

Summary

## Summary The fix released in jackson-core `2.18.6` and `2.21.1` for [GHSA-72hv-8253-57qq](https://github.com/FasterXML/jackson-core/security/advisories/GHSA-72hv-8253-57qq) (Number Length Constraint Bypass in Async Parser, published 2026-02-28) is incomplete. The fix commit `b0c428e6` (#1555) wired `validateIntegerLength` into a new `_setIntLength` helper and called it at every place where the integer portion of a number is *decided* (terminator byte arrived, `.` / `e/E` seen, end-of-feed inside a fully-buffered value). It did not call it on the much more attacker-relevant path: "ran out of input while still inside `MINOR_NUMBER_INTEGER_DIGITS`, return `NOT_AVAILABLE` to caller". As a result, an attacker who streams JSON to a non-blocking parser in many small chunks, without ever sending a terminator byte, can keep the parser inside `MINOR_NUMBER_INTEGER_DIGITS` indefinitely. `_textBuffer.expandCurrentSegment()` grows on every chunk, and `validateIntegerLength` is never invoked. The accumulator is only gated by `maxStringLength` (20 MiB default) — a **~20,000x amplification** of the documented `maxNumberLength` (1000 default). This is the same vulnerability class, same advisory wording ("Memory Exhaustion: Unbounded allocation in TextBuffer from excessively long numbers"), same parser class — just the streaming path the original fix didn't cover. The fix to the *fraction* path is correct (see `_finishFloatFraction` at line 1834-1837 of `NonBlockingUtf8JsonParserBase.java` in 2.18.6, where `_setFractLength(fractLen)` IS called before the `NOT_AVAILABLE` return); the equivalent call is missing from every integer-digit path. ## Affected versions Verified on the patched releases: - `com.fasterxml.jackson.core:jackson-core` **2.18.6** - `com.fasterxml.jackson.core:jackson-core` **2.21.1** Structurally identical code in `tools.jackson.core` 3.0.x / 3.1.x — same `NonBlockingUtf8JsonParserBase` class, same `_setIntLength` rollout, same NOT_AVAILABLE returns without validation. Not retested but presumed vulnerable. ## Affected code [`src/main/java/com/fasterxml/jackson/core/json/async/NonBlockingUtf8JsonParserBase.java`](https://github.com/FasterXML/jackson-core/blob/b0c428e6/src/main/java/com/fasterxml/jackson/core/json/async/NonBlockingUtf8JsonParserBase.java) in 2.18.6 / 2.21.1. ### Site 1 — `_startPositiveNumber(int ch)` lines 1320-1330: ```java if (outPtr >= outBuf.length) { // NOTE: must expand to ensure contents all in a single buffer (to keep // other parts of parsing simpler) outBuf = _textBuffer.expandCurrentSegment(); } outBuf[outPtr++] = (char) ch; if (++_inputPtr >= _inputEnd) { _minorState = MINOR_NUMBER_INTEGER_DIGITS; _textBuffer.setCurrentLength(outPtr); return _updateTokenToNA(); // = _inputEnd) { _minorState = MINOR_NUMBER_INTEGER_DIGITS; _textBuffer.setCurrentLength(outPtr); return _updateTokenToNA(); // INT_9) { if ((ch | 0x20) == INT_e) { _setIntLength(outPtr+negMod); // = outBuf.length) { outBuf = _textBuffer.expandCurrentSegment();

Affected packages

EcosystemPackageAffected versionsFixed versions
Mavencom.fasterxml.jackson.core:jackson-core2.18.8, 2.21.4, 2.22.1
Maventools.jackson.core:jackson-core3.1.4, 3.2.1

Remediation: Upgrade to 2.18.8 or later.

References

Includes data from the GitHub Advisory Database, licensed under CC-BY 4.0.