Severity by source
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:H/SI:H/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
Network-delivered XSS with no attacker auth required, but victim must trigger template cloning (UI:R); scope changes to victim browser with full session compromise (S:C, C:H, I:H).
Primary rating from Vendor (https://github.com/cure53/DOMPurify).
CVSS VectorVendor: https://github.com/cure53/DOMPurify
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:H/SI:H/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
Lifecycle Timeline
3Blast Radius
ecosystem impact- 25 npm packages depend on dompurify (17 direct, 8 indirect)
Ecosystem-wide dependent count for version 3.4.7.
DescriptionCVE.org
If the HTML you give it contains a <template> element, and inside that template there's an element with a shadow DOM attached to it, DOMPurify quietly skips over the shadow contents. Whatever the attacker put in there - an image with an onerror handler, a link with a javascript: URL, even a full script - survives untouched. The moment the application uses that template the way templates are meant to be used (cloning it and inserting the result into the page), the malicious payload comes along and runs as if it had never been sanitized. From there an attacker gets everything XSS normally gets them: session cookies, stored tokens, the ability to act as the user, and the ability to leave persistent payloads behind for the next person who visits.
AnalysisAI
DOMPurify's HTML sanitizer silently skips shadow DOM contents nested inside <template> elements, allowing stored or reflected XSS payloads to survive sanitization untouched in versions up to and including 3.4.6. When a consuming application clones and inserts the sanitized template into the live DOM - the standard and intended usage pattern for HTML templates - any attacker-controlled payload within the shadow root executes with full script privileges in the victim's browser context. A publicly available proof-of-concept (poc.html) has been released alongside the advisory; no confirmed active exploitation (CISA KEV) has been recorded at time of analysis, but the low attack complexity and broad deployment of DOMPurify across web applications make this a high-priority patching target.
Technical ContextAI
DOMPurify (pkg:npm/dompurify) is the de-facto client-side HTML sanitization library used across thousands of web applications to strip XSS payloads from user-supplied markup. The root cause (CWE-79: Improper Neutralization of Input During Web Page Generation) lies in the library's DOM traversal logic: when DOMPurify encounters a <template> element, it inspects the template's inert DocumentFragment content, but it fails to descend into shadow roots attached to elements within that fragment. The Web Components shadow DOM API allows arbitrary HTML subtrees to be attached via Element.attachShadow() and these subtrees are encapsulated from standard DOM queries. DOMPurify's walker never enters those shadow roots, meaning event handlers (onerror, onload), javascript: URL hrefs, and even raw <script> tags placed inside a shadow root nested within a template bypass all sanitization rules. The affected code path is specifically the IN_PLACE sanitization mode, as identified in the GHSA-rp9w-3fw7-7cwq advisory.
RemediationAI
Upgrade DOMPurify to version 3.4.7 or later, which resolves the shadow DOM traversal gap. The fix is confirmed by the upstream GitHub Security Advisory GHSA-rp9w-3fw7-7cwq at https://github.com/cure53/DOMPurify/security/advisories/GHSA-rp9w-3fw7-7cwq. Run npm install dompurify@3.4.7 or pin ^3.4.7 in package.json and rebuild. If immediate patching is not feasible, a targeted workaround is to strip or disallow <template> elements from input prior to DOMPurify processing using an allowlist that excludes the TEMPLATE tag - note that this trade-off disables legitimate template-based content. A second compensating control is to avoid cloning and inserting DOMPurify-sanitized content via the template cloning pattern (document.importNode / cloneNode on template.content) until the upgrade is applied; instead, use innerHTML-based insertion on the sanitized string directly, which does not trigger the vulnerable shadow DOM activation path. Neither workaround is a substitute for the 3.4.7 patch.
Same weakness CWE-79 – Cross-site Scripting (XSS)
View allShare
External POC / Exploit Code
Leaving vuln.today
EUVD-2026-44452
GHSA-rp9w-3fw7-7cwq