rel="noopener" 直接使新页面的 window.opener 为 null,从html解析阶段切断引用链,防止跨域劫持重定向;无效写法包括大小写错误、缺失 target="_blank"、空格或用于 window.open() 等。

rel="noopener" 是怎么堵住 window.opener 劫持的
它不是“增强防护”,而是直接让新页面的 window.opener 变成 null,从浏览器解析 HTML 阶段就切断引用链。没这个属性时,哪怕跨域,新标签页也能执行 window.opener.location.href = 'https://phishing.example' 把你的页面无声重定向——TikTok 2023 年真实被利用过。
关键点:这个行为不依赖同源策略,也不需要 XSS 漏洞,纯靠浏览器默认机制。加了 rel="noopener" 后,新页面再调用 window.opener 得到的就是 null,任何读写操作都会报错或静默失败。
哪些地方写了也白写,根本不起作用
常见无效写法,实际部署中高频出现:
-
rel="NOOPENER"或rel="no-opener":必须全小写、无连字符,否则浏览器忽略 - 只写
rel="noopener"却没配target="_blank":属性存在但不触发 opener 隔离逻辑 - 在
target="_self"或target="_parent"上硬塞rel="noopener":既不防劫持,也不影响 Referer -
rel="noopener noreferrer "末尾带空格:HTML 属性值按空格分隔,多出的空格会让整个值失效
window.open() 场景下 rel 属性完全无效
rel 是 HTML 属性,对 JavaScript 主动开窗不起作用。下面这些写法都是错的:
-
window.open(url, '_blank', 'noopener'):noopener不是合法的features字符串参数 -
window.open(url, '_blank'):默认保留window.opener引用,高危
正确做法只有两种:
- 同步断开:
const w = window.open(url, '_blank'); if (w) w.opener = null; - 兼容性兜底(仅限同源):
window.open(url, '_blank', 'noopener=yes'),但 Chrome/Edge 才支持,Safari/Firefox 忽略
服务端和富文本才是漏洞高发区
手写 HTML 容易补全,但真实风险集中在动态生成环节:
- CKEditor、TinyMCE 等富文本编辑器自动给外链加
target="_blank",却从不补rel - 评论区自动识别 URL 渲染为链接,
v-html或dangerouslySetInnerHTML直接输出,没做清洗 - 服务端模板拼接链接时写死
target="_blank",但rel被漏掉或覆盖 - 已有
rel="nofollow"的链接,直接替换成rel="noopener",丢失原有语义
最稳妥的做法是在服务端输出前统一正则匹配:<a>]*target=["']_blank["'][^>]*>(?!</a>rel=["']noopener["']),再注入 rel="noopener noreferrer";注意保留已存在的其他 rel 值,用空格合并。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











