Safeguard
Security Guides•

postMessage security: check origin on receive, name it on send

Cross-window messaging is safe only with an exact targetOrigin when sending and an event.origin check when receiving. The rules and a minimal example.

Safeguard Security Team
3 min read

window.postMessage lets pages, popups and iframes talk across origins. Two rules keep it safe. When sending, give an exact targetOrigin instead of the star. When receiving, check event.origin and event.source, then validate the message shape before acting on it.

The sender side

The second argument to postMessage is the target origin. If you pass a specific origin, the browser delivers the message only if the receiving window has that origin at that moment.

If you use the star, anyone who controls the window you hold a reference to can read the data. MDN notes that a malicious site can navigate that window without your knowledge. Never send credentials or tokens with the star. If you omit the argument, the default is your own origin, so delivery only reaches same-origin recipients.

MDN lists exceptions where you must use the star, such as data URLs and file URLs. Treat those destinations as low trust.

The receiver side

Any window in the frame hierarchy can send you a message. Without a check, you will act on messages from sites you never meant to talk to.

window.addEventListener("message", (event) => {
  if (event.origin !== "https://app.example.com") return;
  if (event.source !== window.opener) return;
  if (typeof event.data !== "object" || event.data.type !== "auth-request") return;
  // handle the message
});

Compare against an exact origin string. Avoid substring or endsWith checks, which attackers can satisfy with lookalike domains. MDN adds that IDN hosts can appear in Unicode or punycode form, so check both when it applies.

If you do not expect cross-site messages at all, do not register a listener.

Validate the content too

A verified origin does not make the content safe. If the sender is compromised, its messages are attacker input. Validate type and fields, and never pass the data to innerHTML, eval or a navigation. Treat it as untrusted, like any request body.

For related DOM sinks see innerHTML vs textContent.

Pitfalls

  • event.origin shows the origin at send time. The sender may have navigated since.
  • Embedded third-party widgets often use postMessage. Review which origins your page accepts and which it sends to.
  • Do not send secrets just because the frame is yours today. Use the exact origin anyway.

Quick check

Is a wildcard targetOrigin ever fine?

Only for non-sensitive data, or the documented cases such as data and file URLs. If you know the recipient, name its origin.

Do I still need CSP?

Yes. A Content Security Policy limits damage if a message handler is abused.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.