Broken HTML Filter Lets Attackers Run Malicious Code in Users' Browsers

Your website uses a popular library called DOMPurify to clean up user-submitted content before displaying it — think of it like a bouncer checking IDs at the door. A flaw in older versions of this library means the bouncer can be tricked by a specific type of disguised content, allowing malicious code to slip through and run in your visitors' browsers. This is a confirmed, actively exploitable issue with public attack code available.

Business Impact And Actions

immediate urgency

Business Impact

If your site displays any user-generated content (comments, form inputs, rich text, messages), an attacker could exploit this to steal login sessions, impersonate users, redirect visitors to malicious sites, or extract sensitive data — all without the victim doing anything beyond visiting a page. This carries real compliance exposure under GDPR and similar regulations if customer data is accessed, and can severely damage user trust if exploited visibly.

What To Do

  1. Ask your developer to upgrade the DOMPurify library to version 2.5.0 (if on the 2.x line) or 3.1.3 (if on the 3.x line) — this is a straightforward dependency update that should take under an hour.
  2. Ask your developer to confirm the update is live in production, not just in the development environment.
  3. If you use a third-party platform or CMS that bundles DOMPurify, check with your vendor whether they have released a patch and apply it immediately.
  4. Review your web application logs for any unusual script injections or unexpected redirects in the period before the fix is applied.

DOMPurify < 2.5.0 / < 3.1.3 — Nesting-Based Mutation XSS (CVE-2024-47875)

critical severity CVSS 10.0

Vulnerability Explanation

DOMPurify sanitizes HTML by parsing it into a DOM tree, walking the nodes, removing disallowed elements and attributes, then re-serializing the result. The vulnerability arises from a mutation XSS (mXSS) technique: an attacker crafts deeply nested HTML structures that are parsed and serialized differently by the browser's HTML parser versus DOMPurify's internal traversal logic. When DOMPurify re-serializes the cleaned tree, the browser's parser re-interprets the output and 'mutates' it into a form that contains executable script — effectively bypassing sanitization. The root of the issue is that DOMPurify did not enforce a maximum nesting depth during DOM traversal and cloning, and lacked sufficient clobbering detection to catch these parser re-serialization quirks.

Root Cause

DOMPurify's DOM traversal and node-cloning routines did not track or limit element nesting depth. Deeply nested structures exploit differences between how the sanitizer walks the DOM and how the browser's HTML parser re-serializes it, causing sanitized output to be re-parsed into a form containing executable JavaScript (mutation XSS). The fix introduced a MAX_NESTING_DEPTH constant (500 levels), depth-tracking properties on nodes (__depth, __removalCount), and enhanced clobbering detection in shadow DOM sanitization loops.

Technical Impact

An attacker who can supply HTML input to a DOMPurify-sanitized field can inject and execute arbitrary JavaScript in the victim's browser context. This enables session hijacking, credential theft, DOM manipulation, phishing overlays, data exfiltration, and account takeover — all without requiring any privileges or user interaction beyond viewing the affected page. CVSS 3.1 Base Score: 10.0 (AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:H/A:H). Public proof-of-concept exploits are available.

Severity Justification

Network-accessible, no authentication required, no user interaction needed, scope change with high integrity and availability impact. CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:H/A:H. EPSS score of ~67% reflects high real-world exploitation probability. Public PoC exploits exist.

Affected Components

  • dompurify (npm) < 2.5.0
  • dompurify (npm) >= 3.0.0, < 3.1.3

Remediation Steps

  1. Identify which version of DOMPurify is installed: run `npm list dompurify` or check your package-lock.json / yarn.lock.
  2. If on the 2.x branch, upgrade to 2.5.0: `npm install dompurify@^2.5.0`. If on the 3.x branch, upgrade to 3.1.3: `npm install dompurify@^3.1.3`.
  3. If DOMPurify is loaded via a CDN (e.g., a <script> tag pointing to a specific version), update the URL to reference 2.5.0 or 3.1.3 and verify the integrity hash (SRI) is updated to match.
  4. Rebuild and redeploy your application. Confirm the updated version is served in production by checking the network tab or running `DOMPurify.version` in the browser console.
  5. If a third-party dependency bundles DOMPurify internally (e.g., a CMS plugin or UI component library), check that vendor's changelog for a patched release and update accordingly.

Verification Steps

  1. Run `npm list dompurify` in your project root and confirm the resolved version is 2.5.0+ or 3.1.3+.
  2. In a browser console on your production site, run `DOMPurify.version` — it should return '2.5.0', '3.1.3', or higher.
  3. If loaded via CDN, inspect the <script> src URL in page source and confirm it references a patched version.
  4. Run `npm audit` and confirm CVE-2024-47875 no longer appears in the output.

Code Examples (bash)

Vulnerable
# package.json dependency pinned to a vulnerable version
"dompurify": "2.4.5"
Fixed
# Upgrade via npm (2.x branch)
npm install dompurify@^2.5.0

# Or for 3.x branch
npm install dompurify@^3.1.3

# Verify installed version
npm list dompurify
# Expected output: dompurify@2.5.x or dompurify@3.1.x

Best Practices

  • Pin DOMPurify to a minor version range (e.g., ^2.5.0) and run `npm audit` in your CI pipeline to catch future CVEs before they reach production.
  • Always use DOMPurify's output as the final step before inserting HTML into the DOM — never re-process or re-serialize sanitized output through a second parser.
  • If using a CDN-hosted script, always include a Subresource Integrity (SRI) hash to detect unexpected version changes or CDN compromise.
  • Avoid accepting raw HTML input from users where possible; prefer Markdown or structured input formats that eliminate the need for HTML sanitization entirely.

Found this in your infrastructure?

VulWall scans for this and dozens of other issues automatically.

Scan Your Domain Free