CWE-1321
AllowedImproperly Controlled Modification of Object Prototype Attributes ('Prototype Pollution')
Abstraction: Variant · Status: Incomplete
The product receives input from an upstream component that specifies attributes that are to be initialized or updated in an object, but it does not properly control modifications of attributes of the object prototype.
779 vulnerabilities reference this CWE, most recent first.
GHSA-V39P-96QG-C8RF
Vulnerability from github – Published: 2021-09-01 18:37 – Updated: 2023-09-08 21:25This affects the package object-path before 0.11.6. A type confusion vulnerability can lead to a bypass of CVE-2020-15256 when the path components used in the path parameter are arrays. In particular, the condition currentPath === '__proto__' returns false if currentPath is ['__proto__']. This is because the === operator returns always false when the type of the operands is different.
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "object-path"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.11.6"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2021-23434"
],
"database_specific": {
"cwe_ids": [
"CWE-1321",
"CWE-843"
],
"github_reviewed": true,
"github_reviewed_at": "2021-08-30T18:16:08Z",
"nvd_published_at": "2021-08-27T17:15:00Z",
"severity": "MODERATE"
},
"details": "This affects the package object-path before 0.11.6. A type confusion vulnerability can lead to a bypass of CVE-2020-15256 when the path components used in the path parameter are arrays. In particular, the condition `currentPath === \u0027__proto__\u0027` returns false if `currentPath` is `[\u0027__proto__\u0027]`. This is because the `===` operator returns always false when the type of the operands is different.",
"id": "GHSA-v39p-96qg-c8rf",
"modified": "2023-09-08T21:25:42Z",
"published": "2021-09-01T18:37:11Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-23434"
},
{
"type": "WEB",
"url": "https://github.com/mariocasciaro/object-path/commit/7bdf4abefd102d16c163d633e8994ef154cab9eb"
},
{
"type": "PACKAGE",
"url": "https://github.com/mariocasciaro/object-path"
},
{
"type": "WEB",
"url": "https://github.com/mariocasciaro/object-path#0116"
},
{
"type": "WEB",
"url": "https://github.com/mariocasciaro/object-path%230116"
},
{
"type": "WEB",
"url": "https://lists.debian.org/debian-lts-announce/2023/01/msg00031.html"
},
{
"type": "WEB",
"url": "https://snyk.io/vuln/SNYK-JAVA-ORGWEBJARSNPM-1570423"
},
{
"type": "WEB",
"url": "https://snyk.io/vuln/SNYK-JS-OBJECTPATH-1569453"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L",
"type": "CVSS_V3"
}
],
"summary": "Prototype Pollution in object-path"
}
GHSA-V3C7-FG8Q-9W96
Vulnerability from github – Published: 2025-09-05 09:30 – Updated: 2025-09-05 09:30Vulnerability of exposing object heap addresses in the Ark eTS module. Impact: Successful exploitation of this vulnerability may affect availability.
{
"affected": [],
"aliases": [
"CVE-2025-58280"
],
"database_specific": {
"cwe_ids": [
"CWE-1321"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-09-05T08:15:31Z",
"severity": "HIGH"
},
"details": "Vulnerability of exposing object heap addresses in the Ark eTS module.\nImpact: Successful exploitation of this vulnerability may affect availability.",
"id": "GHSA-v3c7-fg8q-9w96",
"modified": "2025-09-05T09:30:35Z",
"published": "2025-09-05T09:30:35Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-58280"
},
{
"type": "WEB",
"url": "https://consumer.huawei.com/en/support/bulletin/2025/9"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-V42Q-78W8-8FCC
Vulnerability from github – Published: 2022-07-26 00:01 – Updated: 2022-08-06 09:34All versions of package set-deep-prop are vulnerable to Prototype Pollution via the main functionality.
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "set-deep-prop"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"last_affected": "1.0.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2021-23373"
],
"database_specific": {
"cwe_ids": [
"CWE-1321"
],
"github_reviewed": true,
"github_reviewed_at": "2022-08-06T09:34:51Z",
"nvd_published_at": "2022-07-25T14:15:00Z",
"severity": "CRITICAL"
},
"details": "All versions of package set-deep-prop are vulnerable to Prototype Pollution via the main functionality.",
"id": "GHSA-v42q-78w8-8fcc",
"modified": "2022-08-06T09:34:51Z",
"published": "2022-07-26T00:01:05Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-23373"
},
{
"type": "WEB",
"url": "https://security.snyk.io/vuln/SNYK-JS-SETDEEPPROP-1083231"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "set-deep-prop Prototype Pollution"
}
GHSA-V55M-3W98-233J
Vulnerability from github – Published: 2025-02-06 06:31 – Updated: 2025-02-06 15:32A prototype pollution in the lib.fromQuery function of underscore-contrib v0.3.0 allows attackers to cause a Denial of Service (DoS) via supplying a crafted payload.
{
"affected": [],
"aliases": [
"CVE-2024-57081"
],
"database_specific": {
"cwe_ids": [
"CWE-1321",
"CWE-400"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-02-05T22:15:32Z",
"severity": "HIGH"
},
"details": "A prototype pollution in the lib.fromQuery function of underscore-contrib v0.3.0 allows attackers to cause a Denial of Service (DoS) via supplying a crafted payload.",
"id": "GHSA-v55m-3w98-233j",
"modified": "2025-02-06T15:32:52Z",
"published": "2025-02-06T06:31:26Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-57081"
},
{
"type": "WEB",
"url": "https://gist.github.com/tariqhawis/4b2c7273054f0d70ef162aa5b6daec01"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-V5VG-G7RQ-363W
Vulnerability from github – Published: 2021-11-08 17:40 – Updated: 2022-07-15 20:23This affects versions of package json-pointer up to and including 0.6.1. A type confusion vulnerability can lead to a bypass of CVE-2020-7709 when the pointer components are arrays.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 0.6.1"
},
"package": {
"ecosystem": "npm",
"name": "json-pointer"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.6.2"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2021-23820"
],
"database_specific": {
"cwe_ids": [
"CWE-1321",
"CWE-843"
],
"github_reviewed": true,
"github_reviewed_at": "2021-11-04T16:55:47Z",
"nvd_published_at": "2021-11-03T18:15:00Z",
"severity": "MODERATE"
},
"details": "This affects versions of package `json-pointer` up to and including `0.6.1`. A type confusion vulnerability can lead to a bypass of CVE-2020-7709 when the pointer components are arrays.",
"id": "GHSA-v5vg-g7rq-363w",
"modified": "2022-07-15T20:23:13Z",
"published": "2021-11-08T17:40:49Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-23820"
},
{
"type": "WEB",
"url": "https://github.com/manuelstofer/json-pointer/pull/36"
},
{
"type": "WEB",
"url": "https://github.com/manuelstofer/json-pointer/commit/931b0f9c7178ca09778087b4b0ac7e4f505620c2"
},
{
"type": "PACKAGE",
"url": "https://github.com/manuelstofer/json-pointer"
},
{
"type": "WEB",
"url": "https://github.com/manuelstofer/json-pointer/blob/master/index.js%23L78"
},
{
"type": "WEB",
"url": "https://snyk.io/vuln/SNYK-JS-JSONPOINTER-1577287"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L",
"type": "CVSS_V3"
}
],
"summary": "Prototype Pollution in json-pointer"
}
GHSA-V659-54CX-G4QR
Vulnerability from github – Published: 2021-05-17 20:57 – Updated: 2021-05-25 20:44Prototype pollution vulnerability in 'deep-override' versions 1.0.0 through 1.0.1 allows an attacker to cause a denial of service and may lead to remote code execution.
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "deep-override"
},
"ranges": [
{
"events": [
{
"introduced": "1.0.0"
},
{
"fixed": "1.0.2"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2021-25941"
],
"database_specific": {
"cwe_ids": [
"CWE-1321"
],
"github_reviewed": true,
"github_reviewed_at": "2021-05-17T17:59:32Z",
"nvd_published_at": "2021-05-14T14:15:00Z",
"severity": "CRITICAL"
},
"details": "Prototype pollution vulnerability in \u0027deep-override\u0027 versions 1.0.0 through 1.0.1 allows an attacker to cause a denial of service and may lead to remote code execution.",
"id": "GHSA-v659-54cx-g4qr",
"modified": "2021-05-25T20:44:52Z",
"published": "2021-05-17T20:57:25Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-25941"
},
{
"type": "WEB",
"url": "https://github.com/ASaiAnudeep/deep-override/commit/2aced17651fb684959a6e04b1465a8329b3d5268"
},
{
"type": "WEB",
"url": "https://www.whitesourcesoftware.com/vulnerability-database/CVE-2021-25941"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "Prototype Pollution in deep-override"
}
GHSA-V7QG-QFRR-C59X
Vulnerability from github – Published: 2024-07-30 21:31 – Updated: 2024-08-01 15:32Prototype Pollution in lukebond json-override 0.2.0 allows attackers to to execute arbitrary code or cause a Denial of Service (DoS) via the proto property.
{
"affected": [],
"aliases": [
"CVE-2024-38984"
],
"database_specific": {
"cwe_ids": [
"CWE-1321"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-07-30T20:15:03Z",
"severity": "CRITICAL"
},
"details": "Prototype Pollution in lukebond json-override 0.2.0 allows attackers to to execute arbitrary code or cause a Denial of Service (DoS) via the __proto__ property.",
"id": "GHSA-v7qg-qfrr-c59x",
"modified": "2024-08-01T15:32:15Z",
"published": "2024-07-30T21:31:28Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-38984"
},
{
"type": "WEB",
"url": "https://gist.github.com/mestrtee/97a9a7d73fc8b38fcf01322239dd5fb1"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-V88G-CGMW-V5XW
Vulnerability from github – Published: 2022-02-10 23:30 – Updated: 2024-06-21 21:33An issue was discovered in ajv.validate() in Ajv (aka Another JSON Schema Validator) 6.12.2. A carefully crafted JSON schema could be provided that allows execution of other code by prototype pollution. (While untrusted schemas are recommended against, the worst case of an untrusted schema should be a denial of service, not execution of code.)
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "ajv"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "6.12.3"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2020-15366"
],
"database_specific": {
"cwe_ids": [
"CWE-1321",
"CWE-915"
],
"github_reviewed": true,
"github_reviewed_at": "2021-05-10T21:23:41Z",
"nvd_published_at": "2020-07-15T20:15:00Z",
"severity": "MODERATE"
},
"details": "An issue was discovered in ajv.validate() in Ajv (aka Another JSON Schema Validator) 6.12.2. A carefully crafted JSON schema could be provided that allows execution of other code by prototype pollution. (While untrusted schemas are recommended against, the worst case of an untrusted schema should be a denial of service, not execution of code.)",
"id": "GHSA-v88g-cgmw-v5xw",
"modified": "2024-06-21T21:33:48Z",
"published": "2022-02-10T23:30:59Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2020-15366"
},
{
"type": "WEB",
"url": "https://github.com/ajv-validator/ajv/commit/65b2f7d76b190ac63a0d4e9154c712d7aa37049f"
},
{
"type": "PACKAGE",
"url": "https://github.com/ajv-validator/ajv"
},
{
"type": "WEB",
"url": "https://github.com/ajv-validator/ajv/releases/tag/v6.12.3"
},
{
"type": "WEB",
"url": "https://github.com/ajv-validator/ajv/tags"
},
{
"type": "WEB",
"url": "https://hackerone.com/bugs?subject=user\u0026report_id=894259"
},
{
"type": "WEB",
"url": "https://security.netapp.com/advisory/ntap-20240621-0007"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L",
"type": "CVSS_V3"
}
],
"summary": "Prototype Pollution in Ajv"
}
GHSA-V8W9-8MX6-G223
Vulnerability from github – Published: 2026-03-11 00:31 – Updated: 2026-03-11 00:31Summary
When using parseBody({ dot: true }) in HonoRequest, specially crafted form field names such as __proto__.x could create objects containing a __proto__ property.
If the parsed result is later merged into regular JavaScript objects using unsafe merge patterns, this may lead to prototype pollution in the target object.
Details
The parseBody({ dot: true }) feature supports dot notation to construct nested objects from form field names.
In previous versions, the __proto__ path segment was not filtered. As a result, specially crafted keys such as __proto__.x could produce objects containing __proto__ properties.
While this behavior does not directly modify Object.prototype within Hono itself, it may become exploitable if the parsed result is later merged into regular JavaScript objects using unsafe merge patterns.
Impact
Applications that merge parsed form data into regular objects using unsafe patterns (for example recursive deep merge utilities) may become vulnerable to prototype pollution.
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "hono"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "4.12.7"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-1321"
],
"github_reviewed": true,
"github_reviewed_at": "2026-03-11T00:31:47Z",
"nvd_published_at": null,
"severity": "MODERATE"
},
"details": "## Summary\n\nWhen using `parseBody({ dot: true })` in HonoRequest, specially crafted form field names such as `__proto__.x` could create objects containing a `__proto__` property.\n\nIf the parsed result is later merged into regular JavaScript objects using unsafe merge patterns, this may lead to prototype pollution in the target object.\n\n## Details\n\nThe `parseBody({ dot: true })` feature supports dot notation to construct nested objects from form field names.\n\nIn previous versions, the `__proto__` path segment was not filtered. As a result, specially crafted keys such as `__proto__.x` could produce objects containing `__proto__` properties.\n\nWhile this behavior does not directly modify `Object.prototype` within Hono itself, it may become exploitable if the parsed result is later merged into regular JavaScript objects using unsafe merge patterns.\n\n## Impact\n\nApplications that merge parsed form data into regular objects using unsafe patterns (for example recursive deep merge utilities) may become vulnerable to prototype pollution.",
"id": "GHSA-v8w9-8mx6-g223",
"modified": "2026-03-11T00:31:47Z",
"published": "2026-03-11T00:31:47Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/honojs/hono/security/advisories/GHSA-v8w9-8mx6-g223"
},
{
"type": "WEB",
"url": "https://github.com/honojs/hono/commit/ef902257e0beacbb83d2a9549b3b83e03514a6fe"
},
{
"type": "PACKAGE",
"url": "https://github.com/honojs/hono"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N",
"type": "CVSS_V3"
}
],
"summary": "Hono vulnerable to Prototype Pollution possible through __proto__ key allowed in parseBody({ dot: true })"
}
GHSA-V9JR-RG53-9PGP
Vulnerability from github – Published: 2026-04-22 17:31 – Updated: 2026-04-27 16:32Summary
DOMPurify versions 3.0.1 through 3.3.3 (latest) are vulnerable to a prototype pollution-based XSS bypass. When an application uses DOMPurify.sanitize() with the default configuration (no CUSTOM_ELEMENT_HANDLING option), a prior prototype pollution gadget can inject permissive tagNameCheck and attributeNameCheck regex values into Object.prototype, causing DOMPurify to allow arbitrary custom elements with arbitrary attributes — including event handlers — through sanitization.
Affected Versions
- 3.0.1 through 3.3.3 (current latest) — all affected
- 3.0.0 and all 2.x versions — NOT affected (used
Object.create(null)for initialization, no|| {}reassignment) - The vulnerable
|| {}reassignment was introduced in the 3.0.0→3.0.1 refactor - This is distinct from GHSA-cj63-jhhr-wcxv (USE_PROFILES Array.prototype pollution, fixed in 3.3.2)
- This is distinct from CVE-2024-45801 / GHSA-mmhx-hmjr-r674 (__depth prototype pollution, fixed in 3.1.3)
Root Cause
In purify.js at line 590, during config parsing:
CUSTOM_ELEMENT_HANDLING = cfg.CUSTOM_ELEMENT_HANDLING || {};
When no CUSTOM_ELEMENT_HANDLING is specified in the config (the default usage pattern), cfg.CUSTOM_ELEMENT_HANDLING is undefined, and the fallback {} is used. This plain object inherits from Object.prototype.
Lines 591-598 then check cfg.CUSTOM_ELEMENT_HANDLING (the original config property) — which is undefined — so the conditional blocks that would set tagNameCheck and attributeNameCheck from the config are never entered.
As a result, CUSTOM_ELEMENT_HANDLING.tagNameCheck and CUSTOM_ELEMENT_HANDLING.attributeNameCheck resolve via the prototype chain. If an attacker has polluted Object.prototype.tagNameCheck and Object.prototype.attributeNameCheck with permissive values (e.g., /.*/), these polluted values flow into DOMPurify's custom element validation at lines 973-977 and attribute validation, causing all custom elements and all attributes to be allowed.
Impact
- Attack type: XSS bypass via prototype pollution chain
- Prerequisites: Attacker must have a prototype pollution primitive in the same execution context (e.g., vulnerable version of lodash, jQuery.extend, query-string parser, deep merge utility, or any other PP gadget)
- Config required: Default. No special DOMPurify configuration needed. The standard
DOMPurify.sanitize(userInput)call is affected. - Payload: Any HTML custom element (name containing a hyphen) with event handler attributes survives sanitization
Proof of Concept
// Step 1: Attacker exploits a prototype pollution gadget elsewhere in the application
Object.prototype.tagNameCheck = /.*/;
Object.prototype.attributeNameCheck = /.*/;
// Step 2: Application sanitizes user input with DEFAULT config
const clean = DOMPurify.sanitize('<x-x onfocus=alert(document.cookie) tabindex=0 autofocus>');
// Step 3: "Sanitized" output still contains the event handler
console.log(clean);
// Output: <x-x onfocus="alert(document.cookie)" tabindex="0" autofocus="">
// Step 4: When injected into DOM, XSS executes
document.body.innerHTML = clean; // alert() fires
Tested configurations that are vulnerable:
| Call Pattern | Vulnerable? |
|---|---|
DOMPurify.sanitize(input) |
YES |
DOMPurify.sanitize(input, {}) |
YES |
DOMPurify.sanitize(input, { CUSTOM_ELEMENT_HANDLING: null }) |
YES |
DOMPurify.sanitize(input, { CUSTOM_ELEMENT_HANDLING: {} }) |
NO (explicit object triggers L591 path) |
Suggested Fix
Change line 590 from:
CUSTOM_ELEMENT_HANDLING = cfg.CUSTOM_ELEMENT_HANDLING || {};
To:
CUSTOM_ELEMENT_HANDLING = cfg.CUSTOM_ELEMENT_HANDLING || create(null);
The create(null) function (already used elsewhere in DOMPurify, e.g., in clone()) creates an object with no prototype, preventing prototype chain inheritance.
Alternative application-level mitigation:
Applications can protect themselves by always providing an explicit CUSTOM_ELEMENT_HANDLING in their config:
DOMPurify.sanitize(input, {
CUSTOM_ELEMENT_HANDLING: {
tagNameCheck: null,
attributeNameCheck: null
}
});
Timeline
- 2026-04-04: Vulnerability discovered during automated DOMPurify fuzzing research (Fermat project)
- 2026-04-04: Confirmed in Chrome browser with DOMPurify 3.3.3
- 2026-04-04: Verified distinct from GHSA-cj63-jhhr-wcxv and CVE-2024-45801
- 2026-04-04: Advisory drafted, responsible disclosure initiated
Credit
https://github.com/trace37labs
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "dompurify"
},
"ranges": [
{
"events": [
{
"introduced": "3.0.1"
},
{
"fixed": "3.4.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-41238"
],
"database_specific": {
"cwe_ids": [
"CWE-1321",
"CWE-79"
],
"github_reviewed": true,
"github_reviewed_at": "2026-04-22T17:31:32Z",
"nvd_published_at": "2026-04-23T16:16:26Z",
"severity": "MODERATE"
},
"details": "## Summary\n\nDOMPurify versions 3.0.1 through 3.3.3 (latest) are vulnerable to a prototype pollution-based XSS bypass. When an application uses `DOMPurify.sanitize()` with the default configuration (no `CUSTOM_ELEMENT_HANDLING` option), a prior prototype pollution gadget can inject permissive `tagNameCheck` and `attributeNameCheck` regex values into `Object.prototype`, causing DOMPurify to allow arbitrary custom elements with arbitrary attributes \u2014 including event handlers \u2014 through sanitization.\n\n## Affected Versions\n\n- **3.0.1 through 3.3.3** (current latest) \u2014 all affected\n- **3.0.0 and all 2.x versions** \u2014 NOT affected (used `Object.create(null)` for initialization, no `|| {}` reassignment)\n- The vulnerable `|| {}` reassignment was introduced in the 3.0.0\u21923.0.1 refactor\n- This is **distinct** from GHSA-cj63-jhhr-wcxv (USE_PROFILES Array.prototype pollution, fixed in 3.3.2)\n- This is **distinct** from CVE-2024-45801 / GHSA-mmhx-hmjr-r674 (__depth prototype pollution, fixed in 3.1.3)\n\n## Root Cause\n\nIn `purify.js` at line 590, during config parsing:\n\n```javascript\nCUSTOM_ELEMENT_HANDLING = cfg.CUSTOM_ELEMENT_HANDLING || {};\n```\n\nWhen no `CUSTOM_ELEMENT_HANDLING` is specified in the config (the default usage pattern), `cfg.CUSTOM_ELEMENT_HANDLING` is `undefined`, and the fallback `{}` is used. This plain object inherits from `Object.prototype`.\n\nLines 591-598 then check `cfg.CUSTOM_ELEMENT_HANDLING` (the original config property) \u2014 which is `undefined` \u2014 so the conditional blocks that would set `tagNameCheck` and `attributeNameCheck` from the config are never entered.\n\nAs a result, `CUSTOM_ELEMENT_HANDLING.tagNameCheck` and `CUSTOM_ELEMENT_HANDLING.attributeNameCheck` resolve via the prototype chain. If an attacker has polluted `Object.prototype.tagNameCheck` and `Object.prototype.attributeNameCheck` with permissive values (e.g., `/.*/`), these polluted values flow into DOMPurify\u0027s custom element validation at lines 973-977 and attribute validation, causing all custom elements and all attributes to be allowed.\n\n## Impact\n\n- **Attack type:** XSS bypass via prototype pollution chain\n- **Prerequisites:** Attacker must have a prototype pollution primitive in the same execution context (e.g., vulnerable version of lodash, jQuery.extend, query-string parser, deep merge utility, or any other PP gadget)\n- **Config required:** Default. No special DOMPurify configuration needed. The standard `DOMPurify.sanitize(userInput)` call is affected.\n- **Payload:** Any HTML custom element (name containing a hyphen) with event handler attributes survives sanitization\n\n## Proof of Concept\n\n```javascript\n// Step 1: Attacker exploits a prototype pollution gadget elsewhere in the application\nObject.prototype.tagNameCheck = /.*/;\nObject.prototype.attributeNameCheck = /.*/;\n\n// Step 2: Application sanitizes user input with DEFAULT config\nconst clean = DOMPurify.sanitize(\u0027\u003cx-x onfocus=alert(document.cookie) tabindex=0 autofocus\u003e\u0027);\n\n// Step 3: \"Sanitized\" output still contains the event handler\nconsole.log(clean);\n// Output: \u003cx-x onfocus=\"alert(document.cookie)\" tabindex=\"0\" autofocus=\"\"\u003e\n\n// Step 4: When injected into DOM, XSS executes\ndocument.body.innerHTML = clean; // alert() fires\n```\n\n### Tested configurations that are vulnerable:\n\n| Call Pattern | Vulnerable? |\n|---|---|\n| `DOMPurify.sanitize(input)` | YES |\n| `DOMPurify.sanitize(input, {})` | YES |\n| `DOMPurify.sanitize(input, { CUSTOM_ELEMENT_HANDLING: null })` | YES |\n| `DOMPurify.sanitize(input, { CUSTOM_ELEMENT_HANDLING: {} })` | NO (explicit object triggers L591 path) |\n\n## Suggested Fix\n\nChange line 590 from:\n```javascript\nCUSTOM_ELEMENT_HANDLING = cfg.CUSTOM_ELEMENT_HANDLING || {};\n```\n\nTo:\n```javascript\nCUSTOM_ELEMENT_HANDLING = cfg.CUSTOM_ELEMENT_HANDLING || create(null);\n```\n\nThe `create(null)` function (already used elsewhere in DOMPurify, e.g., in `clone()`) creates an object with no prototype, preventing prototype chain inheritance.\n\n### Alternative application-level mitigation:\n\nApplications can protect themselves by always providing an explicit `CUSTOM_ELEMENT_HANDLING` in their config:\n\n```javascript\nDOMPurify.sanitize(input, {\n CUSTOM_ELEMENT_HANDLING: {\n tagNameCheck: null,\n attributeNameCheck: null\n }\n});\n```\n\n## Timeline\n\n- **2026-04-04:** Vulnerability discovered during automated DOMPurify fuzzing research (Fermat project)\n- **2026-04-04:** Confirmed in Chrome browser with DOMPurify 3.3.3\n- **2026-04-04:** Verified distinct from GHSA-cj63-jhhr-wcxv and CVE-2024-45801\n- **2026-04-04:** Advisory drafted, responsible disclosure initiated\n\n## Credit\n\nhttps://github.com/trace37labs",
"id": "GHSA-v9jr-rg53-9pgp",
"modified": "2026-04-27T16:32:03Z",
"published": "2026-04-22T17:31:32Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/cure53/DOMPurify/security/advisories/GHSA-v9jr-rg53-9pgp"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-41238"
},
{
"type": "PACKAGE",
"url": "https://github.com/cure53/DOMPurify"
},
{
"type": "WEB",
"url": "https://github.com/cure53/DOMPurify/releases/tag/3.4.0"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:H/I:L/A:N",
"type": "CVSS_V3"
}
],
"summary": "DOMPurify: Prototype Pollution to XSS Bypass via CUSTOM_ELEMENT_HANDLING Fallback"
}
Mitigation
By freezing the object prototype first (for example, Object.freeze(Object.prototype)), modification of the prototype becomes impossible.
Mitigation
By blocking modifications of attributes that resolve to object prototype, such as proto or prototype, this weakness can be mitigated.
Mitigation
Strategy: Input Validation
When handling untrusted objects, validating using a schema can be used.
Mitigation
By using an object without prototypes (via Object.create(null) ), adding object prototype attributes by accessing the prototype via the special attributes becomes impossible, mitigating this weakness.
Mitigation
Map can be used instead of objects in most cases. If Map methods are used instead of object attributes, it is not possible to access the object prototype or modify it.
CAPEC-1: Accessing Functionality Not Properly Constrained by ACLs
In applications, particularly web applications, access to functionality is mitigated by an authorization framework. This framework maps Access Control Lists (ACLs) to elements of the application's functionality; particularly URL's for web apps. In the case that the administrator failed to specify an ACL for a particular element, an attacker may be able to access it with impunity. An attacker with the ability to access functionality not properly constrained by ACLs can obtain sensitive information and possibly compromise the entire application. Such an attacker can access resources that must be available only to users at a higher privilege level, can access management sections of the application, or can run queries for data that they otherwise not supposed to.
CAPEC-180: Exploiting Incorrectly Configured Access Control Security Levels
An attacker exploits a weakness in the configuration of access controls and is able to bypass the intended protection that these measures guard against and thereby obtain unauthorized access to the system or network. Sensitive functionality should always be protected with access controls. However configuring all but the most trivial access control systems can be very complicated and there are many opportunities for mistakes. If an attacker can learn of incorrectly configured access security settings, they may be able to exploit this in an attack.
CAPEC-77: Manipulating User-Controlled Variables
This attack targets user controlled variables (DEBUG=1, PHP Globals, and So Forth). An adversary can override variables leveraging user-supplied, untrusted query variables directly used on the application server without any data sanitization. In extreme cases, the adversary can change variables controlling the business logic of the application. For instance, in languages like PHP, a number of poorly set default configurations may allow the user to override variables.