Skip to main content

DOMPurify CVE-2026-109345

| EUVDEUVD-2026-97647 MEDIUM
Cross-site Scripting (XSS) (CWE-79)
2026-10-12 VulnCheck GHSA-cjhx-p48c-gfm9
5.1
CVSS 4.0 · Vendor: VulnCheck
View

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain

  1. Access
    Craft style element with onerror payload
  2. Delivery
    Submit to app using IN_PLACE sanitize
  3. Exploit
    Bypass neutralization via surviving rawtext text
  4. Execution
    App serializes and re-parses returned node
  5. Impact
    Execute script in victim browser

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

Exploitation requires the target application to call DOMPurify.sanitize(node, { IN_PLACE: true }) on a Node input (not a string) using a vulnerable version <=3.4.15, and to subsequently serialize the returned node and re-parse that serialized HTML in a plain HTML context - the published PoC runs with SAFE_FOR_XML at its default (true). The specific trigger is a rawtext element (e.g. <style>) whose text content carries markup (a closing </style> tag plus an img onerror payload); the 3.4.9 _forceRemove TypeError guard and _neutralizeSubtree attribute-stripping do not touch text content, so the killed node is returned with live markup. LIMITING FACTORS: this is not a default DOMPurify usage pattern - string inputs and non-IN_PLACE sanitization return an empty/safe result, so applications not using IN_PLACE mode with node inputs and a serialize-then-reparse round-trip are not affected. CVSS UI:A also indicates active victim interaction is part of the attack path.

Impact

CVSS 4.0 base score is 5.1 (medium): AV:N/AC:L/AT:N/PR:N/UI:A with no impact on the vulnerable system (VC:N/VI:N/VA:N) and low confidentiality/integrity impact on a subsequent system (SC:L/SI:L) - i.e. a classic client-side XSS whose damage lands in the victim's browser session rather than on the DOMPurify host. No EPSS score, SSVC decision, or CISA KEV status was provided in the input, so there is no quantitative exploitation-probability or automatability signal to weigh; absence of KEV means there is no evidence of active exploitation. However, the GHSA advisory ships a complete, independently-reproduced proof-of-concept (jsdom 30.0.1/29.1.1, Node 20.x/26.x), so working exploit code is effectively public. The signals are internally consistent - network vector with required user interaction matches a reflected/stored XSS - but exploitability is heavily gated by a non-default integration pattern (the target application must call DOMPurify.sanitize with IN_PLACE:true on a Node input and then serialize and re-parse the returned node), which is not captured by the CVSS metrics and materially lowers real-world reach. Net: a real but conditional XSS bug in a very widely used library; prioritize for applications known to use IN_PLACE mode, treat as lower urgency elsewhere. No EPSS/KEV data available - risk ranking relies on CVSS and confirmed PoC only.

Exploit ScenarioDerived

An attacker submits user-controlled content containing a <style> element whose text is '</style><img src=x onerror=...>' to a web application that sanitizes nodes with DOMPurify.sanitize(node, { IN_PLACE: true }). DOMPurify force-removes the rawtext root but returns it with its text payload intact; when the application serializes the returned node and re-parses the HTML, the img onerror handler executes script in the victim's browser. A working proof-of-concept is published in the GHSA advisory.

This Month Plan within 30 days. Why: MEDIUM severity (CVSS 4.0-6.9).
Patch available 0.2% exploitation probability (EPSS)

Get an e-mail when this CVE is exploited, patched or re-scored. Free account.

Alert me

AnalysisAIv1 – Oct 12, 2026

Cross-site scripting in DOMPurify 3.4.15 and earlier lets an attacker smuggle live markup through the library's IN_PLACE sanitization path when a rawtext element such as <style> is passed as a DOM Node: the killed node is returned detached but its text content still contains the closing </style> tag plus an img onerror payload, which materializes as script if the application serializes that node and re-parses the resulting HTML in a plain HTML context. Only applications that call DOMPurify.sanitize(node, { IN_PLACE: true }) with a Node (not a string) and then perform a serialize-then-reparse round-trip on the returned value are affected; the CVSS 4.0 base score is 5.1 (medium, AV:N/AC:L/PR:N/UI:A, no impact to the vulnerable system, low confidentiality and integrity impact on a subsequent system), and a working proof-of-concept is published in the upstream advisory, though there is no indication of confirmed active exploitation. Vendor-released patch: 3.4.16.

RemediationAI

