postMessage 跨窗口通信如何防止消息伪造和数据泄露?
先理解原理和示例,再练习完整口述与追问。
回答要点
指定精确 targetOrigin;接收端校验 origin、source 和消息结构;使用请求 ID;不把消息当代码执行;与 CORS 分工不同。
原理拆解
postMessage 允许窗口、iframe 等上下文在受控规则下通信,发送方通过目标窗口引用调用 postMessage(data,targetOrigin)。发送敏感信息时,targetOrigin 应是明确的协议、主机和端口组成的 origin,避免使用 *,因为目标窗口可能已被导航到别的站点。origin 不包含 URL 路径,不能用 startsWith 或模糊子串匹配冒充严格来源校验。
接收方在 message 监听中先比较 event.origin 是否等于预期 origin,再检查 event.source 是否为预期 iframe.contentWindow 或已建立关系的窗口,随后校验消息类型、字段、大小与允许的操作。请求响应要携带不可混淆的 requestId 并设置超时,对敏感动作仍由服务端验证权限。event.data 是不可信输入,不能直接 eval,也不能不经转义插入 innerHTML。
postMessage 解决不同上下文间的消息传递,不等于允许读取任意跨域页面 DOM,也不等于替代接口 CORS。使用沙箱 iframe、弹窗和嵌套页面时,还需考虑不透明来源、窗口关闭、重定向和监听清理。如果无法可靠验证来源或建立安全握手,就不应向该通道发送凭据或执行高权限操作。
参考:MDN postMessage。
示例与推演
父页向支付 iframe 发消息时指定精确 origin;接收回包校验 event.origin、event.source===iframe.contentWindow 和 message.type/requestId。即使来源匹配,也不应允许消息内任意 URL 导航或任意方法执行。页面卸载后移除监听,并使未完成请求超时。
易错点
event.origin 是来源不是完整路径。目标 iframe 后续导航到其他站点时,targetOrigin:* 可能把敏感数据发给新的页面。
参考回答可直接练习口述
postMessage 允许窗口、iframe 等上下文在受控规则下通信,发送方通过目标窗口引用调用 postMessage(data,targetOrigin)。发送敏感信息时,targetOrigin 应是明确的协议、主机和端口组成的 origin,避免使用 *,因为目标窗口可能已被导航到别的站点。origin 不包含 URL 路径,不能用 startsWith 或模糊子串匹配冒充严格来源校验。