Attacker
S3
Bypass the regex
This page runs at https://attacker.com.trusted-origin.pmlab.amir.baby. The portal
validates senders with
/^https?:\/\/.*\.trusted-origin\.pmlab\.amir\.baby(:\d+)?$/ —
and that pattern matches this origin, because .* eats
attacker.com on the way to the suffix.
let victimWindow = window.open(victim);
victimWindow.postMessage('<script>alert("ROOTAST")</script>', "https://attacker.com.trusted-origin.com");
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, "https://victim.pmlab.amir.baby"));
One character is the whole bug. In
The origin that actually reaches the portal is this page's real origin,
Note on the target origin. The writeup prints this page's own origin as the target origin. A browser only delivers a postMessage when the target origin matches the receiving window's origin, and the portal is on
^https:\/\/.*\.trusted-origin\.com$ the
.* is meant to stand for “one label”, but it
matches anything — dots included. So
attacker.com.trusted-origin.com satisfies a pattern that
was meant to describe <label>.trusted-origin.com.
The origin that actually reaches the portal is this page's real origin,
https://attacker.com.trusted-origin.pmlab.amir.baby, and it matches the pattern too.
Note on the target origin. The writeup prints this page's own origin as the target origin. A browser only delivers a postMessage when the target origin matches the receiving window's origin, and the portal is on
https://victim.pmlab.amir.baby — so that value goes nowhere.
The target origin is a delivery filter; the receiver's origin check is the
trust decision.
Payload
Ready.
Victim in a frame
The portal runs on https://victim.pmlab.amir.baby.