Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-49459

CVE-2026-49459: DOMPurify XSS Vulnerability

CVE-2026-49459 is a cross-site scripting vulnerability in DOMPurify that allows attackers to bypass sanitization via DOM clobbering. This article covers the technical details, affected versions, security impact, and mitigation.

Published:

CVE-2026-49459 Overview

CVE-2026-49459 is a cross-site scripting (XSS) sanitizer bypass in DOMPurify, a widely used DOM-only sanitizer for HTML, MathML, and SVG. Versions prior to 3.4.6 fail to strip event-handler attributes when DOMPurify.sanitize(root, { IN_PLACE: true }) is invoked on an attacker-controlled <form> root. A descendant element with a name attribute can clobber properties checked by the internal _isClobbered function, causing _forceRemove to no-op on the parent-less root and _sanitizeAttributes to return early. The flaw is tracked under CWE-79 and is fixed in DOMPurify 3.4.6.

Critical Impact

Attackers can smuggle event-handler attributes past DOMPurify sanitization to execute arbitrary JavaScript in the victim's browser session.

Affected Products

  • DOMPurify versions prior to 3.4.6
  • Applications using DOMPurify.sanitize() with the IN_PLACE: true option on untrusted roots
  • Web applications embedding DOMPurify as a client-side XSS defense for user-supplied HTML

Discovery Timeline

  • 2026-07-14 - CVE-2026-49459 published to NVD
  • 2026-07-15 - Last updated in NVD database
  • DOMPurify 3.4.6 - Cure53 releases patched version resolving the sanitizer bypass

Technical Details for CVE-2026-49459

Vulnerability Analysis

DOMPurify sanitizes DOM trees by walking nodes and calling _sanitizeAttributes to strip disallowed attributes such as onclick, onerror, and other event handlers. Before removing a hostile node, the library invokes _forceRemove, which detaches the element from its parent. When IN_PLACE: true is used, the caller passes an existing DOM node as the sanitization root. That root has no parent by design in this mode.

The bypass chains two internal weaknesses. First, _forceRemove no-ops when the target element has no parent, so the root itself is never removed even if it should be. Second, _isClobbered protects DOMPurify against DOM clobbering by verifying that critical properties on the node reference the expected native functions. A descendant element named to shadow those properties returns true from _isClobbered, causing _sanitizeAttributes to return early without stripping event handlers on the root.

Combined, an attacker who controls the root <form> element and one of its descendants preserves attributes like onfocus or onmouseover on the form, resulting in stored or reflected XSS despite sanitization.

Root Cause

The root cause is an unsafe interaction between IN_PLACE mode handling and DOM clobbering defenses. _sanitizeAttributes treats a clobbered node as unsafe and bails out early instead of forcibly stripping attributes, while _forceRemove cannot delete a parent-less root. The sanitizer therefore leaves attacker-controlled event handlers in place [CWE-79].

Attack Vector

Exploitation requires user interaction, such as loading a page or interacting with a form field bound to an event handler. An attacker crafts a <form> containing a descendant whose name attribute clobbers a property referenced by _isClobbered (for example, attributes or nodeName). The attacker adds an event-handler attribute to the form root. When the application invokes DOMPurify.sanitize(form, { IN_PLACE: true }), the sanitizer preserves the handler, and the payload fires when the user interacts with the form.

typescript
// Patch metadata from DOMPurify 3.4.6 release
-/*! @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

Detection Methods for CVE-2026-49459

Indicators of Compromise

  • HTML payloads containing a <form> element with event-handler attributes such as onfocus, onmouseover, or onclick combined with descendants whose name attributes match DOM properties like attributes, nodeName, or children.
  • Application logs or CSP violation reports showing inline script execution originating from sanitized user-generated content.
  • Client-side error telemetry indicating unexpected property shadowing on form elements passed to DOMPurify.

Detection Strategies

  • Perform a Software Composition Analysis (SCA) scan of front-end dependencies and lockfiles (package-lock.json, yarn.lock, pnpm-lock.yaml) for DOMPurify versions below 3.4.6.
  • Grep repositories for IN_PLACE: true usage and audit callers to confirm the root node is not attacker-controlled.
  • Deploy a strict Content Security Policy (CSP) that blocks inline event handlers and monitor report-uri endpoints for violations that indicate a sanitizer bypass in production.

Monitoring Recommendations

  • Instrument client-side sanitization calls with logging that records the tag name and attribute set of the root node passed to DOMPurify.
  • Alert on CSP script-src violations tied to pages that render user-supplied HTML.
  • Track browser telemetry for unusual event-handler activation on <form> elements within untrusted content regions.

How to Mitigate CVE-2026-49459

Immediate Actions Required

  • Upgrade DOMPurify to version 3.4.6 or later across all applications and bundled artifacts.
  • Rebuild and redeploy front-end bundles so cached copies of vulnerable DOMPurify are evicted from CDNs and service workers.
  • Audit every call site using IN_PLACE: true and validate that the supplied root is trusted or freshly cloned.

Patch Information

The fix ships in DOMPurify Release 3.4.6 via commit bb7739e. Full advisory details are published in GHSA-r47g-fvhr-h676.

Workarounds

  • Avoid the IN_PLACE: true option and instead pass the HTML string to DOMPurify.sanitize() so the library operates on a detached template document.
  • Reject or pre-strip <form> elements from untrusted HTML before sanitization until the patched version is deployed.
  • Enforce a strict CSP with script-src 'self' and no 'unsafe-inline' to blunt the impact of inline event-handler execution.
bash
# Upgrade DOMPurify to the patched release
npm install dompurify@^3.4.6

# Verify the resolved version in the lockfile
npm ls dompurify

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.