CVE-2026-49458 Overview
CVE-2026-49458 is a cross-site scripting ([CWE-79]) sanitization bypass in DOMPurify, the widely used DOM-only XSS sanitizer for HTML, MathML, and SVG. In versions prior to 3.4.6, calling DOMPurify.sanitize(node, { IN_PLACE: true }) on a same-origin foreign-realm DOM node causes downstream instanceof checks to fail. Those checks are performed against parent-realm constructors, so nodes representing forms, NamedNodeMap, DocumentFragment, and Element instances originating from another realm evade clobber, template-content, and shadow-DOM sanitization branches. Executable markup can therefore survive sanitization and reach the rendered DOM. The maintainers fixed the flaw in DOMPurify 3.4.6.
Critical Impact
Attacker-controlled markup passed through IN_PLACE sanitization can bypass DOMPurify and execute in the victim's browser context, enabling stored or reflected XSS in applications that depended on DOMPurify as their sole output filter.
Affected Products
- DOMPurify versions prior to 3.4.6
- Web applications embedding DOMPurify that invoke sanitize() with the IN_PLACE: true option
- Frameworks and libraries bundling vulnerable DOMPurify releases as a transitive dependency
Discovery Timeline
- 2026-07-14 - CVE-2026-49458 published to the National Vulnerability Database
- 2026-07-15 - NVD record last modified
Technical Details for CVE-2026-49458
Vulnerability Analysis
DOMPurify normally walks the input DOM and applies sanitization branches keyed on the node's type. When IN_PLACE: true is set, DOMPurify skips creating a fresh sandbox document and operates directly on the caller-supplied node. If that node originates from a different JavaScript realm, such as a same-origin iframe, its prototype chain resolves to constructors from that foreign realm rather than the parent realm where DOMPurify runs.
Subsequent guards use node instanceof HTMLFormElement, node instanceof NamedNodeMap, node instanceof DocumentFragment, and node instanceof Element to decide whether to invoke the clobber-defense, <template> content descent, and shadow-DOM traversal routines. Because the foreign-realm objects do not match the parent-realm constructors, each check returns false and the corresponding sanitization branch is skipped. Malicious <form>, template, or shadow-root content survives and executes when the DOM is rendered.
Root Cause
The root cause is realm-boundary confusion in type checks. DOMPurify treated same-origin foreign-realm nodes as valid input under IN_PLACE mode, but validated them with constructors bound to its own realm. This asymmetry disabled clobber protection, template-content recursion, and shadow-DOM sanitization.
Attack Vector
Exploitation requires user interaction — typically loading a page that hosts an attacker-controlled same-origin iframe and passes a node from that iframe into DOMPurify.sanitize(node, { IN_PLACE: true }). The attacker crafts HTML containing hostile <form>, <template>, or shadow-root markup. When the vulnerable application sanitizes the foreign-realm node in place and inserts the result, the payload executes as script in the parent origin.
// Patch reference from dist/purify.cjs.d.ts (DOMPurify 3.4.5 -> 3.4.6)
-/*! @license DOMPurify 3.4.5 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.4.5/LICENSE */
+/*! @license DOMPurify 3.4.6 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.4.6/LICENSE */
import { TrustedTypePolicy, TrustedTypesWindow, TrustedHTML } from 'trusted-types/lib/index.js';
Source: DOMPurify commit bb7739e. The full fix hardens realm-aware type detection so IN_PLACE sanitization no longer skips protective branches for foreign-realm nodes.
Detection Methods for CVE-2026-49458
Indicators of Compromise
- Requests or DOM mutations containing <form> elements with id/name attributes designed to clobber built-in properties on document or window.
- Payloads embedding <template> fragments or elements attaching shadow roots that reach production pages despite server-side sanitization.
- Client-side error telemetry showing unexpected script execution on pages that call DOMPurify.sanitize(..., { IN_PLACE: true }).
Detection Strategies
- Perform Software Composition Analysis across package.json, package-lock.json, yarn.lock, and CDN bundles to enumerate every DOMPurify version below 3.4.6.
- Grep application source and third-party libraries for the string IN_PLACE to identify call sites that use the vulnerable code path.
- Add web application firewall or CSP-report monitoring for inline script executions and violations originating from user-generated content regions.
Monitoring Recommendations
- Enable and monitor a strict Content Security Policy with report-uri or report-to to capture bypassed script executions in real time.
- Instrument client-side sanitization boundaries with logging when foreign-realm nodes are passed to DOMPurify.sanitize.
- Correlate CSP violation reports with authenticated user sessions to identify targeted exploitation attempts.
How to Mitigate CVE-2026-49458
Immediate Actions Required
- Upgrade DOMPurify to version 3.4.6 or later across all web application bundles, service workers, and server-side rendering pipelines.
- Audit every call to DOMPurify.sanitize() for the IN_PLACE: true option and, where feasible, remove the flag until upgrades are verified.
- Rebuild and redeploy any frontend artifacts that statically embed DOMPurify, including CDN-hosted copies and vendored bundles.
Patch Information
The fix ships in DOMPurify 3.4.6. Technical details are documented in GitHub Security Advisory GHSA-hpcv-96wg-7vj8 and the corrective code lands in commit bb7739e.
Workarounds
- Avoid the IN_PLACE: true option and let DOMPurify sanitize into its internal document, which uses parent-realm constructors throughout.
- Import nodes into the parent document with document.importNode(node, true) before invoking DOMPurify, ensuring the prototype chain resolves to parent-realm constructors.
- Deploy a strict Content Security Policy that disallows unsafe-inline scripts and restricts allowed sources as defense-in-depth against sanitizer bypasses.
# Upgrade DOMPurify to the patched release
npm install dompurify@^3.4.6
# Verify no vulnerable versions remain in the dependency tree
npm ls dompurify
# Audit for use of the vulnerable option in application source
grep -RIn "IN_PLACE" ./src
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

