e.origin to https://frames.example-app.com — equality, character for character — before anything renders. Our-origin parent (this page) is not that origin ⇒ "you're not allowed to send from here — origin was: https://stuxnet.pro". Protection working as designed: the check values the browser's attested sender origin, not anything the sender claims in a payload.event.origin comparison is the strict invocation; developers who write it by pattern (below) lose the guarantee./^(https?):\/\/[a-z]+\.stuxnet\.pro/ — "starts with http(s) then any subdomain of stuxnet.pro". This page's parent (stuxnet.pro) matches trivially — press Run and the message renders.$ anchor, so anything at the end still matches. https://sub.stuxnet.pro glows… and so does https://sub.stuxnet.pro.evil.test. Take the pattern to regex101.com yourself — the lesson's exact drill — and watch the glow that shouldn't be there.evil.test in ours), host a page, embed the victim frame, and post from an origin that pattern-matches. Then the receiver renders — and the payload executes inside the victim site's document. Framework habit identical to the CORS lab's: your host merely contains the trusted string./^(https?):\/\/[a-z]+.stuxnet.pro$/) and . means any character — borderline cousins like subXstuxnet.pro pattern-match. Escape the dots, or better, compare strings, not patterns.targetOrigin (next lab) others forget entirely. Both must hold for the bridge to be safe.Fineprint on the pattern itself: even the "corrected" anchored pattern rejects the apex https://stuxnet.pro (nothing matches [a-z]+. before it) — exactly the kind of breakage real apps routinely bow to by loosening the pattern again. Protection code that has no tests develops soft spots like this.
<!-- host at https://x.stuxnet.pro.evil.test/ — the name is the exploit -->
<iframe src="https://stuxnet.pro/pm/lab30/frame.html?level=2" id="f"></iframe>
<script>
const f = document.getElementById('f');
setTimeout(() => f.contentWindow.postMessage(
{message: '<img src=x onerror=alert(document.domain)>'}, '*'), 800);
</script>
The frame's check pattern-matches our page's origin (x.stuxnet.pro.evil.test contains [a-z]+.stuxnet.pro) so the payload renders — and the alert's domain is stuxnet.pro's: execution happened in the victim app's frame, not ours. That origin-scoped-but-victim-executed result is the same shape as any worrying framed submission reported, only now carried inside the sanctioned bridge.
hunt: grep for addEventListener('message' → every finding is a channel
who checks e.origin? → none: Lab 29 shape. too loose: Lab 30 L2 (regex cracks)
who renders e.data? → innerHTML / document.write = sink (Lab 29)
sender half? grep postMessage\( → does IT pin a targetOrigin? (Lab 31)
The source view lesson from the evasion set applies verbatim: read the receiver's listen block first, then the sender's post block — one line each usually shows whether trust is claimed or given. (Our classroom limits: postMessage moves in the browser, so the two curls that proved CORS don't apply here — the POC is a hosted page, exactly like the attacker framing we just showed.)
Who's allowed to talk?
postMessage