JavaEE单体项目中通过window.postMessage()传递Access Token是否安全?
window.postMessage()本身是浏览器提供的安全跨窗口通信机制,但如果使用不当,确实会存在安全隐患,具体风险和对应的防护措施如下:
核心风险点
未校验消息来源/目标的风险
如果GWT发送消息时使用*作为targetOrigin(允许发送到任意域名),或者Angular接收消息时不校验event.origin是否为可信域名,恶意站点一旦通过XSS或iframe劫持被加载进来,就能直接窃取Access Token。
比如:GWT端如果写iframe.contentWindow.postMessage(token, '*'),token会被发送给任何加载到该iframe的页面,极端危险。iframe被篡改导致的Token泄露
若GWT页面存在XSS漏洞,攻击者可以篡改iframe的src属性,将其替换为恶意站点。此时如果postMessage没有做严格校验,Token会直接发送给恶意站点,进而被用来调用共用的后端API。XSS劫持postMessage流程
不管是GWT还是Angular页面,只要存在XSS漏洞,攻击者都能注入脚本监听或篡改postMessage的内容:比如在GWT端注入脚本劫持要发送的Token,或者在Angular端伪造来自GWT的消息,骗取后端资源访问权限。权限过度分配的次生风险
因为两个应用共用后端API,如果给Angular应用的Token分配了超出其业务需求的权限(比如本来只需要查询权限却给了修改权限),一旦Token泄露,攻击者能造成更大的破坏。
安全实践建议
严格校验Origin
GWT发送消息时必须指定精确的targetOrigin(比如https://your-angular-domain.com),绝对不能用*;Angular接收消息时,要检查event.origin是否在预先定义的可信域名列表中,不符合则直接丢弃消息。
示例代码(Angular端):window.addEventListener('message', (event) => { if (event.origin !== 'https://your-gwt-domain.com') return; // 处理合法消息 });对消息内容做完整性校验
可以给Token附加签名信息(比如用后端约定的密钥对Token和随机串做哈希),Angular接收后先校验签名,确认消息未被篡改后再使用Token。全方位防范XSS
GWT和Angular都要做好输入过滤、输出转义,避免用户可控内容被当作脚本执行;同时启用浏览器的CSP(内容安全策略),限制脚本加载来源,进一步降低XSS风险。遵循最小权限原则
为Angular应用生成Token时,只分配其业务必需的API权限;同时使用短有效期的Access Token,配合Refresh Token(如果需要),缩短Token泄露后的风险窗口。监控异常访问
后端要监控API的异常调用行为,比如来自陌生IP、异常User-Agent的请求,或者超出正常业务频率的调用,及时发现Token泄露后的滥用行为。
内容的提问来源于stack exchange,提问作者user842225

