Web 安全

点击劫持

约 3 分钟阅读

什么是点击劫持

点击劫持 (Clickjacking) 是一种使用透明或不可见的 iframe 将合法网页覆盖在用户屏幕上,诱导用户进行非预期点击操作的攻击手法。也被称为 UI Redressing (UI 伪装)。

攻击者创建一个陷阱页面,并在其上方用透明的 iframe 覆盖目标站点。用户看到的是陷阱页面的按钮和链接,但实际点击的是透明 iframe 中目标站点的元素。这样,用户在不知情的情况下就会执行「点赞」、设置变更、转账确认等操作。

攻击原理与手法

点击劫持按以下步骤执行。

  1. 攻击者创建陷阱网页,放置有吸引力的内容 (视频播放按钮、游戏、抽奖表单等)
  2. 通过 iframe 加载目标站点,并用 CSS 设置 opacity: 0 (完全透明)
  3. 将透明 iframe 精确覆盖在陷阱页面的可点击元素上方
  4. 用户点击陷阱页面的按钮时,实际点击的是透明 iframe 中目标站点的按钮

进阶手法

  • 拖放利用:利用用户的拖动操作向透明 iframe 中的表单输入数据
  • 光标劫持:将光标的显示位置偏移实际位置,使用户点击非预期的位置
  • 多步攻击:诱导多次点击,甚至让用户点击确认对话框的「确定」按钮

XSSCSRF 结合时,可以构建更复杂的攻击场景。

防御措施的实现

点击劫持防御的核心是防止本站被其他站点的 iframe 嵌入。

CSP frame-ancestors 指令

CSPframe-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-ancestorsX-Frame-Options,可以在兼容旧浏览器的同时应用最新的保护。

JavaScript 防御 (Frame Busting)

使用 if (top !== self) { top.location = self.location; } 这样的脚本,在被 iframe 加载时跳转到顶层框架。但由于攻击者可以通过 sandbox 属性限制 JavaScript 执行,因此只应作为 HTTP 头防御的补充。

实务防御检查清单

确保可靠实现点击劫持防御的检查清单。

  • 确认安全头配置:确认所有页面的响应中包含 X-Frame-Options: DENY (或 SAMEORIGIN) 和 CSP frame-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 只是辅助措施。
分享

相关术语