防御点击劫持的核心是服务端设置Content-Security-Policy响应头的frame-ancestors指令,前端JS、meta标签、样式遮罩等均为无效或兜底手段;frame-ancestors语法错误将导致整条CSP失效,且现代浏览器完全忽略X-Frame-Options和meta标签。

点击劫持不是前端能“写对代码”就防住的
它根本不是 DOM 操作或 JS 逻辑错误,而是 UI 层的视觉欺骗:攻击者用透明 <iframe> 叠在你已登录的页面上,用户点“领券”,实则触发了你银行页的转账按钮。防御核心只有一个——不让你的敏感页被嵌入。所有前端 JS 跳转、meta 标签、内联样式遮罩,都是兜底手段,不能替代服务端响应头。
frame-ancestors 必须由后端设在 HTTP 响应头里
meta 标签写 <meta http-equiv="Content-Security-Policy" content="frame-ancestors 'none';"> 完全无效。Chrome 40+、Firefox 50+、Safari 10.1+ 自 2015 年起已彻底忽略。验证方法很简单:
- 用
curl -I https://yoursite.com/withdraw查响应头,没出现Content-Security-Policy字样,就等于没配 - 本地开发时看似生效?那是 Vite/Webpack Dev Server 自动注入的假象,上线即失效
- 安全扫描工具(如 Mozilla HTTP Observatory)报
Missing frame-ancestors,就是铁证
frame-ancestors 语法错一个字符就全失效
浏览器不会警告,也不会降级,而是直接跳过整条 CSP 指令。常见硬伤:
-
frame-ancestors 'none'✅;frame-ancestors none❌(缺单引号) -
frame-ancestors 'self' https://app.example.com✅;frame-ancestors 'self', https://app.example.com❌(逗号分隔) -
frame-ancestors 'self'/admin❌(路径后缀不支持) -
frame-ancestors 'none'❌(末尾漏分号) - 同时设
X-Frame-Options和frame-ancestors?现代浏览器只认后者,前者被忽略
JS 防御只能作为极端场景的视觉阻断
仅适用于旧版 IE 或沙箱 iframe 绕过 CSP 的情况,不阻止嵌入,只让嵌入后不可交互。必须配合服务端头使用,否则毫无意义:
立即学习“前端免费学习笔记(深入)”;
- 在
<body>开头放一个<div id="frame-guard">,z-index: 9999+visibility: hidden - 紧跟内联脚本:
if (top !== self) document.getElementById('frame-guard').style.visibility = 'visible'; - 该
div可加提示文字或背景色,但别依赖它挡攻击——它只是让用户看到“被套了”,不是技术防护
真正要卡住的,是后端发出来的那个 Content-Security-Policy 响应头。别的都算补丁,这个才是地基。



















