背景
柜面项目需内嵌第三方验印控件,通过iframe方式内嵌后,内嵌页面突破iframe跳转顶层页面,导致父页面节点全部被干掉。异常效果图见图一,控制台节点图见图二,正常效果图见图三。
图一
图二
图三
外层父页面window对象与iframe的window对象
每个 iframe 拥有独立的 window:浏览器会将每个 iframe 视为一个独立的浏览上下文(browsing context)。因此,iframe 内部加载的页面拥有自己全新的 window对象,这与外层父页面的 window对象是不同的。
通过属性访问关联对象:虽然 window对象彼此独立,但它们之间存在关联。在 iframe 内的页面中,可以通过 window.parent访问其直接父页面的 window对象,通过 window.top访问最顶层的页面(即浏览器标签页)的 window对象。如果 iframe 内的页面与父页面满足同源策略,还可以进行更多的交互操作。
解决方案
作为外层页面的使用者,对嵌入的 iframe 内容可控度低,核心的防护思路是:阻止 iframe 内的代码操作父页面的浏览上下文。方案有如下几种见图四,因嵌入页是第三方页面且不可控,使用sandbox方案应是最合适的。
图四
沙箱安全机制对照表
图五
配置方案
<iframe
src="https://juejin.cn"
sandbox="allow-same-origin allow-scripts allow-forms"
></iframe>
其他场景配置方案
场景一:嵌入可信度较低的外部页面
<iframe
src="https://external-survey.com"
sandbox="allow-scripts allow-forms"
allow="camera 'none'; microphone 'none'"
></iframe>
场景二:内部跨域子系统通信
<iframe
src="https://internal-tool.yourcompany.com"
sandbox="allow-same-origin allow-scripts allow-forms"
></iframe>
常见踩坑场景
1.误用allow-same-origin导致XSS
<!-- 危险配置! -->
<iframe sandbox="allow-scripts allow-same-origin" src="malicious.com"></iframe>
2.allow-top-navigation引发父页面劫持
<!-- 允许iframe跳转父页面至钓鱼网站 -->
<iframe sandbox="allow-top-navigation" src="attacker.com"></iframe>
总结
- 基础防护:即使只写
sandbox="",也能立刻阻止跳转,提供最高级别的隔离(但可能会破坏第三方页面的部分功能)。 - 推荐做法:根据第三方页面的实际需要,逐步添加必要的权限(如
allow-scripts,allow-forms),但坚决不授予allow-top-navigation。 - 保持警惕:谨慎处理
allow-scripts和allow-same-origin的组合使用。