Immutable.js List 32-bit Trie Overflow Leads to Denial of Service
A vulnerability in Immutable.js List methods (`#set`, `#setSize`, `#setIn`, `#updateIn`) allows a remote, unauthenticated attacker to trigger an infinite loop or heap exhaustion by providing a crafted numeric string index in the range `[2 ** 30, 2 ** 31)`. This leads to an unrecoverable Denial of Service (DoS) by causing a tight CPU spin or process abortion, with an additional silent data corruption issue in `setSize`. This vulnerability impacts application availability but not confidentiality or integrity, and can be triggered by a single small HTTP request.
A high-severity vulnerability (CVE-2026-59879) has been discovered in the immutable.js library, affecting versions < 4.3.9 and >= 5.0.0-beta.1, < 5.1.8. This flaw allows a remote, unauthenticated attacker to cause a Denial of Service (DoS) in applications that use immutable.js by supplying specific numeric string inputs to List#set, List#setSize, List#setIn, or List#updateIn methods. Specifically, an index in the range [2 ** 30, 2 ** 31) can trigger an uncatchable infinite loop on an empty List (leading to a tight CPU spin) or unbounded memory allocation on a populated List (causing heap exhaustion and process abortion). The vulnerability is rooted in incorrect signed 32-bit bitwise arithmetic handling within setListBounds() and can be triggered via a single, small HTTP request body, URL parameter, or key-path, impacting application availability. Additionally, a companion silent data corruption issue in setSize can lead to incorrect application state.
Attack Chain
- An unauthenticated attacker crafts a small HTTP request, embedding a numeric string (e.g.,
1073741824) in the range[2 ** 30, 2 ** 31)into a request body, URL, or key-path. - The vulnerable application, using
immutable.jsversions< 4.3.9or>= 5.0.0-beta.1, < 5.1.8, receives this request. - The application processes the untrusted input, passing the crafted numeric string as an index to
List#set,List#setSize,List#setIn, orList#updateIn. - Within
immutable.js, thesetListBounds()function attempts to handle the index using signed 32-bit bitwise arithmetic. - Due to a bug where JavaScript's shift count is taken modulo 32, the level-raising loop condition
newTailOffset >= 1 << (newLevel + SHIFT)becomes perpetually true. - If the
Listis empty, this results in an uncatchable infinite CPU spin, freezing the worker process. - If the
Listis populated (e.g., from an array with >= 32 elements), each iteration of the loop allocates a newVNodewithout bound, rapidly exhausting the process heap. - Heap exhaustion leads to the application process aborting (e.g.,
SIGABRT, exit134, or kernel OOM-kill137), causing a Denial of Service. - Alternatively, if
setSizeis called with a large value like2 ** 31or2 ** 32 + 5, silent wraparound due toToInt32coercion can corrupt theList's size to 0 or 5 respectively, leading to data corruption without crashing.
Impact
This vulnerability primarily impacts the availability of applications using vulnerable versions of immutable.js. A single, small, unauthenticated HTTP request can trigger an unrecoverable Denial of Service (DoS) by either causing a worker process to enter an infinite CPU spin, effectively hanging, or by forcing the process to consume all available memory, leading to an application crash (e.g., SIGABRT or OOM-kill). This can affect common application patterns such as configuration stores, document/collection editors, Redux-Immutable reducers, or JSON-Patch endpoints that route untrusted input into List operations. There is no observed impact on confidentiality or integrity, nor does it lead to Remote Code Execution (RCE). The companion silent data corruption issue can lead to applications operating with incorrect state, potentially causing further malfunctions, but without an immediate crash.
Recommendation
- Upgrade immutable.js: Immediately upgrade
immutable.jsto version4.3.9or higher, or to5.1.8or higher for the v5 beta releases, to remediate CVE-2026-59879. - Implement Input Validation: For systems that cannot be immediately upgraded, validate and clamp any externally supplied
Listindex orsetIn/updateInkey-path segments. Reject numeric path segments greater than or equal to2 ** 30before passing them toimmutable.jsmethods. - Containerize and Resource Limit Applications: Run request handling processes in isolated worker environments with resource limits (e.g., cap heap size using
--max-old-space-size) to contain any potential process aborts, allowing for faster recovery or restart of affected workers.
Indicators of compromise
2
package
| Type | Value |
|---|---|
| package | npm/immutable |
| package | npm/immutable |