点击劫持
约 3 分钟阅读
最后更新: 2026-09-01
什么是点击劫持
点击劫持 (Clickjacking) 是一种使用透明或不可见的 iframe 将合法网页覆盖在用户屏幕上,诱导用户进行非预期点击操作的攻击手法。将其他内容覆盖在可见 UI 之上、使用户产生错觉的攻击统称为 UI Redressing (UI 伪装),点击劫持是其中的代表。
攻击者创建一个陷阱页面,并在其上方用透明的 iframe 覆盖目标站点。用户看到的是陷阱页面的按钮和链接,但实际点击的是透明 iframe 中目标站点的元素。这样,用户在不知情的情况下就会执行「点赞」、设置变更、转账确认等操作。
攻击原理与手法
点击劫持按以下步骤执行。
- 攻击者创建陷阱网页,放置有吸引力的内容 (视频播放按钮、游戏、抽奖表单等)
- 通过
iframe加载目标站点,并用 CSS 设置opacity: 0(完全透明) - 将透明 iframe 精确覆盖在陷阱页面的可点击元素上方
- 用户点击陷阱页面的按钮时,实际点击的是透明 iframe 中目标站点的按钮
进阶手法
- 拖放利用:利用用户的拖动操作向透明 iframe 中的表单输入数据
- 光标显示的伪装:通过 CSS 替换或隐藏光标图像,使看到的光标位置与实际的点击位置产生偏移,让用户点击非预期的位置
- 多步攻击:诱导多次点击,甚至让用户点击确认对话框的「确定」按钮
防御措施的实现
点击劫持防御的核心是防止本站被其他站点的 iframe 嵌入。
CSP frame-ancestors 指令
CSP 的 frame-ancestors 指令控制哪些父页面源可以将本站嵌入 iframe。它在 CSP Level 2 中作为 X-Frame-Options 的后继被引入,CSP 规范规定:两者同时指定时,应用 frame-ancestors 并忽略 X-Frame-Options。如果现在开始配置,应以它为基准。
frame-ancestors 'none':不允许任何站点通过 iframe 嵌入frame-ancestors 'self':仅允许同源的嵌入frame-ancestors https://trusted.example.com:仅允许特定源的嵌入
X-Frame-Options 头
2009 年至 2010 年间由各浏览器厂商作为非标准头引入,并于 2013 年被整理为 RFC 7034 (Informational) 的防御措施。实际使用的值有以下两个。
X-Frame-Options: DENY:拒绝所有 iframe 嵌入X-Frame-Options: SAMEORIGIN:仅允许同源的嵌入
规范中还有第三个值 ALLOW-FROM <URI>,但它在主要浏览器中无法工作,因此不要使用。不支持它的浏览器会整个忽略这项设置,结果是没有留下任何防御。
另一个陷阱是 SAMEORIGIN 的比对范围。许多浏览器的实现只比对最顶层文档的源,因此把本站页面加载到本站的 iframe 中、再由攻击者页面在最顶层包裹整体的嵌套结构可以绕过它。frame-ancestors 会逐个比对祖先框架,所以没有这个漏洞。
同时设置两者时,支持 frame-ancestors 的浏览器会应用它,不支持的浏览器则由 X-Frame-Options 生效。重复指定不会互相抵消。
JavaScript 防御 (Frame Busting)
使用 if (top !== self) { top.location = self.location; } 这样的脚本,在被 iframe 加载时跳转到顶层框架。但由于攻击者可以通过 sandbox 属性限制 JavaScript 执行,因此只应作为 HTTP 头防御的补充。
实务防御检查清单
确保可靠实现点击劫持防御的检查清单。
- 确认安全头配置:确认所有页面的响应中包含
X-Frame-Options: DENY(或SAMEORIGIN) 和 CSPframe-ancestors - 识别需要 iframe 嵌入的页面:对于有合理理由允许 iframe 的页面 (如支付表单嵌入),严格限制允许的源
- 保护关键操作:对于密码修改、转账、账户删除等关键操作,除 CSRF 令牌外还要求重新认证 (重新输入密码)
- 与 HSTS 配合:强制 HTTPS,防止通过中间人攻击移除安全头
- 定期测试:定期测试本站是否可以被 iframe 嵌入。可使用浏览器开发者工具或安全扫描器验证
点击劫持单独来看可能危害不大,但与社会工程学结合后,是一种能在用户不知情的情况下执行关键操作的强大攻击手法。由于仅通过 HTTP 头配置就能防御,是性价比极高的安全措施。
常见误解
- 点击劫持是过时的攻击手法,现在已不构成威胁
- 成立条件只有「本站能被其他站点的 iframe 加载」这一点,在既未设置 X-Frame-Options 也未设置 CSP frame-ancestors 的页面上,截至 2026 年仍然成立。拥有一次点击就能确定结果的 UI (社交网络的分享按钮、OAuth 的授权页面、设置的开关等) 的站点,无论上线时间早晚,都需要确认自身的响应头。
- 仅靠 JavaScript 的 Frame Busting 就能充分防御
- 攻击者可以通过 iframe 的 sandbox 属性限制 JavaScript 执行,或通过 onbeforeunload 事件阻止框架跳转。基于 HTTP 头 (X-Frame-Options、CSP frame-ancestors) 的防御是必须的,JavaScript 只是辅助措施。