GHSA-gvmj-g25r-r7wr
NoneCVSS
—
EPSS
—
Published
Jun 15, 2026
CISA due date
—
Cloudanix analysis
Some websites that use this library to clean user-submitted HTML may still let hidden instructions through that can run unwanted actions in a visitor’s browser.
- Exploitation
- Remote Unauthenticated
- Attacker needs
- None
- Complexity
- Moderate
- Impact
- Data Exposure
- Component
- Library
- Class
- XSS
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
This vulnerability is a cross-site scripting sanitization bypass in DOMPurify when applications use SAFE_FOR_TEMPLATES together with DOM output modes such as returning a DOM node or fragment. Under affected versions, template expressions embedded inside HTML <template> content can survive sanitization. If the sanitized output is later inserted into a client-side or server-side templating context, the surviving expression may be evaluated, allowing attacker-controlled script execution in the browser context of the consuming application.
Why it matters to the business
Applications relying on DOMPurify to safely display untrusted HTML may still expose users to script execution if they use the affected SAFE_FOR_TEMPLATES and DOM-output configuration. Successful exploitation can lead to account takeover, session theft, malicious actions performed as the victim, data exposure in the browser, or defacement of application content. The issue is not listed in CISA KEV, has no known public exploit maturity in the provided data, and is fixed in DOMPurify 3.4.8, so remediation should be prioritized for applications that sanitize user-generated HTML, rich text, comments, messages, CMS content, or imported HTML templates.
How an attack unfolds
An attacker first finds an application feature that accepts user-controlled HTML and is sanitized with DOMPurify. The attacker then submits markup containing a <template> element with a template expression that should have been removed by SAFE_FOR_TEMPLATES. In affected versions, the expression remains inside the template content when DOM output modes are used. If the application later inserts, clones, renders, compiles, or otherwise passes that sanitized DOM content into a templating engine or framework that evaluates the surviving expression, the attacker-controlled code executes in the victim user's browser. The practical impact depends on the surrounding application: exploitation may allow theft of tokens available to JavaScript, unauthorized state-changing requests, phishing overlays, content manipulation, or pivoting into privileged application workflows.
How to fix it
Upgrade DOMPurify to version 3.4.8 or later for the npm package. Review package-lock.json, yarn.lock, pnpm-lock.yaml, and bundled frontend assets to ensure no affected DOMPurify version remains in production builds. If immediate upgrade is not possible, avoid combining SAFE_FOR_TEMPLATES with DOM output modes for untrusted input, avoid re-processing sanitized DOM through template engines, strip or reject <template> elements from untrusted content, and prefer string sanitization followed by safe insertion patterns. Treat client-side sanitization as defense-in-depth; enforce server-side validation and apply a strict Content Security Policy that limits inline script execution where feasible.
How to confirm the fix worked
Confirm that dependency resolution installs dompurify 3.4.8 or later and that built frontend bundles contain the updated library. Validate all direct and transitive package references with npm audit, npm ls dompurify, yarn why dompurify, or pnpm why dompurify. Review code for DOMPurify.sanitize calls using SAFE_FOR_TEMPLATES with RETURN_DOM, RETURN_DOM_FRAGMENT, or other DOM-returning options. Add regression tests that sanitize payloads containing <template> elements with template-expression delimiters and verify that the expressions are removed or rendered inert before any templating or DOM insertion occurs. In deployed applications, test representative rich-text input flows using a non-destructive proof-of-concept payload and verify that it is displayed as inert text or removed, not evaluated.
Typical attack path
- Identify an application endpoint or UI feature that accepts rich HTML or template-like user input.
- Submit crafted HTML containing a <template> element with embedded template expressions such as mustache, ES template, ERB-style, or framework-specific delimiters.
- Rely on the vulnerable DOMPurify configuration using SAFE_FOR_TEMPLATES with DOM return modes to leave the expression inside the template content.
- Wait for the application to insert, clone, render, or compile the sanitized DOM output in a browser or templating context.
- Trigger execution when a victim views or interacts with the affected content.
- Use the resulting browser execution to steal accessible data, perform actions as the user, or modify application content.
How to detect it
To assess prior exploitation, focus on application logs, WAF logs, CDN request logs, API request bodies, stored-content audit trails, CMS history, support-ticket content, comment/message databases, and browser security telemetry for submitted HTML containing <template> tags combined with template-expression delimiters. Look especially at fields that accept rich text or HTML and are later viewed by privileged users. Review source repositories for vulnerable usage patterns such as DOMPurify.sanitize with SAFE_FOR_TEMPLATES and DOM return options, then correlate those features with suspicious historical inputs. In web telemetry, search for encoded and decoded variants of <template>, mustache delimiters, ES template expressions, ERB/EJS-style delimiters, Angular/Vue-like expressions, and scriptless payloads that depend on later template evaluation. There are no universal host-level artifacts for this issue because exploitation occurs through application content and browser-side rendering; investigation should be application-flow-specific and should include checking whether suspicious submitted content was viewed by authenticated or privileged users.
- SAFE_FOR_TEMPLATES
- RETURN_DOM
- RETURN_DOM_FRAGMENT
- <template
- %3Ctemplate
- </template>
- %3C%2Ftemplate%3E
- {{
- }}
- ${
- <%
- %>
- <%=
- ng-app
- v-html
- x-template
What your security team should do
- Inventory all applications and frontend bundles that include DOMPurify, including transitive dependencies and vendored copies.
- Upgrade dompurify npm package to 3.4.8 or later and redeploy affected applications.
- Prioritize remediation for applications that process user-generated HTML, administrator-viewed content, customer support messages, CMS content, chat, comments, or document imports.
- Search code for SAFE_FOR_TEMPLATES combined with DOM output options and review whether sanitized content is later passed into a templating engine or framework compiler.
- Add automated tests for sanitizer bypass payloads involving <template> content and common template delimiters.
- Apply or strengthen Content Security Policy controls to reduce the impact of any residual browser script execution.
- Review historical submissions and logs for suspicious template-expression payloads in HTML-bearing fields.
- Because the issue is not currently marked KEV and no exploit maturity is provided, track vendor advisories and threat intelligence for changes while still remediating exposed applications promptly.
The record
DOMPurify: SAFE_FOR_TEMPLATES bypass - template expressions survive sanitization inside <template> content when using DOM output modes
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|---|---|---|
| npm | dompurify | 3.0.0 | 3.4.8 |
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-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
- GHSA-87xg-pxx2-7hvx DOMPurify XSS via selectedcontent re-clone Also affects dompurify