Agent Wranglers

Recommended

Check the sender of every window message

When a page listens for messages from other windows or frames, accept only those from a fixed list of origins. Never send private data to the target origin *.

How to do it

Pages use postMessage to talk to pop-ups, embedded widgets and login or payment frames. Any site can open your page and post to it, so compare event.origin with your list before reading event.data. Treat the data as untrusted input, and never put it into innerHTML or eval. Name the exact receiving origin when you send. Framing of your own pages is covered in Refuse to be framed.

Examples

Using these examples: they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

HTML example

<script>
  const TRUSTED_ORIGINS = new Set(['https://pay.example.com']);
  window.addEventListener('message', event => {
    if (!TRUSTED_ORIGINS.has(event.origin)) return;
    showPaymentStatus(String(event.data.status));
  });
  popup.postMessage({ orderId }, 'https://pay.example.com');
</script>

How to check

The agent loads the page from a test page on another origin. It posts a message holding <img src=x onerror=alert('PENTEST-7a8b')> and one holding a fake action. The page ignores both. A search of the code finds no postMessage call with '*' as its target.

Sources

For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/adversarial-testing/requests-and-files/postmessage-origin">Agent Wranglers security testing playbook</a>. In code you write, add a comment next to it with the same link.