Web 安全
点击劫持
约 3 分钟阅读
最后更新: 2026-01-30
什么是点击劫持
点击劫持 (Clickjacking) 是一种使用透明或不可见的 iframe 将合法网页覆盖在用户屏幕上,诱导用户进行非预期点击操作的攻击手法。也被称为 UI Redressing (UI 伪装)。
攻击者创建一个陷阱页面,并在其上方用透明的 iframe 覆盖目标站点。用户看到的是陷阱页面的按钮和链接,但实际点击的是透明 iframe 中目标站点的元素。这样,用户在不知情的情况下就会执行「点赞」、设置变更、转账确认等操作。
攻击原理与手法
点击劫持按以下步骤执行。
- 攻击者创建陷阱网页,放置有吸引力的内容 (视频播放按钮、游戏、抽奖表单等)
- 通过
iframe加载目标站点,并用 CSS 设置opacity: 0(完全透明) - 将透明 iframe 精确覆盖在陷阱页面的可点击元素上方
- 用户点击陷阱页面的按钮时,实际点击的是透明 iframe 中目标站点的按钮
进阶手法
- 拖放利用:利用用户的拖动操作向透明 iframe 中的表单输入数据
- 光标劫持:将光标的显示位置偏移实际位置,使用户点击非预期的位置
- 多步攻击:诱导多次点击,甚至让用户点击确认对话框的「确定」按钮
防御措施的实现
点击劫持防御的核心是防止本站被其他站点的 iframe 嵌入。
CSP frame-ancestors 指令
CSP 的 frame-ancestors 指令控制哪些父页面源可以将本站嵌入 iframe。这是最推荐的防御措施。
frame-ancestors 'none':不允许任何站点通过 iframe 嵌入frame-ancestors 'self':仅允许同源的嵌入frame-ancestors https://trusted.example.com:仅允许特定源的嵌入
X-Frame-Options 头
CSP 之前就在使用的防御措施,目前仍被广泛支持。
X-Frame-Options: DENY:拒绝所有 iframe 嵌入X-Frame-Options: SAMEORIGIN:仅允许同源的嵌入
同时设置 CSP 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 头配置就能防御,是性价比极高的安全措施。
常见误解
- 点击劫持是过时的攻击手法,现在已不构成威胁
- 虽然 2008 年首次被报告,但许多站点仍未设置 X-Frame-Options 或 CSP frame-ancestors,攻击至今仍然有效。针对社交网络「点赞」按钮和 OAuth 授权页面的攻击持续被报告。
- 仅靠 JavaScript 的 Frame Busting 就能充分防御
- 攻击者可以通过 iframe 的 sandbox 属性限制 JavaScript 执行,或通过 onbeforeunload 事件阻止框架跳转。基于 HTTP 头 (X-Frame-Options、CSP frame-ancestors) 的防御是必须的,JavaScript 只是辅助措施。
分享