关于 HTML 中 <a> 标签的 rel 属性应包含 noopener noreferrer 的安全最佳实践

HTML中的<a>标签使用target="_blank"时,存在潜在安全风险。


攻击者可通过新页面的window.opener访问原页面,实施"标签页劫持"攻击,诱导用户输入敏感信息。


建议添加rel="noopener"属性切断两个页面间的联系,防止原页面被篡改。


现代浏览器普遍支持该属性,开发者工具也会提示相关风险。


最佳实践是显式添加rel="noopener noreferrer"以确保安全。


关于 HTML 中 <a> 标签的 rel 属性应包含 noopener 的安全最佳实践


Link 'rel' attribute should include 'noopener'.

Microsoft Edge Toolsdisown-opener If the a element has an href attribute, then it represents a hyperlink (a hypertext anchor) labeled by its contents.

Baseline icon Widely available across major browsers (Baseline since 2015)

上述提到的内容是关于 HTML 中 <a> 标签的 rel 属性应包含 noopener 的安全最佳实践,这是为了防止新打开的页面通过 window.opener 访问原始页面,从而避免潜在的安全风险(如钓鱼攻击或恶意重定向)。


为什么需要 rel="noopener"

当你使用 <a> 标签并设置 target="_blank" 时,新页面可以通过 window.opener 访问原页面的 window 对象。如果原页面未设置 rel="noopener"rel="noreferrer",攻击者可能利用这一点进行"标签页劫持"(Tabnabbing)等攻击。


什么是标签页劫持


标签页劫持(Tabnabbing) 是一种网络钓鱼攻击技术,攻击者利用用户在新标签页中打开链接时的信任心理,诱导用户输入敏感信息。


攻击原理与过程:
  1. 诱导点击 :用户在正常网站(如新闻站、论坛)上点击一个带有 target="_blank" 的链接,该链接在新标签页中打开恶意网站。
  2. 后台篡改
    • 如果原链接没有 设置 rel="noopener",新打开的恶意页面可以通过 JavaScript 访问原页面的 window.opener 对象。
    • 恶意脚本利用这个权限,将原标签页(用户刚才离开的那个页面)重定向到一个伪造的登录界面(例如伪造的 Gmail、银行或公司内网登录页)。
    • 同时,恶意页面可能会让自己进入休眠或显示空白,以降低用户的警惕性。
  3. 用户回切:用户在浏览完新标签页后,习惯性地切换回原来的标签页,想继续之前的操作。
  4. 窃取信息:用户看到原标签页变成了"登录超时"或"会话过期"的提示(实际上是伪造的页面),出于惯性思维,用户会毫不犹豫地输入账号密码。这些信息随即被发送给攻击者。

为什么 rel="noopener" 能防御它?
  • 切断联系 :当 <a> 标签包含 rel="noopener" 时,浏览器会阻止新页面获取 window.opener 对象的引用。
  • 隔离环境:新打开的页面完全无法控制或修改原页面的内容(包括地址栏 URL 和页面 DOM),从而彻底阻断了攻击者篡改原页面进行钓鱼的路径。

简单总结

标签页劫持就是:你点开一个链接去了新页面,坏人趁机把你原来的页面偷偷换成了假登录页,等你切回来时,你以为只是会话过期了,结果把密码输给了坏人。 加上 rel="noopener" 就能给原页面加一把锁,防止被篡改。

正确用法示例

html 复制代码
<a href="https://example.com" target="_blank" rel="noopener">访问示例网站</a>

如果你还希望隐藏来源页面(即不发送 Referer 头),可以同时加上 noreferrer

html 复制代码
<a href="https://example.com" target="_blank" rel="noopener noreferrer">访问示例网站</a>

noreferrer 是 HTML <a> 标签(以及 <area><form> 等)中 rel 属性的一个值,它的核心作用是阻止浏览器在向目标链接发送请求时携带 Referer(来源)头信息

1. 什么是 Referer 头?

