Skip to main content

Validate cross-frame messages

Check the origin and the sender of every postMessage event before you act on it, and send sensitive messages only to an exact target origin.


Embedded apps, theme editor previews, and checkout extensions talk across frames with postMessage. Any frame that can reach yours can send a message, and a loose origin check accepts a lookalike domain.


window.addEventListener('message', (event) => {
if (event.origin !== EXPECTED_ORIGIN) return;
if (event.source !== window.parent) return;

// Validate the message shape and values before acting on it.
});

Compare origins with === against an exact expected value. The following look safe but aren't:

  • origin.includes('shopify.com'), which matches shopify.com.attacker.net.
  • origin.startsWith('https://shopify'), which matches https://shopify-lookalike.net.
  • Checking the message contents and inferring the sender from them.
  • Sending sensitive messages with postMessage(data, '*'), which delivers to whatever is currently in that frame.

The frame that your embedded app runs in needs protection too. Set up iframe protection so that only the authenticated shop's admin can frame your app.


The app security checks confirm the iframe protection headers. No check covers postMessage handlers, so review each one for an exact origin comparison and a sender check.


Was this page helpful?