Bypassing DOMPurify with mXSS

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>&lt;/title&gt;&lt;img src=1 onerror=alert(1)&gt;

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>&amp;lt;/title&amp;gt;&amp;lt;img src=1 onerror=alert(1)&amp;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.

Comments are closed :( too much spam. If you want to contact me about any article please email or tweet me.