Attacker
S1
Inject through the wildcard listener
The portal listens for messages from anyone and writes them into the DOM as HTML.
Because it never checks event.origin, a page on
any origin can post a payload to it.
let victimWindow = window.opene(victimSite);
victimWindow.postMessage('<script>alert("ROOTAST")</script>', "*");
const victimWindow = window.open(VICTIM_URL);
// post when the portal has loaded — a message posted to a window that is
// still loading is delivered to the blank document and lost
victimWindow.addEventListener("load", () => victimWindow.postMessage(PAYLOAD, "*"));
The target origin is
"*" on both sides.
On the sending side it means “deliver this to whatever origin the receiver has”;
on the receiving side, no check means “accept this from whoever sent it”.
Neither half of the handshake is checked, so cross-origin is not a barrier.
Pick a payload
Ready.
Captured from the victim
The payload below is served by the victim's origin, so it can reach the victim's cookie. Anything arriving here was stolen from the portal.
— nothing yet —
Victim in a frame
The portal runs on https://victim.pmlab.amir.baby.