通常情况下,当你从页面 A 点击链接跳转到页面 B 时,浏览器会自动在发送给页面 B 的 HTTP 请求头中包含一个 Referer 字段,告诉页面 B:"用户是从页面 A 跳转过来的"。

  • 例子 :如果你在 https://google.com/search?q=秘密 搜索结果中点击了一个外部链接,目标网站通常会知道你是从 Google 搜了什么词跳转过来的。

2. noreferrer 的具体作用

当你在链接中添加 rel="noreferrer" 时:浏览器在发起请求时,不会 发送 Referer 头。目标网站(example.com)将无法知道用户是从哪个页面跳转过来的,它的访问统计工具(如 Google Analytics)会将该流量显示为"直接访问"(Direct Traffic)或"未知来源"。

3. 为什么要使用它?(主要好处)

  • 保护用户隐私
    • 防止目标网站知道你之前浏览的具体页面 URL。
    • 特别重要的是,如果原页面的 URL 中包含敏感信息(如会话令牌 ?token=xyz、搜索关键词、用户 ID 等),使用 noreferrer 可以防止这些敏感数据泄露给第三方网站。
  • 防止反向链接追踪
    • 某些网站通过分析 Referer 来统计是谁链接了它们。如果你不想让目标网站知道是你推荐的流量,可以使用它。

4. 关键的安全副作用:隐含 noopener

这是一个非常重要但常被忽略的特性:
在现代浏览器中,设置 rel="noreferrer" 会自动隐含 rel="noopener" 的行为。

  • 这意味着,如果你写了 rel="noreferrer",即使你没写 noopener,浏览器也会自动切断新页面与旧页面的 window.opener 连接。
  • 结论rel="noreferrer" 既能隐藏来源(隐私),又能防止标签页劫持(安全)。

常见组合用法

为了代码的明确性和最大兼容性,开发者通常同时写上两者:

html 复制代码
<!-- 最佳实践:既明确禁止 opener,又明确禁止 referer -->
<a href="https://external-site.com" target="_blank" rel="noopener noreferrer">
  访问外部网站
</a>
  • 虽然 noreferrer 通常包含了 noopener 的功能,但显式写出 noopener 可以让代码意图更清晰,并兼容极少数可能未将两者绑定的旧版浏览器环境。

总结

属性值 主要功能 安全/隐私影响
noopener 断开新页面与原页面的脚本联系 (window.opener) 防攻击:防止标签页劫持 (Tabnabbing)。
noreferrer 不发送 Referer HTTP 头 防泄露 :保护原页面 URL 隐私(含参数)。 附带安全 :现代浏览器中自动包含 noopener 效果。

如果你只关心安全(防劫持),用 noopener 即可;

如果你既关心安全又想保护隐私(不让对方知道你是从哪来的),就用 noreferrer 或者两者都加。


浏览器支持情况

  • noopener 自 2015 年起已被主流浏览器广泛支持(包括 Chrome、Firefox、Edge、Safari 等)。
  • 现代浏览器在开发者工具中(如 Microsoft Edge DevTools)会提示缺少 noopener 的问题,归类为 "disown-opener" 类型的安全建议。

补充说明

  • 在某些现代浏览器中,即使没有显式设置 rel="noopener",当使用 target="_blank" 时,浏览器也会自动隐含地行为如同设置了 noopener。但为了兼容性和明确性,仍建议显式添加。
  • 对于动态生成的链接(例如通过 JavaScript 创建),也应确保设置相应的 rel 属性。

如需进一步验证或自动化检测此类问题,可以使用 Lighthouse、Microsoft Edge DevTools 或其他静态分析工具。

相关推荐
Irene19913 个月前
Vue 如何避免 XSS 攻击等常见前端安全问题
前端安全
冰镇屎壳郎1 年前
前端安全 常见的攻击类型及防御措施
前端·安全·前端安全
布啦啦李2 年前
「渗透笔记」对某小程序的一次渗透记录
web安全·网络安全·小程序·小程序渗透·小程序挖洞·前端安全