Glossary
postMessage (window.postMessage)
The sanctioned way for a page and an iframe from another origin to talk. postMessage sends a message across the same-origin boundary; the origin checks on both ends are what keep it safe.
General definition
postMessage (window.postMessage) is defined in the HTML Living Standard. The same-origin policy stops a page from reading or scripting a frame served from a different origin, which is exactly the situation an embedded widget is in. targetWindow.postMessage(message, targetOrigin) delivers a structured-cloneable message to the other window, which receives it as a message event carrying data, origin and source. The same mechanism works between a page and a popup, between a page and a Web Worker, and between service workers and their clients.
- Sender: always pass an explicit
targetOriginsuch ashttps://widget.example.com; the wildcard*means any page that ends up in that window can read the message - Receiver: check
event.originagainst an allow-list before acting onevent.data, and validate the payload shape too - Reply: use
event.source.postMessage()with the origin you validated, or aMessageChannelport for a private two-way channel - Payload: send plain objects, never strings to be evaluated, and version the message schema so widget and host can be updated separately
Most postMessage vulnerabilities are one of two mistakes: a receiver that skips the origin check and does something dangerous with the data (writes it into the DOM, calls a privileged function, stores a token), or a sender that broadcasts sensitive data with a wildcard target. Security scanners flag both. A well-designed widget protocol keeps the message set small (open, close, resize, identify user, event callback), treats every inbound message as untrusted input, and never passes secrets through the page at all when a server-side call would do.
For embedded chat this is the glue between the launcher on the host page and the conversation in the iframe: the launcher tells the frame to open, the frame tells the page its height, the page passes a signed user token so the conversation is attributed, and the frame reports events back. A webhook covers the server-to-server half of the same integration.
In the Ethora ecosystem
Ethora’s embeddable AI assistant widget is iframe based: the assistant.js script tag with a data-app-id creates a frame that runs the assistant on Ethora’s origin, separate from the host page. That is the design in which postMessage belongs: the loader on the page and the frame need to coordinate opening, closing and sizing without either side being able to script the other, and the browser’s same-origin policy keeps the conversation, its storage and its tokens out of reach of the host page’s scripts. See the chat widget and Shadow DOM entries for the isolation options.
When the host is your own application, the React chat component and the chat widget SDK run in-page and talk to the Ethora backend directly with short-lived JWT chat tokens and API-provisioned users, so there is no cross-origin boundary to bridge. Server-side integration, such as forwarding Trust and Safety reports to your systems, goes through the API, message bus or email rather than the browser.