SafePaste
Challenge
A paste site with an admin bot and DOMPurify in the mix. I burned time chasing DOMPurify CVEs before realizing the bug was in how the server vs the browser parse the input, a mutation XSS.
Solution
Breakout via replace patterns. The server ran a String.prototype.replace over the input, and the special replacement patterns ($` and $&) let me smuggle markup past the sanitizer’s view of the string. With tab entities (	) as attribute separators, I could inject a live element:
| |
The cookie scope trick. The flag cookie was scoped to /hidden, and visiting /hidden redirects to about:blank (cross-origin), destroying the context before you can read it. But the cookie attaches to any path matching the /hidden scope, so sending the bot to /hidden/<anything> (which 404s but keeps the cookie) and loading that in a same-origin iframe lets the parent read frames[1].document.cookie. Then a form POST exfiltrates it:
| |
Because the iframe is same origin with the parent, the parent reads its cookie, and the 404 page under /hidden still carries it.