a标签target=”_blank”的安全问题及解决办法

一、定义

A 标签的 target 属性规定在何处打开链接文档。如果在一个 A 标签内包含一个 target 属性,浏览器将会载入和显示用这个标签的 href 属性命名的、名称与这个目标吻合的框架或者窗口中的文档。如果这个指定名称或 id 的框架或者窗口不存在,浏览器将打开一个新的窗口,给这个窗口一个指定的标记,然后将新的文档载入那个窗口。从此以后,超链接文档就可以指向这个新的窗口。target="_blank"的意思是新的浏览器窗口打开此超链接,但是大多数人都没有注意到这个属性其实是有安全缺陷的,当我们在这样的写的时候一个非常简单的钓鱼攻击的漏洞就这样产生了。

二、原理

熟悉js的朋友都应该知道当我们在调用window下的open方法创建一个新窗口的同时,我们可以获得一个创建窗口的opener句柄,但你也许没注意到,通过target="_blank"点开的窗口活着标签页,子窗口也能捕获opener句柄,通过这个句柄,子窗口可以访问到父窗口的一些属性,虽然很有限,但是我们却可以修改父窗口的页面地址,让父窗口显示指定的页面。

举个例子,在页面a.html中有这样一段代码:

<a href="b.html" target="_blank">跳转</a>;

当我们点击页面a.html中的跳转链接时,浏览器会在新的窗口或标签页中打开b.html,假如这个时候b.html中有这样一段js代码:

if (window.opener) {
	window.opener.location.href = 'eval.html';
}

当页面b.html被打开的同时原来打开a.html的标签页会被重定向到eval.html, eval.html可以是和原来域完全不相关的其它域的资源。

是不是突然有点后怕,其实也不用过分担心,出现这种情况的几率还是比较小的,首先我们自己站内的资源是受信的,能放到站内的其他网站基本也是站长自己加的,当然不排除被黑的情况,那么我们该如何防范呢?

三、防范

如果需要限制window.opener的访问行为,我们只需要在原始页面每个使用了target="_blank"的链接中加上一个rel="noopener"属性。但是,火狐并不支持这个属性值,火狐浏览器里需要写成rel="noreferrer",所以我们可以将两个属性值合并写成rel="noopener noreferrer"来完整覆盖。这样子页面就再也访问不到父页面的句柄了。当然,我们也可以通过js来控制来限制句柄的访问,代码如下:

var otherWindow = window.open();
otherWindow.opener = null;
otherWindow.location = url;

四、总结

在开发中,一些小细节还是要引起注意,别怕麻烦,比如我们以后在写a标签的时候尽量都在target="_blank"后面添加一句 rel="noopener noreferrer"。

  • 支付宝二维码 支付宝
  • 微信二维码 微信

本文地址: /target-blank-problem.html

版权声明: 本文为原创文章,版权归 逐梦个人博客 所有,欢迎分享本文,转载请保留出处!

相关文章