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.opener 为 null,彻底切断双向引用。注意几个关键点:
立即学习“前端免费学习笔记(深入)”;
target="_blank" 的隐式默认行为(但显式声明更可靠)rel="noopener" 不影响 Referer 头,如果还要隐藏来源,得额外加 noreferrer
noreferrer 会同时禁 Referer,不如组合用推荐写法:<a href="..." target="_blank" rel="noopener noreferrer">
仅当满足全部条件时才可省略:
/help、/about)window.opener 回调原页(极少见,且应改用 postMessage)对外链、用户生成内容、CMS 自动生成的链接,一律强制添加 —— 没有例外。
Chrome 和 Firefox 的 DevTools 已不再默认提示缺失 noopener,但这不代表风险消失。Lighthouse 仍会标记,而真实攻击者根本不会等你打开控制台。最容易被忽略的是:
target="_blank" 却不加 rel
rel 属性target 却忘了 rel
安全不是“加了就完事”,是每个动态生成链接的环节都得守住这一关。