Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessSupply DOM node carrying attached shadow root
-
DeliverySplit template expression across text nodes separated by disallowed elements
-
ExploitSanitize with SAFE_FOR_TEMPLATES and DOM-returning mode
-
ExecutionSeparator elements removed, fragments become adjacent
-
PersistshadowRoot.textContent serializes complete expression
-
ImpactDownstream template engine evaluates expression as XSS
Vulnerability Assessment
| Weakness |
CWE
OWASP Top 10:2025
A05:2025 - Injection
ASVS 5.0
V1 - Encoding and Sanitization Output encoding, context-aware escaping
MITRE ATT&CK
2 techniques across 2 tactics: Initial Access, Execution The technique list with ATT&CK links and the kill-chain view is part of the Basic plan and up. |
| Exploitation Conditions | Not a default-configuration flaw. ALL of the following must hold: (1) the application enables SAFE_FOR_TEMPLATES:true; (2) together with a DOM-returning mode - RETURN_DOM:true, RETURN_DOM_FRAGMENT:true, or IN_PLACE:true; (3) the sanitized input is a DOM node carrying an attached shadow root, created either programmatically via element.attachShadow or via declarative shadow DOM (attacker markup with <template shadowrootmode="open"> parsed through setHTMLUnsafe / Document.parseHTMLUnsafe); and (4) the application subsequently feeds the sanitized shadow root's textContent/innerHTML into a template evaluator that interprets {{...}}, ${...}, or <%...%>. Limiting factors: every one of these is non-default and application-specific; no impact occurs unless a downstream engine actually evaluates the expression; affected only in dompurify 3.4.4-3.4.16 (string sanitization without shadow roots, or non-DOM/non-template-safe modes, are not affected). |
| Impact | Signals converge on a genuine but conditional, mid-tier issue rather than an emergency. The input CVSS 4.0 vector (AV:N/AC:L/AT:N/PR:N/UI:A) scores 5.1 (medium) and models no impact to DOMPurify itself (VC/VI/VA:N) with low confidentiality/integrity impact to a subsequent system (SC:L/SI:L) - consistent with XSS landing in the downstream application rather than the library. EPSS is low (0.18%, 7th percentile) and the CVE is NOT in CISA KEV, so there is no evidence of active or widespread exploitation; the vuln.today decision label is 'this_month' (not act_now/emergency). A complete, working proof-of-concept is published in the Cure53 GHSA advisory, so exploitability is demonstrated, but exploitation is gated by a chain of non-default preconditions (see exploitation_conditions), which is why real-world risk is materially lower than the CWE-79 class would suggest. Note a vector-vs-mechanism caveat: the official 4.0 vector uses AT:N, yet the advisory states exploitation 'requires non-default application configuration' - a specific environmental precondition that arguably warrants AT:P; the low EPSS despite a public PoC fits this precondition-heavy, non-commodity profile. Net: patch within normal cycles (vendor fix exists in 3.4.17); prioritize if your application actually enables SAFE_FOR_TEMPLATES with a DOM-returning mode and feeds sanitized output to a template engine. |
| Exploit ScenarioDerived | A web application sanitizes attacker-influenced DOM (containing an attached shadow root) with DOMPurify configured as SAFE_FOR_TEMPLATES plus IN_PLACE/RETURN_DOM, then feeds the sanitized shadow root's textContent into a client- or server-side template engine. The attacker splits a template expression like ${alert(document.domain)} across text nodes separated by a disallowed element (e.g. <object>); after sanitization removes the separator the fragments merge into a complete expression that the template engine evaluates as script. The GHSA advisory includes a complete working PoC demonstrating injection of the attacker-chosen expression into post-sanitization shadow-root content. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Oct 28, 2026
DOMPurify 3.4.4 through 3.4.16 can be made to preserve attacker-chosen template expressions in the text content of an attached shadow root when SAFE_FOR_TEMPLATES is enabled together with a DOM-returning mode (RETURN_DOM, RETURN_DOM_FRAGMENT or IN_PLACE); because a disallowed separator element can sit between two individually harmless text fragments, the fragments become adjacent once that element is removed and reconstitute a complete ${...}, {{...}} or <%...%> expression. The exposure is not a default-configuration flaw: the application must sanitize a DOM node that already carries a shadow root and must subsequently feed that shadow root's textContent or innerHTML into a template evaluator, so real impact depends entirely on the downstream engine's evaluation context. Severity is mid-tier and conditional - EPSS is 0.18% (7th percentile), there is no CISA KEV entry, and the vendor has released a fix in 3.4.17; a public PoC reference (a demonstration snippet in the GitHub advisory) exists but is not verified as working exploit code.
RemediationAI
Vendor-released patch: upgrade dompurify to 3.4.17, which closes the gap; the upstream change is PR https://github.com/cure53/DOMPurify/pull/1672, commit a77a3e78b59f72fa4d1c83f22e121ad9cc7d3575, published in advisory https://github.com/cure53/DOMPurify/security/advisories/GHSA-cg2g-xh64-v4q7. If upgrading cannot be done immediately, the exposed configuration itself is the constraint: the flaw only manifests when SAFE_FOR_TEMPLATES:true is combined with RETURN_DOM, RETURN_DOM_FRAGMENT or IN_PLACE and the input is a DOM node carrying an attached shadow root, so either dropping SAFE_FOR_TEMPLATES from that call site or switching to plain string sanitization removes the bypass, at the cost of losing template-expression neutralization or the DOM output shape the application relies on. As a narrower stopgap matching the advisory's suggested fix, applications can mirror the missing invariant themselves by normalizing and re-stripping shadow root text content after sanitization and before handing it to any template evaluator; this trades an extra post-processing step and must cover nested shadow roots and shadow roots inside <template>.content to be complete. Upstream notes the fix should apply the post-walk normalize-and-rescrub to attached shadow roots; no per-text-node regex change is sufficient on its own.
Affected VersionsENISA
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 1 package in npm
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
DOMPurify neutralizes template syntax under SAFE_FOR_TEMPLATES through two layers in src/purify.ts: a per-text-node strip during the main walk (_stripTemplateExpressions, applied from _sanitizeElements around line 2246) and a post-walk safety net (_scrubTemplateExpressions around line 1717) that calls node.normalize() and re-strips expressions that only form after adjacent text nodes merge. Split fragments such as a lone '$' plus '{alert(document.domain)}' deliberately fail the delimiter regexes MUSTACHE_EXPR, TMPLIT_EXPR and ERB_EXPR, so only the post-walk pass can catch the merged expression - and that pass cannot reach shadow trees, because node.normalize() and the NodeIterator used there do not descend into shadow roots by DOM specification. Explicit recursion added at lines 1743-1750 under CVE-2026-65900 / GHSA-gvmj-g25r-r7wr covers <template>.content only; _sanitizeShadowDOM (around line 2710), which receives shadow roots via _sanitizeAttachedShadowRoots, applies the per-node strip but never performs the normalize-and-rescrub. This is CWE-79 (improper neutralization of input during web page generation): the sanitizer emits a serialized string that a downstream template engine interprets, yielding cross-site scripting client-side and potentially template injection server-side. Root cause is reachability of a post-walk normalization invariant, not a weakness in the expression regexes themselves; the advisory notes the trigger is confined to the DOM-output code paths and that string sanitization without shadow roots is unaffected.
Know when Dompurify gets its next vulnerability
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N
No attacker auth (PR:N), but exploitation needs non-default config and a downstream template engine (AC:H); XSS crosses into the app context (S:C) with low C/I.
Primary rating from Vendor (VulnCheck).
CVSS VectorVendor: VulnCheck
Lifecycle Timeline
2DescriptionCVE.org
DOMPurify from 3.4.4 before 3.4.17 contains a SAFE_FOR_TEMPLATES bypass that lets attackers preserve template expressions in attached shadow roots when using RETURN_DOM, RETURN_DOM_FRAGMENT, or IN_PLACE modes. Attackers can split expressions across text nodes separated by disallowed elements, which merge after removal and are evaluated by downstream template engines for cross-site scripting.
Blast Radius
ecosystem impact- 1 npm packages depend on dompurify (1 direct, 0 indirect)
Ecosystem-wide dependent count for version 3.4.4.
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
Cross-Site Scripting occurs when an application accepts untrusted data and sends it to a web browser without proper validation or encoding.
DOMPurify is a DOM-only, super-fast, uber-tolerant XSS sanitizer for HTML, MathML and SVG. Rated medium severity (CVSS 6
Cure53 DOMPurify before 2.0.17 allows mutation XSS. Rated medium severity (CVSS 6.1), this vulnerability is remotely exp
DOMPurify before 2.0.1 allows XSS because of innerHTML mutation XSS (mXSS) for an SVG element or a MATH element, as demo
DOMPurify is a DOM-only, super-fast, uber-tolerant XSS sanitizer for HTML, MathML and SVG. Rated critical severity (CVSS
Mutation-XSS in DOMPurify before 3.3.2 enables JavaScript execution in victim browsers when sanitized output is re-inser
Hook mutation pollution in DOMPurify <= 3.4.5 allows persistent bypass of HTML sanitization defaults when application-in
Trusted Types policy state contamination in DOMPurify 3.0.0-3.4.8 allows a previously supplied TRUSTED_TYPES_POLICY to s
Prototype pollution in DOMPurify's USE_PROFILES mode enables DOM-based XSS by causing the sanitizer to accept event hand
URI validation bypass in DOMPurify 3.3.1 and earlier allows `javascript:` protocol payloads to survive HTML sanitization
SAFE_FOR_TEMPLATES bypass in DOMPurify 3.0.0-3.4.7 allows template expressions such as ${evil}, {{evil}}, and <%evil%> t
Cross-site scripting in DOMPurify 3.4.6 and earlier enables script execution when the library's IN_PLACE sanitization mo
Stored XSS is achievable in applications using DOMPurify's setConfig() API combined with an uponSanitizeAttribute hook t
EUVD-2026-110512
GHSA-6vxf-252m-8g79
NVD
CVE.org
EPSS
Exploit-DB