You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
My name is Oscar Uribe, Security Researcher at Fluid Attacks. I am writing to inform you that Camilo Vera and Cristian Vargas, from the Fluid Attacks Research Team, have identified a mXSS via Re-Contextualization in DomPurify 3.3.1.
This vulnerability has been rated with a severity of 6.9 (Medium), according to the CVSS 4.0.
We have reserved the CVE-2026-3126 ID to refer to this security issue from now on. Following our Disclosure Policy, if this report corresponds to a vulnerability and the conditions outlined in our policy are met, this advisory will be published on our website over the next few days (the timeline may vary depending on your willingness to attend to and respond to this report) at the following URL: https://fluidattacks.com/advisories/daft
We would appreciate it if you could acknowledge Camilo Vera and Cristian Vargas in the GitHub Security Advisory.
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).
This is a mutation-XSS pattern caused by a parse-context mismatch:
Parse 1 (sanitization phase): input is interpreted under normal HTML parsing rules.
Parse 2 (sink phase): sanitized output is embedded into a wrapper that changes parser state (xmp raw-text behavior).
Attacker-controlled sequence (</xmp>) gains structural meaning in parse 2 and alters DOM structure.
Sanitization is not a universal guarantee across all future parsing contexts. The sink design reintroduces risk.
Remediation Guidance
Do not concatenate sanitized strings into new HTML wrappers followed by innerHTML.
Keep the rendering context stable from sanitize to sink.
Prefer DOM-safe APIs (textContent, createElement, setAttribute) over string-based HTML composition.
If HTML insertion is required, sanitize as close as possible to final insertion context and avoid wrapper constructs with raw-text semantics (xmp, script, etc.).
Add regression tests for context-switch/mXSS payloads (including </xmp>, </noscript>, similar parser-breakout markers).
Our security policy
We have reserved the CVE-2026-3126 ID to refer to this issue from now on.
The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
Learn more on MITRE.
My name is Oscar Uribe, Security Researcher at Fluid Attacks. I am writing to inform you that Camilo Vera and Cristian Vargas, from the Fluid Attacks Research Team, have identified a mXSS via Re-Contextualization in DomPurify 3.3.1.
This vulnerability has been rated with a severity of 6.9 (Medium), according to the CVSS 4.0.
We have reserved the CVE-2026-3126 ID to refer to this security issue from now on. Following our Disclosure Policy, if this report corresponds to a vulnerability and the conditions outlined in our policy are met, this advisory will be published on our website over the next few days (the timeline may vary depending on your willingness to attend to and respond to this report) at the following URL: https://fluidattacks.com/advisories/daft
We would appreciate it if you could acknowledge Camilo Vera and Cristian Vargas in the GitHub Security Advisory.
Description
A mutation-XSS (mXSS) condition was confirmed when sanitized HTML is reinserted into a new parsing context using
innerHTMLand special wrappers. The vulnerable wrappers confirmed in browser behavior arescript,xmp,iframe,noembed,noframes, andnoscript. The payload remains seemingly benign afterDOMPurify.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
http://localhost:3001.Wrapper en sinktoxmp.Sanitize + Render.Sanitized responsestill contains the</xmp>sequence insidealt.<img src="x" onerror="alert('expoc')">.alert('expoc')is triggered.{ "name": "expoc", "version": "1.0.0", "main": "server.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "node server.js", "dev": "node server.js" }, "keywords": [], "author": "", "license": "ISC", "description": "", "dependencies": { "dompurify": "^3.3.1", "express": "^5.2.1", "jsdom": "^28.1.0" } }Evidence
daft-video.webm
Why This Happens
This is a mutation-XSS pattern caused by a parse-context mismatch:
xmpraw-text behavior).</xmp>) gains structural meaning in parse 2 and alters DOM structure.Sanitization is not a universal guarantee across all future parsing contexts. The sink design reintroduces risk.
Remediation Guidance
innerHTML.textContent,createElement,setAttribute) over string-based HTML composition.xmp,script, etc.).</xmp>,</noscript>, similar parser-breakout markers).Our security policy
We have reserved the CVE-2026-3126 ID to refer to this issue from now on.