点击劫持 (UI 覆盖攻击)
1. 定义
点击劫持 (Clickjacking)(又称「UI 覆盖攻击」)是一种恶意技术,攻击者欺骗用户点击与其感知不同的内容。攻击者将目标网站加载到透明的 iframe 中,并将其覆盖在诱饵页面之上,使得用户对可见页面的点击实际上作用于隐藏的目标网站。
这允许攻击者劫持原本针对可见页面的点击,并将其重定向到用户已认证的另一个网站上执行非预期的操作。
2. 技术原理
该攻击利用浏览器使用 CSS 定位和透明度来分层 Web 内容的能力。
攻击结构:
<!-- 攻击者页面 -->
<style>
iframe {
position: absolute;
top: 0;
left: 0;
width: 500px;
height: 200px;
opacity: 0; /* 不可见 */
z-index: 2; /* 在最上层 */
}
.decoy-button {
position: absolute;
top: 50px;
left: 100px;
z-index: 1; /* 在 iframe 下方 */
}
</style>
<button class="decoy-button">点击领取奖品!</button>
<iframe src="https://bank.com/transfer?to=attacker&amount=1000"></iframe>当用户点击「领取奖品」按钮时,他们实际上点击了 bank.com 上不可见的「转账」按钮。
关键条件:
- 目标网站允许在 iframe 中嵌入。
- 用户已在目标网站上认证。
- 目标操作可以通过单次点击触发。
3. 攻击流程
sequenceDiagram
participant Victim as 受害者
participant AttackerPage as 攻击者页面
participant TargetSite as iframe 中的目标网站
Victim->>AttackerPage: 访问恶意页面
Note over AttackerPage: 页面在不可见的<br/>iframe 中加载目标网站
AttackerPage-->>Victim: 显示诱饵内容<br/>领取奖品按钮
Victim->>AttackerPage: 点击诱饵按钮
Note over Victim,TargetSite: 点击穿透到<br/>不可见的 iframe
Victim->>TargetSite: 实际点击了删除账号按钮
TargetSite-->>TargetSite: 操作已执行<br/>账号已删除
TargetSite-->>Victim: 隐藏 iframe 中显示确认页面4. 真实案例:Twitter 蠕虫 (2009)
目标: Twitter「关注」按钮功能。 漏洞类别: 经典点击劫持 / UI 覆盖。
漏洞背景: 2009 年,Twitter 没有实施 frame-busting 或 X-Frame-Options 标头。任何页面都可以在 iframe 中嵌入 Twitter。
攻击过程:
- 攻击者创建了带有诱人内容的页面,如「不要点击这里」或假的 Flash 播放器按钮。
- 在这些按钮后面是一个不可见的 iframe,其中包含针对特定账号的 Twitter 关注按钮。
- 当用户点击时,他们在不知情的情况下关注了攻击者的 Twitter 账号。
- 被关注的账号随后发送包含同一恶意页面链接的私信。
影响: 该蠕虫病毒式传播,一些账号在数小时内获得了数十万关注者。它展示了点击劫持如何在社交平台上实现自我传播的攻击。
5. 深度防御策略
A. X-Frame-Options 标头
防止框架攻击的经典防御手段。
X-Frame-Options: DENYDENY: 页面不能在任何框架中显示。SAMEORIGIN: 页面只能被同源页面嵌入框架。
注意: 此标头现在被视为遗留方案。请改用 CSP frame-ancestors。
B. Content-Security-Policy: frame-ancestors
现代且更灵活的方法。
Content-Security-Policy: frame-ancestors 'self' https://trusted-partner.com'none': 等同于 X-Frame-Options: DENY。'self': 仅同源可以嵌入框架。- 特定域名: 白名单信任的嵌入方。
C. JavaScript Frame Busting(备选方案)
用于不支持标头的旧版浏览器的遗留技术。
// 基本的框架破解
if (top !== self) {
top.location = self.location;
}警告: 这可以通过 sandbox 属性绕过:
<iframe src="target.com" sandbox="allow-scripts"></iframe>现代防御应依赖 HTTP 标头,而非 JavaScript。
D. SameSite Cookies
即使被嵌入框架,也可防止会话 Cookie 在跨站 iframe 上下文中被发送。
Set-Cookie: session=abc123; SameSite=Strict; Secure这会破坏攻击,因为目标网站不会将用户识别为已认证。
E. 用户交互确认
对于关键操作,要求额外确认:
- 重新认证: 敏感操作需要重新输入密码。
- 验证码: 证明是人类意图。
- 两步操作: 要求明确的确认对话框。
