CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-59879

CVE-2026-59879: Infinite Loop and Integer Overflow in Immutable.js List Sizing

Amit Schendel
Amit Schendel
Senior Security Researcher

Jul 21, 2026·8 min read·89 visits

Executive Summary (TL;DR)

A design flaw in Immutable.js allows integer overflows during list resizing, enabling attackers to cause CPU exhaustion, out-of-memory crashes, or data corruption.

CVE-2026-59879 describes a critical integer overflow vulnerability in the Immutable.js library when handling indices near 32-bit boundaries. An attacker can leverage this flaw to cause a denial of service via CPU thread lockup or process crashes, as well as data corruption through silent size truncation.

Vulnerability Overview

Immutable.js is a widely used library for managing persistent, immutable data structures in JavaScript. Its List data structure utilizes a 32-way bitmapped vector trie to achieve efficient lookups and updates. The vulnerability, tracked as CVE-2026-59879, resides in the trie's internal resizing logic, which handles dynamic index and size boundaries.

An attacker can trigger this vulnerability by supplying index or size arguments in the range [2^30, 2^31) or larger to functions that modify the List bounds. This input causes an integer overflow during trie expansion, resulting in a thread-locking infinite loop or an Out-of-Memory (OOM) crash. The issue is classified under CWE-190 (Integer Overflow) and CWE-400 (Uncontrolled Resource Consumption).

The attack surface is exposed in any application that permits user-controlled indices or sizes to propagate into Immutable.js List mutation interfaces, such as set(), setSize(), setIn(), or updateIn(). Because JavaScript runtimes are typically single-threaded, a thread lockup completely disables processing of all concurrent requests on the affected event loop instance, leading to a severe denial of service.

Root Cause Analysis

The underlying issue stems from a combination of JavaScript bitwise operations and how Immutable.js dynamically scales its bitmapped vector trie. The library splits list indices into 5-bit chunks (SHIFT = 5) to navigate levels of the tree structure. When the engine processes a capacity change, it must raise the height of the trie if the new tail offset exceeds the maximum capacity representable at the current level.

In the vulnerable codebase, the loop responsible for raising trie levels was controlled by the condition newTailOffset >= 1 << (newLevel + SHIFT). Although standard JavaScript numbers are 64-bit floating-point values, JavaScript implements bitwise operations by coercing the operands to signed 32-bit integers. As newLevel increments in steps of 5, the term newLevel + SHIFT eventually reaches 31 and 32.

When newLevel + SHIFT equals 31, the bitwise expression 1 << 31 yields -2147483648. If newTailOffset is a positive number (such as 1073741792 from a requested size within [2^30, 2^31)), the comparison newTailOffset >= -2147483648 evaluates to true. In the next iteration, when newLevel + SHIFT equals 32, the shift count wraps around modulo 32, resulting in 1 << 0, which is 1. This causes the condition newTailOffset >= 1 to remain true indefinitely, establishing an infinite loop.

The runtime outcome of this loop depends on the initial state of the List object. For empty lists, the loop performs lightweight array allocations, leading to immediate CPU execution exhaustion. For populated lists, the loop continuously allocates wrapping VNode instances, consuming heap memory until the process terminates with an Out-of-Memory error.

Code Analysis

Prior to the remediation in versions 4.3.9 and 5.1.8, the library did not validate input bounds before applying bitwise coercion. The list normalization step relied on lossy signed 32-bit coercion, while the level-raising mechanism allowed bit shifts to overflow into negative numbers and wrap around.

// Vulnerable Code Path in src/List.js
if (end !== undefined) {
  end |= 0; // Lossy 32-bit integer coercion
}
 
// Level-raising logic
while (newTailOffset >= 1 << (newLevel + SHIFT)) {
  newRoot = new VNode(
    newRoot && newRoot.array.length ? [newRoot] : [],
    owner
  );
  newLevel += SHIFT;
}

The official fix implements pre-validation of the list limits using Number.isFinite and introduces MAX_LIST_SIZE capped at 2^30. This prevents any value exceeding safe limits from ever reaching the coercion or loop logic. Additionally, the bitwise shift operator in the comparison is replaced with a custom helper function, levelCapacity(exp), which avoids the overflow by switching to exponential representation when the exponent meets or exceeds 31.

// Patched Code Path in src/List.js
const MAX_LIST_SIZE = 2 ** 30;
 
function validateListBoundsRequest(list, begin, end) {
  const requestedOrigin = list._origin + (begin === undefined ? 0 : begin);
  const requestedCapacity = end === undefined
    ? list._capacity
    : end < 0
    ? list._capacity + end
    : list._origin + end;
 
  if (
    (Number.isFinite(requestedCapacity) && requestedCapacity > MAX_LIST_SIZE) ||
    (Number.isFinite(requestedOrigin) && requestedOrigin < -MAX_LIST_SIZE)
  ) {
    throw new RangeError('Invalid List size');
  }
}
 