Upgrade the dompurify npm dependency to 3.4.16 or later, the vendor-released patch version; the fix is delivered by pull request https://github.com/cure53/DOMPurify/pull/1636 (commit b9b9d80f7e401771c2ccaef5f45def7eec8f27d7) and the change is documented in GHSA-6688-9rhm-gjv2 at https://github.com/cure53/DOMPurify/security/advisories/GHSA-6688-9rhm-gjv2. If an immediate upgrade is not possible, the highest-fidelity compensating control is to stop passing DOM Nodes to DOMPurify with IN_PLACE: true and instead sanitize the input as a string (or use non-IN_PLACE output such as RETURN_DOM/RETURN_DOM_FRAGMENT and insert the returned tree directly), since string and default-mode sanitization return an empty/safe result for this payload - the trade-off is that code depending on in-place mutation of a caller-owned node must be refactored, and any caller that keeps the untrusted node reference must be audited. Because the bypass only materializes when the returned node is serialized (outerHTML) and re-parsed as HTML, breaking the serialize-then-reparse round-trip on sanitizer output - for example by consuming the returned node directly in the DOM rather than round-tripping its markup through innerHTML or a template renderer - removes the execution primitive; this is a containment measure, not a substitute for upgrading, and it leaves the unsanitized rawtext content reachable to any other code path that does serialize the node. As defense in depth, keep a strict Content-Security-Policy (script-src without unsafe-inline and without unsafe-eval) to blunt the img onerror execution primitive, and re-sanitize any sanitizer output that is persisted and later re-parsed. Note that no backport for releases earlier than 3.4.16 is identified, so pinned or vendored copies of DOMPurify must be updated explicitly.

Affected VersionsENISA

DOMPurify 0 <3.4.16

Affected Packages

npm dompurify fix: 3.4.16

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 is a widely used client-side HTML/SVG/MathML sanitizer from Cure53, distributed on npm as dompurify (CPE cpe:2.3:a:cure53:dompurify:*:*:*:*:*:*:*:*), typically wrapping a DOM implementation such as the native browser DOM or jsdom. IN_PLACE mode is a non-default Node-input path in which sanitization mutates and returns the caller's own node rather than a sanitized string. The root cause is CWE-79 (improper neutralization of input during web page generation, i.e. cross-site scripting) combined with an incomplete fix: the 3.4.9 hardening for the IN_PLACE detached-root class added a fail-closed TypeError in _forceRemove when a node selected for removal cannot be detached, plus a _neutralizeSubtree pass that strips non-allowlisted attributes from removed subtrees. Both defenses address attributes and detachment failure only. When the force-removed root is a rawtext element such as <style>, the payload lives in the element's text content, so the TypeError guard is never reached (the node detaches cleanly), _neutralizeSubtree strips nothing (there are no attributes to strip), and the IN_PLACE exit returns the detached, never-sanitized <style> whose text still carries '</style><img src=x onerror=1>'. Because the HTML parser treats <style> as a rawtext state element, that text is inert while embedded, but serializing the node with outerHTML re-emits the raw text and re-parsing it in ordinary HTML context closes the style element and instantiates the injected <img> element with its onerror handler - a classic sanitizer round-trip bypass requiring no foreign-content context. The same Node sanitized without IN_PLACE returns an empty result, which confirms the defect is specific to the IN_PLACE return path handing back the killed node. The affected version range is <= 3.4.15 across all npm distribution channels, and SAFE_FOR_XML at its default (true) does not prevent the issue.

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

Vendor (VulnCheck) PRIMARY 5.1 MEDIUM
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
vuln.today AI 6.1 MEDIUM

Network-delivered XSS executing in the victim browser (scope change S:C, UI:R); no attacker privileges (PR:N); low confidentiality/integrity impact on the subsequent context and no availability impact.

3.1 AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
4.0 AV:N/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N
Red Hat 6.1 MEDIUM

Primary rating from Vendor (VulnCheck).

CVSS VectorVendor: VulnCheck

Attack Vector
Network
Attack Complexity
Low
Attack Requirements
None
Privileges Required
None
User Interaction
Active
Vulnerable system: Confidentiality
None
Vulnerable system: Integrity
None
Vulnerable system: Availability
None
Subsequent system: Confidentiality
Low
Subsequent system: Integrity
Low
Subsequent system: Availability
None

Lifecycle Timeline

2
Patch available
Oct 12, 2026 - 18:03 EUVD
CVE Published
Oct 12, 2026 - 16:05 cve.org
MEDIUM 5.1

DescriptionCVE.org

DOMPurify before 3.4.16 contains a cross-site scripting vulnerability that allows attackers to bypass sanitization because IN_PLACE mode returns a force-removed style element whose text content still carries markup. Attackers can supply a style element containing a closing style tag and an img onerror payload, which executes script when the application serializes and re-parses the returned node.

