DOMPurify: IN_PLACE mode preserves attributes of a clobbered root element, allowing XSS via attacker-controlled root DOM
Date: 2026-06
Affected: npm/dompurify
Attack vector: xss
Category: vulnerability-disclosure
Severity: Medium
CVE: CVE-2026-49459
CWE: CWE-1321
CWE-693
CWE-79
CVSS: 6.1 (CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N)

# IN_PLACE mode preserves attributes of a clobbered root element, allowing XSS via attacker-controlled root DOM **CWE**: CWE-79 (XSS — Improper Neutralization of Input During Web Page Generation) via CWE-693 (Protection Mechanism Failure — silent no-op when `_forceRemove` is called on a parent-less node) ## Summary When `DOMPurify.sanitize(root, { IN_PLACE: true })` is called and `root` is a `<form>` whose own attributes carry an event handler (`onmouseover`, `onfocus`, `onclick`, etc.), a single descendant element with a `name=` attribute matching any of the property names `_isClobbered` checks (`nodeName`, `setAttribute`, `namespaceURI`, `insertBefore`, `hasChildNodes`, `childNodes`) is sufficient to bypass attribute sanitization on the root. `_forceRemove` silently no-ops because the root has no parent; the iterator drives on to `_sanitizeAttributes`, which early-returns on clobbered nodes — and the event handler attribute is never inspected. The sanitized return is the same root, with the handler live. This affects current `main` at `89da34e` (the just-landed DOM-clobbering hardening fix at `89da34e` addressed `_sanitizeAttachedShadowRoots` walk traversal, **not** the main `_sanitizeElements` / `_sanitizeAttributes` pipeline against the iterator-root node). ## Affected - DOMPurify ≤ 3.4.5, including `main` at `89da34e03ec17868e561f87f3747a9371b61a9e7` - Any caller that does `DOMPurify.sanitize(node, { IN_PLACE: true })` where `node` is built from untrusted HTML (e.g


Mitigations:

Architectural layers (MAESTRO):