DOMPurify is vulnerable to mutation-XSS via Re-Contextualization
Date: 2026-03
Affected: npm/dompurify
Attack vector: xss
Category: vulnerability-disclosure
Severity: Medium
CWE: CWE-79

## Description A mutation-XSS (mXSS) condition was confirmed when sanitized HTML is reinserted into a new parsing context using `innerHTML` and special wrappers. The vulnerable wrappers confirmed in browser behavior are `script`, `xmp`, `iframe`, `noembed`, `noframes`, and `noscript`. The payload remains seemingly benign after `DOMPurify.sanitize()`, but mutates during the second parse into executable markup with an event handler, enabling JavaScript execution in the client (`alert(1)` in the PoC). ## Vulnerability The root cause is context switching after sanitization: sanitized output is treated as trusted and concatenated into a wrapper string (for example, `<xmp> ... </xmp>` or other special wrappers) before being reparsed by the browser. In this flow, attacker-controlled text inside an attribute (for example `</xmp>` or equivalent closing sequences for each wrapper) closes the special parsing context early and reintroduces attacker markup (`<img ... onerror=...>`) outside the original attribute context. DOMPurify sanitizes the original parse tree, but the application performs a second parse in a different context, reactivating dangerous tokens (classic mXSS pattern). ## PoC 1. Start the PoC app: ```bash npm install npm start ``` 2. Open `http://localhost:3001`. 3. Set `Wrapper en sink` to `xmp`. 4. Use payload: ```html <img src=x alt="</xmp><img src=x onerror=alert('expoc')>"> ``` 5. Click `Sanitize + Render`. 6. Observe: - `Sanitized response` still contains th


Mitigations:

Architectural layers (MAESTRO):