GHSA-h8r8-wccr-v5f2
NoneCVSS
—
EPSS
—
Published
Mar 27, 2026
CISA due date
—
Cloudanix analysis
A widely used web page sanitizing library could let malicious content run code in users’ browsers if applications render untrusted HTML with an outdated version.
- Exploitation
- Requires User Interaction
- Attacker needs
- None
- Complexity
- Moderate
- Impact
- Data Exposure
- Component
- Library
- Class
- XSS
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
DOMPurify versions before 3.3.2 can incorrectly sanitize specially crafted markup due to a mutation-XSS condition involving browser re-contextualization. An attacker can supply HTML/SVG/MathML-like content that appears safe during sanitization but is later mutated or reinterpreted by the browser into executable script when inserted into a page. Applications relying on DOMPurify as the primary control for rendering untrusted HTML may therefore allow client-side JavaScript execution in the victim’s browser.
Why it matters to the business
If an affected application renders attacker-controlled content, users may be exposed to account takeover, session theft, fraudulent actions performed in their browser, data exposure from the application UI, or malware/phishing delivery through trusted pages. Because DOMPurify is a widely used npm package and may be included directly or through downstream components, exposure can exist even when application teams did not intentionally add it as a first-party dependency.
How an attack unfolds
An attacker first identifies an application feature that accepts and later renders user-supplied rich text, HTML fragments, comments, profile fields, messages, documents, or other content sanitized by a vulnerable DOMPurify version. The attacker submits a carefully constructed payload designed to survive DOMPurify’s sanitization pass but change meaning when the browser parses, moves, normalizes, or re-contextualizes the markup. When another user views the content, the browser mutates the sanitized markup into active script execution. The injected script then runs with the privileges of the vulnerable web application origin, allowing the attacker to read page-accessible data, perform actions as the user, modify displayed content, exfiltrate tokens that are not properly protected, or pivot into phishing and session-abuse workflows.
How to fix it
Upgrade DOMPurify to version 3.3.2 or later in all npm projects and rebuild/redeploy affected applications. Update lockfiles as well as package manifests, and verify that transitive dependencies do not continue to bundle an older DOMPurify copy. Where immediate upgrade is not possible, reduce exposure by disabling rendering of untrusted HTML, rendering untrusted content as plain text, applying strict allowlists, avoiding post-sanitization DOM manipulation, and ensuring content is sanitized in the exact context where it will be inserted. Add defense-in-depth controls such as a restrictive Content Security Policy, Trusted Types where supported, HttpOnly/SameSite cookies, and avoidance of unsafe sinks such as innerHTML, outerHTML, insertAdjacentHTML, and dangerouslySetInnerHTML for untrusted content.
How to confirm the fix worked
Confirm the deployed dependency tree resolves DOMPurify to 3.3.2 or later using package manager tooling such as npm ls dompurify, npm audit, software composition analysis, SBOM review, and lockfile inspection. Verify production artifacts, containers, bundled JavaScript, and generated vendor assets do not include an older DOMPurify copy. Regression-test application features that render user-supplied rich text to ensure sanitized content does not execute script after browser parsing, DOM movement, templating, hydration, or framework re-rendering. Confirm CSP and Trusted Types policies are active where deployed, and review browser console/CSP reporting to ensure expected enforcement.
Typical attack path
- Find a web application feature that stores or reflects user-controlled rich text or HTML.
- Confirm the application uses an affected DOMPurify version before 3.3.2 to sanitize that content.
- Craft a mutation-XSS payload using markup that changes behavior after browser parsing or re-contextualization.
- Submit the payload through a field such as a comment, message, profile, document, ticket, or content-management input.
- Wait for a victim or privileged user to view the rendered content in the application.
- Achieve JavaScript execution in the victim’s browser under the application’s origin.
- Use the script to steal accessible data, perform unauthorized actions, capture user input, redirect the user, or load additional attacker-controlled code.
How to detect it
Retrospective detection is difficult because successful exploitation occurs in the victim’s browser and may not leave a server-side error. Review CDN, WAF, reverse proxy, and application logs for requests or stored submissions containing unusual nested HTML/SVG/MathML structures, encoded markup, template-like elements, foreignObject usage, annotation-xml, malformed tag nesting, or event-handler-like content in fields that support rich text. Review database or content-store records for recently created or modified user-generated HTML submitted before the upgrade, especially content later viewed by privileged users. Collect and analyze Content Security Policy violation reports for blocked inline script, unexpected script execution, or outbound connections following rich-content rendering. Correlate suspicious content views with authentication anomalies such as new sessions, unusual user-agent/IP changes, unexpected account actions, password or MFA changes, token refreshes, and abnormal API activity. Endpoint and browser telemetry, where available, should be checked for unexpected navigation, credential prompts, clipboard access, or script loads from untrusted domains immediately after users viewed pages containing user-generated content.
What your security team should do
- Prioritize inventory of all applications, packages, frontend bundles, and transitive dependencies that include dompurify npm versions before 3.3.2.
- Upgrade DOMPurify to 3.3.2 or later and redeploy affected applications, including rebuilt static assets and containers.
- Search code for unsafe HTML insertion sinks and ensure untrusted content is sanitized immediately before insertion into the final browser context.
- Add or tighten CSP to reduce the impact of successful XSS, especially by blocking inline script and limiting script-src to trusted origins.
- Enable Trusted Types for high-risk applications where supported to reduce unsafe DOM injection paths.
- Review stored user-generated content created before remediation for suspicious HTML/SVG/MathML payloads and consider re-sanitizing or invalidating cached rendered content.
- Monitor CSP reports, WAF/CDN logs, application logs, and authentication telemetry for signs of attempted or successful client-side exploitation.
- Add security tests for mutation-XSS and browser re-parsing behavior around all rich-text rendering features.
The record
DOMPurify is vulnerable to mutation-XSS via Re-Contextualization
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|---|---|---|
| npm | dompurify | 0 | 3.3.2 |
Related vulnerabilities
- GHSA-cmwh-pvxp-8882 DOMPurify: Permanent `ALLOWED_ATTR` pollution via `setConfig()` bypassing the hook… Also affects dompurify
- GHSA-vxr8-fq34-vvx9 DOMPurify: Trusted Types policy survives `clearConfig()` and can poison later… Also affects dompurify
- GHSA-gvmj-g25r-r7wr DOMPurify: SAFE_FOR_TEMPLATES bypass - template expressions survive sanitization inside… Also affects dompurify
- GHSA-rp9w-3fw7-7cwq DOMPurify IN_PLACE Sanitization Bypass via Attached Shadow Root Inside .content Also affects dompurify
- GHSA-x4vx-rjvf-j5p4 DOMPurify: `IN_PLACE` mode trusts attacker-controlled `nodeName` on live non-form nodes… Also affects dompurify
- GHSA-76mc-f452-cxcm DOMPurify: Hook mutation of `data.allowedTags` / `data.allowedAttributes` permanently… Also affects dompurify
- GHSA-hpcv-96wg-7vj8 DOMPurify: Cross-realm IN_PLACE sanitization leaves executable markup intact via… Also affects dompurify
- GHSA-r47g-fvhr-h676 DOMPurify: IN_PLACE mode preserves attributes of a clobbered root element, allowing XSS… Also affects dompurify