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.