CVE-2026-59880: Immutable.js: Hash-collision algorithmic complexity denial of service in Immutable.Map/Set

Published Jul 8, 2026
·
Updated

Summary

Immutable.Map and Immutable.Set keep keys that share the same 32-bit hash in a collision bucket that is scanned linearly. The string hash is public and deterministic, so an attacker who controls the keys inserted into a Map can craft many keys that all collide, degrading insertion and lookup from amortized O(1) to O(n) per operation — and O(n²) to build or read the whole set. A small, attacker-shaped payload can therefore consume disproportionate CPU and, on a single-threaded runtime such as Node.js, stall the event loop and deny service.

Details

The string hash uses the JVM-style polynomial hashed = (31 hashed + charCode) | 0. Strings such as "Aa" and "BB" hash to the same value (6531+97 == 6631+66 == 2112), and concatenating such blocks yields 2^n distinct strings sharing one hash (40 characters ⇒ >1,000,000 colliding keys). All such keys route to a single HashCollisionNode, whose get/update walk the entire bucket testing is(). There is no per-process salt, so the colliding set is fully precomputable from the open-source algorithm.

Proof of concept

Inserting N colliding keys (e.g. via Immutable.Map(obj) / Immutable.fromJS(obj)) is O(N²). Measured on one machine, ~8,000 colliding keys take ~0.7 s to build and ~0.6 s to read, scaling ×4 per doubling; ~16,000 keys exceed several seconds.

Impact

CPU-bound denial of service in applications that ingest attacker-controlled object keys into Immutable structures, e.g. Immutable.Map(req.body), Immutable.fromJS(req.body), state.merge(userObject) / mergeDeep(...). Applications that only store attacker input as values under fixed keys are not affected.

Affected versions

All versions through 5.1.7 (the deterministic string hash and linear collision bucket have existed since the 4.x line).

Patches

Fixed in 5.1.8 (adjust to the actual release): large collision buckets are indexed by a per-process seeded secondary hash, restoring near-linear behavior for the affected paths. The public hash() is unchanged (no breaking change), and is() remains the sole authority on key equality.

Workarounds

Before passing untrusted data to Immutable.js: cap request body size, limit object key count/length, and reject high-cardinality payloads; avoid building Maps directly from untrusted object keys.

References

- CWE-407 (Inefficient Algorithmic Complexity), CWE-400 (Uncontrolled Resource Consumption) - OWASP API4:2023 (Unrestricted Resource Consumption)

Other sources

Immutable.js provides many Persistent Immutable data structures. Prior to 4.3.9 and 5.1.8, Immutable.Map and Immutable.Set keep keys that share the same 32-bit hash in a HashCollisionNode collision bucket that is scanned linearly, allowing an attacker who controls keys inserted into a Map, such as through Immutable.Map(obj), Immutable.fromJS(obj), state.merge(userObject), or mergeDeep, to craft many colliding keys and degrade insertion and lookup to consume disproportionate CPU. This issue is fixed in versions 4.3.9 and 5.1.8.

MITRE

Affected Software

8 affected componentsFixes available
Immutable.js Immutable.Map<4.3.9
Immutable.js Immutable.Set<4.3.9
Immutable.js Immutable.Map<5.1.8
Immutable.js Immutable.Set<5.1.8
Immutable-js Immutable Node.js<4.3.9
Immutable-js Immutable Node.js>=5.0.0<5.1.8
npm/immutable>=5.0.0-beta.1<5.1.8
5.1.8
npm/immutable<4.3.9
4.3.9

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade npm/immutable to a version that resolves this vulnerability.

    Fixed in 5.1.8
  2. Upgrade

    Upgrade npm/immutable to a version that resolves this vulnerability.

    Fixed in 4.3.9
  3. Upgrade

    Upgrade to a fixed release to a version that resolves this vulnerability.

    Fixed in 5.1.8
  4. Upgrade

    Upgrade to a fixed release to a version that resolves this vulnerability.

    Fixed in 4.3.9
  5. Configuration

    Before passing untrusted data to Immutable.js, cap request body size, limit object key count/length, and reject high-cardinality payloads; avoid building Maps directly from untrusted object keys.

    Immutable.js Per-request input limits (request body size, object key count/length, and high-cardinality payload rejection) = cap request body size; limit object key count/length; reject high-cardinality payloads; avoid building Maps directly from untrusted object keys
  6. Configuration

    If possible for your application, ensure attacker-controlled data is only used as values under fixed keys, not as untrusted object keys inserted into Immutable.Map/Immutable.Set (e.g., avoid patterns like Immutable.Map(req.body) and Immutable.fromJS(req.body) when keys are attacker-controlled).

    Immutable.js Untrusted key handling when constructing Maps/Sets (input as values vs keys) = ensure attacker input is stored as values under fixed keys (not as object keys)

Event History

Jul 8, 2026
CVE Published
via MITRE·03:44 PM
Data Sourced
via MITRE·03:44 PM
DescriptionWeakness
Data Sourced
via NVD·04:16 PM
RemedyDescriptionSeverityWeaknessAffected Software
Jul 21, 2026
Advisory Published
via GitHub·07:02 PM
Data Sourced
via GitHub·07:02 PM
DescriptionWeaknessAffected Software
Free Weekly Intel

Don't miss critical vulnerabilities

Join thousands of security professionals who receive our weekly digest of trending CVEs, zero-days, and exploited vulnerabilities.

No spam. Unsubscribe anytime.

Frequently Asked Questions

1

What is the severity of CVE-2026-59880?

The severity of CVE-2026-59880 is high, with a CVSS score of 8.7.

2

How do I fix CVE-2026-59880?

To mitigate CVE-2026-59880, upgrade Immutable.js to versions 4.3.9 or 5.1.8 or later.

3

What systems are affected by CVE-2026-59880?

CVE-2026-59880 affects Immutable.Map and Immutable.Set in Immutable.js versions prior to 4.3.9 and 5.1.8.

4

What type of attack does CVE-2026-59880 enable?

CVE-2026-59880 allows for a denial of service attack due to hash-collision algorithmic complexity.

5

When was CVE-2026-59880 published?

CVE-2026-59880 was published on July 8, 2026.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203