a标签的rel="noopener"有什么用:HTML超链接安全属性全解析

作者:袖梨 2026-07-22
rel="noopener"必须添加,否则target="_blank"会使新页面通过window.opener劫持原页面,引发Tabnabbing攻击;它强制新页面window.opener为null,彻底切断控制链。

必须加 rel="noopener",否则 target="_blank" 会把原页面控制权交给新页面 —— 这不是推测,是浏览器明确允许的行为。

为什么 target="_blank" 默认危险?

新标签页打开后,它的 window.opener 会直接指向原始页面的 window 对象。这意味着恶意页面可以:

  • window.opener.location.href = "https://fake-login.example" —— 瞬间劫持你原来的标签页
  • window.opener.document.write(...) —— 替换你刚离开的页面内容
  • 即使跨域也生效,不依赖同源策略

这不是理论漏洞,是已知攻击链(Tabnabbing)的标准入口。

rel="noopener" 到底做了什么?

它强制让新页面的 window.openernull,彻底切断双向引用。注意几个关键点:

立即学习“前端免费学习笔记(深入)”;

  • 不是“建议加”,而是现代浏览器对 target="_blank" 的隐式默认行为(但显式声明更可靠)
  • rel="noopener" 不影响 Referer 头,如果还要隐藏来源,得额外加 noreferrer
  • 旧版 Safari(rel="noreferrer" 兼容,但 noreferrer 会同时禁 Referer,不如组合用

推荐写法:<a href="..." target="_blank" rel="noopener noreferrer">

什么时候可以不加?

仅当满足全部条件时才可省略:

  • 链接目标是同域内页面(如 /help/about
  • 你完全信任该页面的 JS 代码(包括所有第三方脚本)
  • 你主动需要在新页中通过 window.opener 回调原页(极少见,且应改用 postMessage

对外链、用户生成内容、CMS 自动生成的链接,一律强制添加 —— 没有例外。

开发者工具里看不到警告?别信

Chrome 和 Firefox 的 DevTools 已不再默认提示缺失 noopener,但这不代表风险消失。Lighthouse 仍会标记,而真实攻击者根本不会等你打开控制台。最容易被忽略的是:

  • Markdown 渲染器自动加 target="_blank" 却不加 rel
  • 富文本编辑器导出的 HTML 没过滤 rel 属性
  • 服务端模板拼接链接时硬编码了 target 却忘了 rel

安全不是“加了就完事”,是每个动态生成链接的环节都得守住这一关。

相关文章

精彩推荐