CVE-2026-59880
Immutable.js: Hash-collision algorithmic complexity denial of service in Immutable.Map/Set
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.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- None
- Integrity
- None
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
8.7
Immutable.js: Hash-collision algorithmic complexity denial of service in Immutable.Map/Set
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.
- Record
CVE-2026-59880- CVSS 4.0
- 8.7 High
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 - Weakness
- CWE-407
- Updated
- 2026-11-02
EUVDEUVD-2026-42315
8.7
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.
- Record
EUVD-2026-42315- CVSS 4.0
- 8.7 High
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 - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-xvcm-6775-5m9r
8.7
Immutable: Hash-collision algorithmic complexity denial of service in Immutable.Map/Set
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 (65*31+97 == 66*31+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
-
= 4.0.0-beta.1, < 4.3.9
-
= 5.0.0-beta.1, < 5.1.8
- < 3.8.4
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. Also fixed in 4.3.9 and 3.8.4.
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)
- Record
GHSA-xvcm-6775-5m9r- CVSS 4.0
- 8.7 High
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 - Weakness
- CWE-400, CWE-407
- Updated
- 2026-11-02
NVD
8.7
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.
- Record
CVE-2026-59880- CVSS 4.0
- 8.7 High
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/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-407
- Updated
- 2026-11-02
OSV
8.7
Immutable.js: Hash-collision algorithmic complexity denial of service in Immutable.Map/Set
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.
- Record
CVE-2026-59880- CVSS 4.0
- 8.7 High
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 - Weakness
- CWE-407
- Updated
- 2026-11-02
OSVDEBIAN-CVE-2026-59880
7.5
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.
- Record
DEBIAN-CVE-2026-59880- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Updated
- 2026-11-02
Show 13 moreShow less
OSVGHSA-xvcm-6775-5m9r
8.7
Immutable: Hash-collision algorithmic complexity denial of service in Immutable.Map/Set
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 (65*31+97 == 66*31+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
-
= 4.0.0-beta.1, < 4.3.9
-
= 5.0.0-beta.1, < 5.1.8
- < 3.8.4
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. Also fixed in 4.3.9 and 3.8.4.
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)
- Record
GHSA-xvcm-6775-5m9r- CVSS 4.0
- 8.7 High
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 - Weakness
- CWE-400, CWE-407
- Updated
- 2026-11-02
OSVUBUNTU-CVE-2026-59880
8.7
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.
- Record
UBUNTU-CVE-2026-59880- CVSS 4.0
- 8.7 High
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 - CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Updated
- 2026-11-02
OSVCLSA-2026-1784769617 No score
TuxCare security update for immutable (1 CVE)
TuxCare rebuilt immutable to address 1 CVE. Fixed in 5.0.3-tuxcare.3.
- Record
CLSA-2026-1784769617- Updated
- 2026-11-02
OSVCLSA-2026-1784856200 No score
TuxCare security update for immutable (1 CVE)
TuxCare rebuilt immutable to address 1 CVE. Fixed in 4.3.7-tuxcare.3.
- Record
CLSA-2026-1784856200- Updated
- 2026-11-02
OSVCLSA-2026-1784856463 No score
TuxCare security update for immutable (1 CVE)
TuxCare rebuilt immutable to address 1 CVE. Fixed in 4.3.5-tuxcare.3.
- Record
CLSA-2026-1784856463- Updated
- 2026-11-02
OSVCLSA-2026-1784943220 No score
TuxCare security update for immutable (1 CVE)
TuxCare rebuilt immutable to address 1 CVE. Fixed in 4.1.0-tuxcare.3.
- Record
CLSA-2026-1784943220- Updated
- 2026-11-02
OSVCLSA-2026-1784943293 No score
TuxCare security update for immutable (1 CVE)
TuxCare rebuilt immutable to address 1 CVE. Fixed in 3.8.3-tuxcare.1.
- Record
CLSA-2026-1784943293- Updated
- 2026-11-02
OSVCLSA-2026-1784943404 No score
TuxCare security update for immutable (2 CVEs)
TuxCare rebuilt immutable to address 2 CVEs. Fixed in 3.8.2-tuxcare.2.
- Record
CLSA-2026-1784943404- Updated
- 2026-11-02
OSVCLSA-2026-1785117466 No score
TuxCare security update for immutable (2 CVEs)
TuxCare rebuilt immutable to address 2 CVEs. Fixed in 3.8.1-tuxcare.2.
- Record
CLSA-2026-1785117466- Updated
- 2026-11-02
OSVCLSA-2026-1790084679 No score
TuxCare security update for immutable (2 CVEs)
TuxCare rebuilt immutable to address 2 CVEs. Fixed in 5.1.5-tuxcare.1.
- Record
CLSA-2026-1790084679- Updated
- 2026-11-02
OSVCLSA-2026-1790808099 No score
TuxCare security update for immutable (2 CVEs)
TuxCare rebuilt immutable to address 2 CVEs. Fixed in 3.7.6-tuxcare.1.
- Record
CLSA-2026-1790808099- Updated
- 2026-11-02
OSVCLSA-2026-1792163804 No score
TuxCare security update for immutable (2 CVEs)
TuxCare rebuilt immutable to address 2 CVEs. Fixed in 4.3.8-tuxcare.1.
- Record
CLSA-2026-1792163804- Updated
- 2026-11-02
OSVROOT-APP-NPM-CVE-2026-59880 No score
CVE-2026-59880 in immutable - Patched by Root
Root has patched CVE-2026-59880 in the immutable package for Root:npm. Multiple fixed versions available.
- Record
ROOT-APP-NPM-CVE-2026-59880- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
immutablenpm |
5.0.0-beta.1 up to 5.1.8 | 5.1.8 |
immutablenpm |
4.0.0-beta.1 up to 4.3.9 | 4.3.9 |
immutablenpm |
before 3.8.4 | 3.8.4 |
immutableTuxCare:npm |
5.0.3-tuxcare.0 up to 5.0.3-tuxcare.3, plus listed versions 5.0.35.0.3-tuxcare.15.0.3-tuxcare.2 |
5.0.3-tuxcare.3 |
immutableTuxCare:npm |
4.3.7-tuxcare.0 up to 4.3.7-tuxcare.3, plus listed versions 4.3.74.3.7-tuxcare.14.3.7-tuxcare.2 |
4.3.7-tuxcare.3 |
immutableTuxCare:npm |
4.3.5-tuxcare.0 up to 4.3.5-tuxcare.3, plus listed versions 4.3.54.3.5-tuxcare.14.3.5-tuxcare.2 |
4.3.5-tuxcare.3 |
immutableTuxCare:npm |
4.1.0-tuxcare.0 up to 4.1.0-tuxcare.3, plus listed versions 4.1.04.1.0-tuxcare.14.1.0-tuxcare.2 |
4.1.0-tuxcare.3 |
immutableTuxCare:npm |
3.8.3-tuxcare.0 up to 3.8.3-tuxcare.1, plus listed versions 3.8.3 |
3.8.3-tuxcare.1 |
immutableTuxCare:npm From an advisory covering 2 CVEs |
3.8.2-tuxcare.0 up to 3.8.2-tuxcare.2, plus listed versions 3.8.23.8.2-tuxcare.1 |
3.8.2-tuxcare.2 |
immutableTuxCare:npm From an advisory covering 2 CVEs |
3.8.1-tuxcare.0 up to 3.8.1-tuxcare.2, plus listed versions 3.8.13.8.1-tuxcare.1 |
3.8.1-tuxcare.2 |
Show 14 moreShow less
| Package | Affected | Fixed |
|---|---|---|
immutableTuxCare:npm From an advisory covering 2 CVEs |
5.1.5-tuxcare.0 up to 5.1.5-tuxcare.1, plus listed versions 5.1.5 |
5.1.5-tuxcare.1 |
immutableTuxCare:npm From an advisory covering 2 CVEs |
3.7.6-tuxcare.0 up to 3.7.6-tuxcare.1, plus listed versions 3.7.6 |
3.7.6-tuxcare.1 |
immutableTuxCare:npm From an advisory covering 2 CVEs |
4.3.8-tuxcare.0 up to 4.3.8-tuxcare.1, plus listed versions 4.3.8 |
4.3.8-tuxcare.1 |
node-immutableDebian:12 |
All versions, plus listed versions 4.1.0-34.3.4-14.3.8-14.3.8-24.3.9-1 |
None known |
node-immutableDebian:13 |
All versions, plus listed versions 4.3.4-14.3.8-14.3.8-24.3.9-1 |
None known |
node-immutableDebian:14 |
before 4.3.9-1, plus listed versions 4.3.4-14.3.8-14.3.8-2 |
4.3.9-1 |
immutableRoot:npm |
before 3.8.4-aikido.2 | 3.8.4-aikido.25.0.3-aikido.14.3.8-aikido.15.1.5-aikido.15.1.7-aikido.15.1.1-aikido.54.3.8-aikido.23.7.6-aikido.34.3.7-aikido.45.1.6-aikido.23.8.3-aikido.25.0.3-aikido.24.0.0-aikido.14.0.0-aikido.23.8.4-aikido.14.3.6-aikido.14.0.0-rc.12-aikido.13.7.6-aikido.4 |
@rootio/immutableRoot:npm |
before 3.8.4-root.io.2 | 3.8.4-root.io.25.0.3-root.io.14.3.8-root.io.15.1.5-root.io.15.1.7-root.io.15.1.1-root.io.54.3.8-root.io.23.7.6-root.io.34.3.7-root.io.45.1.6-root.io.23.8.3-root.io.25.0.3-root.io.24.0.0-root.io.14.0.0-root.io.23.8.4-root.io.14.3.6-root.io.14.0.0-rc.12-root.io.13.7.6-root.io.4 |
node-immutableUbuntu:20.04:LTS |
All versions, plus listed versions 3.8.2+dfsg-3 |
None known |
node-immutableUbuntu:22.04:LTS |
All versions, plus listed versions 3.8.2+dfsg-34.0.0-14.0.0-2 |
None known |
node-immutableUbuntu:24.04:LTS |
All versions, plus listed versions 4.1.0-34.3.4-1 |
None known |
node-immutableUbuntu:25.10 |
All versions, plus listed versions 4.3.4-1 |
None known |
node-immutableUbuntu:26.10 |
All versions, plus listed versions 4.3.8-24.3.9-1 |
None known |
node-immutableUbuntu:26.04:LTS |
All versions, plus listed versions 4.3.4-14.3.8-2 |
None known |
History
| Recorded | Changed | Sources |
|---|---|---|
| affected, facts | ||
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-59880 is a high vulnerability (CVSS 8.7) in Immutable-js Immutable, published July 8, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.66%, the 52nd percentile. Fixed in immutable 5.1.8.
References
github.com/immutable-js/immutable-js/security/advisories/GHSA-xvcm-6775-5m9r
github.com/immutable-js/immutable-js/commit/3dd7e5655012597a41873e328bf9142a8901527b
github.com/immutable-js/immutable-js/commit/e51d49fc612ded5ec4dfb94ff294d22074269b0f
github.com/immutable-js/immutable-js/releases/tag/v4.3.9
github.com/immutable-js/immutable-js/releases/tag/v5.1.8
nvd.nist.gov/vuln/detail/CVE-2026-59880
Show 7 moreShow less
github.com/immutable-js/immutable-js/releases/tag/v3.8.4
github.com/advisories/GHSA-xvcm-6775-5m9r
github.com/CVEProject/cvelistV5/tree/main/cves/2026/59xxx/CVE-2026-59880.json
security-tracker.debian.org/tracker/CVE-2026-59880
github.com/immutable-js/immutable-js
ubuntu.com/security/CVE-2026-59880
cve.org/CVERecord?id=CVE-2026-59880