35

使用<a>标签时,你可能会忽略的一个安全问题

 5 years ago
source link: https://segmentfault.com/a/1190000017840948?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
本文首发于公众号: 符合预期的CoyPan

本文章翻译于: https://medium.com/front-end-weekly/prevent-sending-http-referer-headers-from-your-website-e30eecfe813a

原标题为:Prevent Sending HTTP Referer Headers from Your Website

在一个新窗口中打开链接是前端开发中一个很常见的逻辑,它可以将用户引导到一个新的域名。我们可以用 target='_blank' 来实现这个功能。我敢肯定,每个人都会在他的某个项目中使用过 target='_blank ,但是我不确定是否每个人都知道这种用法的缺陷。

7byA32A.jpg!web

当一个外部链接使用了 target=_blank 的方式,这个外部链接会打开一个新的浏览器tab。此时,新页面会打开,并且和原始页面占用同一个进程。这也意味着,如果这个新页面有任何性能上的问题,比如有一个很高的加载时间,这也将会影响到原始页面的表现。如果你打开的是一个同域的页面,那么你将可以在新页面访问到原始页面的所有内容,包括 document 对象( window.opener.document )。如果你打开的是一个跨域的页面,你虽然无法访问到 document ,但是你依然可以访问到 location 对象。

这意味着,如果你在你的站点或者文章中,嵌入了通过新窗口打开一个新页面的链接,这个新页面可以使用window.opener,在一定程度上来修改原始页面。

可以参考这个例子: https://s.codepen.io/adamlaki/debug/dd4475e9a73052ad37d3e5f19f4bcb92

(笔者这里做了一个小gif,方便大家看上面那个例子的效果)

6fmqMru.gif

我们来看看上面例子发生了什么?当你点击了链接(在打开的 document 中),浏览器会打开这个页面。而这个页面中运行了一段 JavaScript 代码:通过 window.opener 来修改原始页面(你来自的那个页面)。有点乏味但是这可能是有害的。

6V7b6vy.gif

那么问题来了:我们如何阻止这种情况的发生呢?在所有使用 target=_blank 打开新页面的链接上,加上 rel="noopener"

<a href="https://niteshsoni.info" target="_blank" rel="noopener"></a>

使用了 rel=noopener 以后,当一个新页面通过一个链接打开后,新页面中的恶意 JavaScript 代码将无法通过 window.opener  来访问到原始页面。这将保证新页面运行在一个单独的进程里。

在老浏览器中,你可以使用 rel=noreferrer 属性,具有同样的效果。但是,这样也会阻止 Referer header被发送到新页面。

<a href="https://niteshsoni.info" target="_blank" rel="noopener noreferrer"></a>

在上面的例子中,使用了 rel="noreferrer" ,当一个用户点击了这个超链接进入到新页面后,新页面拿不到 referrer 信息。这将意味着,新页面不知道用户是从哪里来的。

如果你通过 JavaScript 中的 window.open 打开一个页面的话,上文所说的都适用,因为你也是打开了一个新的窗口。在这种情况下,你不得不清楚掉 opener 对象:

var newWindow = window.open();
newWindow.opener = null;

在我看来,使用第一种解决方案(在每一个 target="_blank" 的链接中加上 rel="noopener" )是没有什么明显的坏处的。这个问题表明,在你的网页安全性中找到漏洞是多么的容易。

笔者的总结

这是一篇很短的文章,主要介绍了在使用 <a target="_blank"> 标签打开一个新窗口过程中的安全问题。新页面中可以使用 window.opener 来控制原始页面。如果新老页面同域,那么在新页面中可以任意操作原始页面。如果是不同域,新页面中依然可以通过 window.opener.location ,访问到原始页面的 location 对象。

试想一下,你在自己的a页面中,通过 <a target="_blank" href="http://b.com"> 打开新窗口,跳转到了b页面,此刻b页面中有一段代码 window.opener.location = 'http://c.com' 。这是,a页面就会自动跳转到c页面。如果这个c页面是一个和a页面长得一样的钓鱼网站,那么用户可能就中招了。

解决方法就是:在带有 target="_blank"<a> 标签中,加上 rel="noopener" 属性。如果使用 window.open 的方式打开页面,将 opener 对象置为空。这样的副作用是:在某些低版本浏览器中,新页面中拿不到 referer 信息。

写在后面

本文介绍了一种前端开发中容易引发安全问题的情况,问题不大,但是比较容易被忽略。笔者自己也是第一次接触到这个问题 - -。

符合预期。

欢迎关注我的公众号: 符合预期的CoyPan

这里只有干货,符合你的预期

bAbUjyA.png!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK