点击劫持

1/31/2022 Network

image

  • 黑客创建一个网页利用 iframe 包含目标网站;
  • 隐藏目标网站,使用户无法无法察觉到目标网站存在;
  • 构造网页,诱变用户点击特点按钮
  • 用户在不知情的情况下点击按钮,触发执行恶意网页的命令。

点击劫持(ClickJacking)是指利用透明的按钮或链接做成陷阱,覆盖在 Web 页面之上。然后诱导用户在不知情的情况下,点击那个链接访问内容的一种攻击手段。这种行为又称为界面伪装(UI Redressing)。

Clickjacking 这个词首次出现在 2008 年,是由互联网安全专家罗伯特·汉森和耶利米·格劳斯曼首创的。

已设置陷阱的 Web 页面,表面上内容并无不妥,但早已埋入想让用户点击的链接。当用户点到透明的按钮时,实际上是点击了以指定透明属性元素的 iframe 页面。

虽然受害者点击的是他所看到的网页,但其实他所点击的是被黑客精心构建的另一个置于原网页上面的透明页面。

Clickjacking 是仅此于 XSS 和 CSRF 的前端漏洞,因为需要诱使用户交互,攻击成本高,所以不被重视,但危害不容小觑。

# 点击劫持的攻击案例

  • 优酷频道刷粉
  • 新浪微博刷粉
  • ...

# 点击劫持的防御手段

  • JavaScript 禁止内嵌
  • X-FRAME-OPTIONS 禁止内嵌
  • 其它辅助手段

# 传统的防御方式

  • window.top 属性返回当前窗口的最顶层浏览器窗口对象
  • 在 iframe 中的 window 指的是 iframe 窗口对象
if (top.location !== window.location) {
  top.location = window.location
}
1
2
3

注意

在一些较新的浏览器中会阻止跳转。

# 阻止顶级导航

我们可以阻止因更改 beforeunload 事件处理程序中的 top.location 而引起的过渡(transition)。

顶级页面(从属于黑客)在 beforeunload 上设置了一个用于阻止的处理程序,像这样:

window.onbeforeunload = function() {
  return false;
};
1
2
3

当 iframe 试图更改 top.location 时,访问者会收到一条消息,询问他们是否要离开页面。 在大多数情况下,访问者会做出否定的回答,因为他们并不知道还有这么一个 iframe,他们所看到的只有顶级页面,他们没有理由离开。所以 top.location 不会变化!

# Sandbox 特性

sandbox 特性的限制之一就是导航。限制iframe的行为。沙箱化的 iframe 不能更改 top.location。

  • allow-same-origin:允许被视为同源,即可操作父级DOM或cookie等
  • allow-top-navigation:允许当前iframe的引用网页通过url跳转链接或加载
  • allow-forms:允许表单提交
  • allow-scripts:允许执行脚本文件
  • allow-popups:允许浏览器打开新窗口进行跳转
  • "":设置为空时上面所有允许全部禁止

但我们可以添加具有 sandbox="allow-scripts allow-forms" 的 iframe。从而放开限制,允许脚本和表单。但我们没添加 allow-top-navigation,因此更改 top.location 是被禁止的。

<iframe sandbox="allow-scripts allow-forms" src="facebook.html"></iframe>
1

# X-FRAME-OPTIONS

X-FRAME-OPTIONS HTTP 响应头是用来给浏览器指示允许一个页面可否在<frame>,<iframe>或者<object>中展现的标记。网站可以使用此功能,来确保自己网站内容没有被嵌到别人的网站中去,也从而避免点击劫持的攻击。有三个值:

  • DENY:表示页面不允许在 frame 中展示,即便是在相同域名的页面中嵌套也不允许。
  • SAMEORIGIN:表示该页面可以在相同域名页面的 frame 中展示。
  • ALLOW-FROM url:表示该页面可以在指定来源的 frame 中展示。

例如:

  • 京东:X-Frame-Options: SAMEORIGIN
  • Facebook:x-frame-options: DENY
  • Twitter:x-frame-options: DENY

配置 X-FRAME-OPTIONS:

  • Apache 把下面这行添加到 'site' 的配置中:
Header always append X-Frame-Options SAMEORIGIN
1
  • nginx

把下面这行添加到 'http', 'server' 或者 'location',配置中

add_header X-Frame-Options SAMEORIGIN;
1
  • IIS

添加下面配置到 Web.config 文件中

<system.webServer>
...
<httpProtocol>
  <customHeaders>
    <add name="X-Frame-Options" value="SAMEORIGIN" />
  </customHeaders>
</httpProtocol>
...
</system.webServer>
1
2
3
4
5
6
7
8
9

# 显示禁用的功能

X-Frame-Options 有一个副作用。其他的网站即使有充分的理由也无法在 iframe 中显示我们的页面。

因此,还有其他解决方案……例如,我们可以用一个样式为 height: 100%; width: 100%; 的 <div> “覆盖”页面,这样它就能拦截所有点击。如果 window == top 或者我们确定不需要保护时,再将该 <div> 移除。

<style>
  #protector {
    height: 100%;
    width: 100%;
    position: absolute;
    left: 0;
    top: 0;
    z-index: 99999999;
  }
</style>
<div id="protector">
  <a href="/" target="_blank">前往网站</a>
</div>
<script>
  // 如果顶级窗口来自其他源,这里则会出现一个 error
  // 但是在本例中没有问题
  if (top.document.domain == document.domain) {
    protector.remove();
  }
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

samesite cookie 特性也可以阻止点击劫持攻击。

具有 samesite 特性的 cookie仅在网站是通过直接方式打开(而不是通过 frame 或其他方式)的情况下才发送到网站。更多细节请见 Cookie,document.cookie。

如果网站,例如 Facebook,在其身份验证 cookie 中具有 samesite 特性,像这样:

Set-Cookie: authorization=secret; samesite
1

那么,当在另一个网站中的 iframe 中打开 Facebook 时,此类 cookie 将不会被发送。因此,攻击将失败。 当不实用 cookie 时,samesite cookie 特性将不会有任何影响。这可以使其他网站能够轻松地在 iframe 中显示我们公开的、未进行身份验证的页面。

然而,这也可能会使得劫持攻击在少数情况下起作用。例如,通过检查 IP 地址来防止重复投票的匿名投票网站仍然会受到点击劫持的攻击,因为它不使用 cookie 对用户身份进行验证。

# 总结

点击劫持是一种“诱骗”用户在不知情的情况下点击恶意网站的方式。如果是重要的点击操作,这是非常危险的。

黑客可以通过信息发布指向他的恶意页面的链接,或者通过某些手段引诱访问者访问他的页面。当然还有很多其他变体。

一方面 —— 这种攻击方式是“浅层”的:黑客所做的只是拦截一次点击。但另一方面,如果黑客知道在点击之后将出现另一个控件,则他们可能还会使用狡猾的消息来迫使用户也点击它们。

这种攻击相当危险,因为在设计交互界面时,我们通常不会考虑到可能会有黑客代表用户点击界面。所以,在许多意想不到的地方可能发现攻击漏洞。

  • 建议在那些不希望被在 frame 中查看的页面上(或整个网站上)使用 X-Frame-Options: SAMEORIGIN。
  • 如果我们希望允许在 frame 中显示我们的页面,那我们使用一个 <div> 对整个页面进行遮盖,这样也是安全的。
更新时间: 2022-01-30 15:35