// Safe exponentiation helper replacing bitwise shifts for large values
function levelCapacity(exp) {
  return exp < 31 ? 1 << exp : 2 ** exp;
}
 
// Patched level-raising logic
while (newTailOffset >= levelCapacity(newLevel + SHIFT)) {
  newRoot = new VNode(
    newRoot && newRoot.array.length ? [newRoot] : [],
    owner
  );
  newLevel += SHIFT;
}

Exploitation and Proof of Concept

An attacker can trigger the vulnerability remotely if the target application exposes endpoints that process user-controlled inputs as indices or array sizes in Immutable.js structures. No authentication is inherently required to exploit the core vulnerability itself; access depends entirely on the application's configuration. The payload consists of an integer payload designed to populate a set() or setSize() call.

To demonstrate a CPU Denial of Service, the attacker inputs a value within [2^30, 2^31), such as 1073741824. On an empty list, this triggers the infinite loop. Since the loop allocates negligible memory in this state, it runs indefinitely without crashing, keeping the CPU core bound at 100% utilization. This state blocks the execution of any other tasks on the Node.js main thread.

// Proof of Concept: CPU Thread Lockup (Empty List)
const { List } = require('immutable');
// Setting a value at 2^30 on an empty list causes a loop that never terminates
List().set(1073741824, "exploit_payload");

To demonstrate a Process Out-of-Memory (OOM) crash, the target structure must contain at least one element. Operating on a populated list changes the execution path because the root node is initialized. During the infinite loop, the runtime continuously creates new VNode wraps, exhausting the process heap space within fractions of a second and forcing the environment to abort.

// Proof of Concept: Process OOM Crash (Populated List)
const { List } = require('immutable');
const activeList = List([1, 2, 3]);
// This triggers rapid heap exhaustion and a SIGABRT crash
activeList.set(1073741824, "exploit_payload");

Advanced Patch Bypasses

A deep-dive analysis of the remediation patch reveals secondary logical vulnerabilities. The validation function validateListBoundsRequest performs checks on raw input values, but the actual sizing parameters undergo a second evaluation and bitwise coercion within setListBounds (begin |= 0, end |= 0). This design creates a double-evaluation hazard analogous to a Time-of-Check to Time-of-Use (TOCTOU) bug.

An attacker can exploit this double-evaluation by passing a stateful JavaScript object equipped with a custom valueOf() hook. The first call to valueOf() occurs during validation and can return a safe integer to pass the checks. The second call occurs inside setListBounds during coercion, where the hook returns an out-of-bounds value. This bypasses the boundary checks completely, causing silent size truncation and state corruption.

// TOCTOU Double-Evaluation Bypass PoC
const { List } = require('immutable');
let evaluations = 0;
const statefulBound = {
  valueOf: () => {
    evaluations++;
    return evaluations === 1 ? 3 : 2 ** 32 + 5;
  }
};
const list = List([1, 2, 3]);
const mutatedList = list.setSize(statefulBound);
// Size is silently coerced and truncated, leading to data corruption
console.log(mutatedList.size); 

A second bypass involves negative value inputs. When validating a negative end parameter, the code computes the requested capacity as list._capacity + end. If an attacker passes a highly negative integer outside the 32-bit signed range (e.g., -2^31 - 5), the validation step accepts it because the resulting negative capacity is mathematically less than MAX_LIST_SIZE. However, during the subsequent coercion (end |= 0), the negative integer wraps to a large positive value, setting a massive capacity without triggering the validation error. This leads to internal index corruption.

Incident Prevention & Remediation

To remediate CVE-2026-59879, developers should upgrade Immutable.js dependencies immediately. The vulnerability is resolved in versions 4.3.9 (for v4.x implementations) and 5.1.8 (for v5.x implementations). Software composition analysis tools should be configured to flag and block older versions.

However, due to the identified double-evaluation and negative overflow bypasses in the official validation logic, upgrading the package may not fully prevent data corruption or state inconsistency if the application processes complex object types or unchecked numeric values. Developers must sanitize and validate all inputs before passing them to Immutable.js APIs.

Implementing a defensive validation wrapper is highly recommended. The wrapper must ensure that the input is a primitive, non-negative integer below the safe limit of 2^30. Converting the input to a primitive number prior to validation blocks the stateful object bypass technique.

// Defensive input validation wrapper
function safeSetSize(list, targetSize) {
  const sizePrimitive = Number(targetSize);
  if (
    !Number.isInteger(sizePrimitive) ||
    sizePrimitive < 0 ||
    sizePrimitive >= 1073741824
  ) {
    throw new RangeError('Size must be a safe, positive primitive integer below 2^30');
  }
  return list.setSize(sizePrimitive);
}