Blast Radius

ecosystem impact
† from your stack dependencies † transitive graph · vuln.today resolves 4-path depth
  • 231 npm packages depend on dompurify (63 direct, 169 indirect)

Ecosystem-wide dependent count for version 3.4.16.

Threat Intelligence Overview

EPSS Score
0.2%
Top 90% exploitable
Prevalence
High
DOMPurify is an extremely popular client-side HTML sanitizer, tens of millions of npm installs
Data Quality
5 sources
Confidence: Medium

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.

SignalValue
Severity MEDIUM
CISA KEV No
Public POC No
EPSS 0.2%
Patch available Yes
Active threat No
Deciding rule
MEDIUM severity (CVSS 4.0-6.9)
What every action level means
Emergency Immediate action required. Criteria: CRITICAL + in CISA KEV (actively exploited) without patch, OR CRITICAL + EPSS > 30% without patch, OR CRITICAL + active threat signals without patch.
Act Now Prioritize within 24-48h. Criteria: in KEV with patch available, OR CRITICAL + public POC, OR HIGH + EPSS > 10%, OR CRITICAL + active threat, OR any CRITICAL severity.
This Week Schedule remediation this week. Criteria: HIGH severity (CVSS 7.0-8.9). Patch within normal change window.
This Month Plan within 30 days. Criteria: MEDIUM severity (CVSS 4.0-6.9), lower exploitation probability. Include in regular patch cycle.
Monitor Track and reassess. Criteria: LOW severity (CVSS 0.1-3.9), minimal exploitation risk. No immediate action needed.

SSVC AssessmentENISA

SSVC Decision· derived
Scheduled
Exploitation· derived
None
System Exposure· derived
Open
Automatable· derived
No
Human Impact· derived
Medium

Priority Score

26
Low Medium High Critical
KEV: 0
EPSS: 0
CVSS: +26
PoC: 0
Weaponized: 0
Threat intel: 0
Gov advisory: 0

Attack Technique

Cross-Site Scripting occurs when an application accepts untrusted data and sends it to a web browser without proper validation or encoding.

CVE-2024-47875 MEDIUM POC
6.1 Oct 11

DOMPurify is a DOM-only, super-fast, uber-tolerant XSS sanitizer for HTML, MathML and SVG. Rated medium severity (CVSS 6

CVE-2020-26870 MEDIUM POC
6.1 Oct 07

Cure53 DOMPurify before 2.0.17 allows mutation XSS. Rated medium severity (CVSS 6.1), this vulnerability is remotely exp

CVE-2019-16728 MEDIUM POC
6.1 Sep 24

DOMPurify before 2.0.1 allows XSS because of innerHTML mutation XSS (mXSS) for an SVG element or a MATH element, as demo

CVE-2024-48910 CRITICAL
9.8 Oct 31

DOMPurify is a DOM-only, super-fast, uber-tolerant XSS sanitizer for HTML, MathML and SVG. Rated critical severity (CVSS

CVE-2026-65914 MEDIUM POC
5.3 Jul 23

Mutation-XSS in DOMPurify before 3.3.2 enables JavaScript execution in victim browsers when sanitized output is re-inser

CVE-2026-65902 MEDIUM POC
5.3 Jul 23

Hook mutation pollution in DOMPurify <= 3.4.5 allows persistent bypass of HTML sanitization defaults when application-in

CVE-2026-65899 MEDIUM POC
5.1 Jul 23

Trusted Types policy state contamination in DOMPurify 3.0.0-3.4.8 allows a previously supplied TRUSTED_TYPES_POLICY to s

CVE-2026-65913 MEDIUM POC
5.1 Jul 23

Prototype pollution in DOMPurify's USE_PROFILES mode enables DOM-based XSS by causing the sanitizer to accept event hand

CVE-2026-65912 MEDIUM POC
5.1 Jul 23

URI validation bypass in DOMPurify 3.3.1 and earlier allows `javascript:` protocol payloads to survive HTML sanitization

CVE-2026-65900 MEDIUM POC
5.1 Jul 23

SAFE_FOR_TEMPLATES bypass in DOMPurify 3.0.0-3.4.7 allows template expressions such as ${evil}, {{evil}}, and <%evil%> t

CVE-2026-65901 MEDIUM POC
5.1 Jul 23

Cross-site scripting in DOMPurify 3.4.6 and earlier enables script execution when the library's IN_PLACE sanitization mo

CVE-2026-65898 MEDIUM POC
5.1 Jul 23

Stored XSS is achievable in applications using DOMPurify's setConfig() API combined with an uponSanitizeAttribute hook t

Vendor StatusVendor

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy