CVE-2024-45801 Overview
CVE-2024-45801 is a sanitizer bypass in DOMPurify, a widely deployed client-side library used to neutralize cross-site scripting (XSS) payloads in HTML, MathML, and SVG. Specially crafted HTML using nesting techniques can evade the depth-checking logic introduced in earlier hardening releases. Attackers can also leverage prototype pollution to weaken the depth check, defeating the library's XSS protections. The maintainer cure53 has fixed the issue in DOMPurify versions 2.5.4 and 3.1.3. The advisory tracks the issue under GHSA-mmhx-hmjr-r674 and references CWE-1333 and CWE-1321.
Critical Impact
Applications relying on DOMPurify to render untrusted HTML can execute attacker-controlled scripts in the victim's browser, enabling session theft, account takeover, and arbitrary action in the application context.
Affected Products
- cure53/DOMPurify versions prior to 2.5.4 (2.x branch)
- cure53/DOMPurify versions prior to 3.1.3 (3.x branch)
- Web applications and frameworks bundling vulnerable DOMPurify builds (purify.cjs.js, purify.es.mjs)
Discovery Timeline
- 2024-09-16 - CVE-2024-45801 published to the National Vulnerability Database
- 2025-09-22 - Last updated in NVD database
Technical Details for CVE-2024-45801
Vulnerability Analysis
DOMPurify parses untrusted HTML into a DOM tree and walks the nodes to strip dangerous elements and attributes. Prior releases added a depth tracker to prevent recursion-based bypasses where deeply nested elements caused the sanitizer to miss malicious content during traversal. CVE-2024-45801 reports two independent weaknesses in that mitigation.
First, specially crafted nesting structures evade the depth counter entirely, allowing payloads to survive sanitization and reach the live DOM. Second, the depth tracking variable is reachable through prototype pollution. By polluting Object.prototype with a property such as the counter key, attackers can force the comparison logic to read attacker-controlled or NaN values, bypassing the threshold check.
The combined effect is a reliable XSS sink in any context where attacker HTML is passed to DOMPurify.sanitize() and then inserted into the page.
Root Cause
The depth tracking code relied on object property lookups without using a hardened own-property check, and did not guard against non-numeric values returned from a polluted prototype chain. The fix adds numberIsNaN = unapply(Number.isNaN) and uses objectHasOwnProperty to validate the depth value before comparison, ensuring polluted prototypes cannot influence sanitization logic. This is consistent with CWE-1321 (Improperly Controlled Modification of Object Prototype Attributes) and CWE-1333 weaknesses.
Attack Vector
Exploitation requires the victim to load a page that passes attacker-supplied HTML through a vulnerable DOMPurify build. The attacker delivers a nested payload or a JSON document that triggers prototype pollution earlier in the request flow, then submits HTML that survives sanitization. Because the scope is Changed and user interaction is required, the typical scenario is a stored or reflected payload rendered when a user views attacker content.
// Patch excerpt: dist/purify.cjs.js and dist/purify.es.mjs (3.x)
// fix: Hardened the depth tracking code against prototype pollution
const objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty);
const regExpTest = unapply(RegExp.prototype.test);
const typeErrorCreate = unconstruct(TypeError);
+const numberIsNaN = unapply(Number.isNaN);
// Source: https://github.com/cure53/DOMPurify/commit/1e520262bf4c66b5efda49e2316d6d1246ca7b21
// Patch excerpt: 2.x branch (dist/purify.cjs.js, dist/purify.es.js)
// fix: Merged prototype pollution check into 2.x
var stringTrim = unapply(String.prototype.trim);
var regExpTest = unapply(RegExp.prototype.test);
var typeErrorCreate = unconstruct(TypeError);
+var numberIsNaN = unapply(Number.isNaN);
function unapply(func) {
return function (thisArg) {
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
// Source: https://github.com/cure53/DOMPurify/commit/26e1d69ca7f769f5c558619d644d90dd8bf26ebc
Detection Methods for CVE-2024-45801
Indicators of Compromise
- Inbound HTTP request bodies containing deeply nested or repeated tag patterns (for example, repeated <form>, <math>, or <svg> wrappers) submitted to fields that render rich content.
- JSON request payloads attempting to set keys such as __proto__, constructor, or prototype reaching endpoints that subsequently invoke DOMPurify.sanitize().
- Outbound browser errors or CSP violation reports referencing inline script execution from user-generated content surfaces.
Detection Strategies
- Inventory all front-end bundles and Node.js dependencies for dompurify versions below 2.5.4 or 3.1.3 using npm ls dompurify or software composition analysis (SCA) tooling.
- Enable a strict Content Security Policy (CSP) with script-src allowlists and report-only endpoints to surface sanitizer escapes in production traffic.
- Add WAF or API gateway rules to flag request payloads containing prototype-pollution keys (__proto__, constructor.prototype) targeting endpoints that store HTML.
Monitoring Recommendations
- Monitor CSP violation reports for unexpected inline script executions on pages that render user-submitted HTML.
- Alert on dependency drift in CI/CD when builds resolve to dompurify versions that do not satisfy >=2.5.4 <3.0.0 || >=3.1.3.
- Capture browser telemetry for DOM mutations that introduce <script>, on* event handlers, or javascript: URLs after sanitization.
How to Mitigate CVE-2024-45801
Immediate Actions Required
- Upgrade DOMPurify to 2.5.4 for the 2.x branch or 3.1.3 (or later) for the 3.x branch across all front-end and server-side rendering code paths.
- Rebuild and redeploy any application bundles that statically include DOMPurify, since the patched code must ship to clients to take effect.
- Audit application code for prototype-pollution sinks (unsafe Object.assign, recursive merge utilities) and patch them, since they remain useful primitives even after the DOMPurify fix.
Patch Information
The fixes are tracked in commits 1e520262 for the 3.x branch and 26e1d69c for the 2.x branch. Both introduce a hardened numberIsNaN check and objectHasOwnProperty validation around the depth tracking logic. Full details are in the GitHub Security Advisory GHSA-mmhx-hmjr-r674.
Workarounds
- No vendor-supplied workaround exists; upgrading is required.
- As a compensating control, deploy a strict CSP that disables inline scripts (script-src 'self') on pages that render sanitized user content.
- Where feasible, render untrusted content as plain text instead of HTML until patched builds are deployed.
# Upgrade to patched DOMPurify versions
npm install dompurify@^3.1.3
# or for 2.x consumers
npm install dompurify@^2.5.4
# Verify resolved version in the dependency tree
npm ls dompurify
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