Official Patches

Immutable-jsOfficial Advisory and Remediation guidance.
Immutable-jsRelease notes for version 4.3.9 contains fixes.
Immutable-jsRelease notes for version 5.1.8 contains fixes.

Fix Analysis (3)

Technical Appendix

CVSS Score
8.7/ 10
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
EPSS Probability
0.37%
Top 71% most exploited

Affected Systems

Applications using Immutable.js versions prior to 4.3.9 (v4 branch) or 5.1.8 (v5 branch)

Affected Versions Detail

Product
Affected Versions
Fixed Version
immutable
immutable-js
< 4.3.94.3.9
immutable
immutable-js
>= 5.0.0-beta.1, < 5.1.85.1.8
AttributeDetail
CWE IDCWE-190, CWE-400, CWE-835, CWE-1284
Attack VectorNetwork
CVSS v4.08.7 (High)
EPSS Score0.0037 (Percentile: 29.38%)
ImpactDenial of Service, Data Corruption
Exploit StatusProof-of-Concept
KEV StatusNot Listed

MITRE ATT&CK Mapping

T1203Exploitation for Client Execution
Execution
T1499Endpoint Denial of Service
Impact
CWE-190
Integer Overflow or Wraparound

The software performs an operation that can overflow the standard bounds of a data type, leading to resource consumption or logic flaws.

Known Exploits & Detection

GitHub AdvisoryDetails on reproducing the infinite loop and crash scenarios.

Vulnerability Timeline

Preparatory CI updates merged to repository.
2026-06-22
Root cause resolution commits authored.
2026-06-25
Formal release of patched versions 4.3.9 and 5.1.8.
2026-07-08
Coordinated disclosure of GHSA-v56q-mh7h-f735.
2026-07-08
NVD publication and CVSS score assignment.
2026-07-10

References & Sources

  • [1]NVD Reference CVE-2026-59879
  • [2]GitHub Advisory / Disclosure
  • [3]Wiz Vulnerability Database Profile

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•2 days ago•CVE-2026-107844
5.3

CVE-2026-107844: Path Traversal Vulnerability in Contao ImagesController

A path traversal vulnerability (CWE-22) in Contao CMS allows unauthenticated remote attackers to bypass directory boundary restrictions in ImagesController and access files within the project directory.

Amit Schendel
Amit Schendel
12 views•5 min read
•2 days ago•CVE-2026-107848
3.5

CVE-2026-107848: Cross-Site Request Forgery (CSRF) in Contao Backend Actions via GET Requests

Contao Open Source CMS versions 4.0.0 through 5.3.49 and 5.4.0-RC1 through 5.7.11 contain a Cross-Site Request Forgery (CSRF) vulnerability in backend parameter handling. The `RequestTokenListener` component validates anti-CSRF tokens solely for HTTP POST requests, while GET-based declarative guards run only when an `act` parameter is present in the query string. Consequently, custom backend actions dispatched via alternative parameters such as `key=` can execute without CSRF token verification when triggered by an authenticated user.

Amit Schendel
Amit Schendel
8 views•5 min read
•3 days ago•CVE-2026-107843
5.3

CVE-2026-107843: Unthrottled Activation Email Resend and Account Enumeration in Contao CMS

Contao CMS versions 4.1.0 through 5.3.49 and 5.4.0-RC1 through 5.7.11 fail to validate form submission tokens and enforce rate limiting when processing activation email resend requests via HTTP POST, enabling resource exhaustion and account state enumeration.

Amit Schendel
Amit Schendel
9 views•4 min read
•3 days ago•CVE-2026-107842
5.3

CVE-2026-107842: Information Disclosure via Stale Indexing in Contao Search Module

An information disclosure vulnerability in Contao CMS allows unauthenticated site visitors to view protected page titles, URLs, and text excerpts through search queries when protected page indexing is disabled after previously being enabled.

Amit Schendel
Amit Schendel
10 views•4 min read
•3 days ago•GHSA-G38J-7V97-X298
6.5

GHSA-G38J-7V97-X298: Missing Authorization Check in Vikunja CalDAV Task Relation Creation

In Vikunja prior to version 2.6.0, relation creation via the CalDAV endpoint fails to invoke the TaskRelation.CanCreate authorization check. This missing access control allows an authenticated user to establish unauthorized relationships and perform write operations against any task, provided its unique identifier (UID) is known.

Alon Barad
Alon Barad
12 views•5 min read
•3 days ago•GHSA-3HC7-R24J-RPWC
6.8

GHSA-3hc7-r24j-rpwc: Cross-Project Task Disclosure via Subtask Expansion in Vikunja

A cross-project information disclosure vulnerability in Vikunja allows authenticated users with read access to one project to view private task details from unauthorized projects via subtask expansion parameters.

Alon Barad
Alon Barad
9 views•5 min read