| Field |
Value |
| Project |
msgpack-java |
| Repository |
https://github.com/msgpack/msgpack-java |
| Affected Version |
0.9.12 (and earlier) |
| Component |
msgpack-core |
| Class |
org.msgpack.core.MessageUnpacker |
| File |
msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java |
| Vulnerable Line(s) |
646–663 |
| Severity |
Medium |
| CVSS 3.1 Score |
Base Score: 5.3 (MEDIUM) — CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L |
| CWE |
CWE-674 (Uncontrolled Recursion) |
An unauthenticated remote attacker sends a small payload of deeply nested fixarray[1] structures to trigger a StackOverflowError in the deserializing thread. StackOverflowError extends Error, so catch (IOException) and catch (MessagePackException) do not intercept it and the request fails. Availability is Low: the error is recoverable, the worker thread stays alive, and a top-level catch (Throwable) survives it. No data is read or modified.
Impact
Denial of service via a recoverable per-request deserialization failure.
- Escapes typed catch blocks:
catch (IOException) / catch (MessagePackException) miss the StackOverflowError.
- Recoverable: the worker thread survives, the stack unwinds cleanly, and frameworks with
catch (Throwable) recover fully. Impact is a per-request failure, not thread-pool exhaustion.
- Minimal payload: crash depth ≈1,500 with
-Xss512k (1,501-byte payload) and ≈11,000 with the default stack (≈11 KB payload), both within typical HTTP body limits.
Remediation
Option 1 — Add maxNestingDepth to UnpackerConfig (recommended):
private int maxNestingDepth = 512; // UnpackerConfig field
public ImmutableValue unpackValue() throws IOException {
return unpackValue(0);
}
private ImmutableValue unpackValue(int depth) throws IOException {
if (depth > config.getMaxNestingDepth()) {
throw new MessageSizeException("Nesting depth exceeds limit: " + depth, depth);
}
// ARRAY/MAP cases call unpackValue(depth + 1)
}
Option 2 — Convert to an iterative implementation using an explicit Deque stack, removing JVM-stack usage for nesting.
References
msgpack-coreorg.msgpack.core.MessageUnpackermsgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.javaCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:LAn unauthenticated remote attacker sends a small payload of deeply nested
fixarray[1]structures to trigger aStackOverflowErrorin the deserializing thread.StackOverflowErrorextendsError, socatch (IOException)andcatch (MessagePackException)do not intercept it and the request fails. Availability is Low: the error is recoverable, the worker thread stays alive, and a top-levelcatch (Throwable)survives it. No data is read or modified.Impact
Denial of service via a recoverable per-request deserialization failure.
catch (IOException)/catch (MessagePackException)miss theStackOverflowError.catch (Throwable)recover fully. Impact is a per-request failure, not thread-pool exhaustion.-Xss512k(1,501-byte payload) and ≈11,000 with the default stack (≈11 KB payload), both within typical HTTP body limits.Remediation
Option 1 — Add
maxNestingDepthtoUnpackerConfig(recommended):Option 2 — Convert to an iterative implementation using an explicit
Dequestack, removing JVM-stack usage for nesting.References
msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java, lines 646–663