CVE-2026-41238
Published:April 23, 2026
Updated:April 23, 2026
Summary 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.
Affected Packages
dompurify (CDN_JS):
Affected version(s) >=3.0.1 <3.4.0Fix Suggestion:
Update to version 3.4.0dompurify (NPM):
Affected version(s) >=3.0.1 <3.4.0Fix Suggestion:
Update to version 3.4.0Related Resources (3)
Do you need more information?
Contact UsCVSS v4
Base Score:
7.1
Attack Vector
NETWORK
Attack Complexity
HIGH
Attack Requirements
NONE
Privileges Required
NONE
User Interaction
PASSIVE
Vulnerable System Confidentiality
HIGH
Vulnerable System Integrity
LOW
Vulnerable System Availability
NONE
Subsequent System Confidentiality
HIGH
Subsequent System Integrity
LOW
Subsequent System Availability
NONE
CVSS v3
Base Score:
6.9
Attack Vector
NETWORK
Attack Complexity
HIGH
Privileges Required
NONE
User Interaction
REQUIRED
Scope
CHANGED
Confidentiality
HIGH
Integrity
LOW
Availability
NONE