点击劫持漏洞¶
点击劫持是一种基于界面的攻击,利用诱饵网站中其他内容,诱导用户点击隐藏网站上可操作的内容。请考虑以下例子:
网页用户访问一个诱饵网站(可能是电子邮件提供的链接),点击按钮即可赢得奖品。他们在不知情的情况下被攻击者欺骗,按下了另一个隐藏按钮,从而在另一个网站上获得了账户。这就是点击劫持攻击的一个例子。该技术依赖于在 iframe 中包含一个不可见的可操作网页(或多个页面),其中包含按钮或隐藏链接。iframe 会叠加在用户预期的诱饵网页内容之上。该攻击与 CSRF 攻击不同,用户需要执行诸如点击按钮等操作,而 CSRF 攻击则依赖于在用户不知情或输入的情况下伪造整个请求。
防御 CSRF 攻击通常通过使用 CSRF 令牌来提供:会话专用的一次性使用编号或 nonce。点击劫持攻击并不能通过 CSRF 令牌来缓解,因为目标会话是从真实网站加载的内容,所有请求都发生在域内。CSRF 令牌被放入请求中,并作为正常会话的一部分传递给服务器。与普通用户会话的区别在于,该过程发生在隐藏的 iframe 内。
点击劫持攻击使用 CSS 来创建和操作图层。攻击者将目标网站作为 iframe 层叠加在诱饵网站上。使用样式标签和参数的一个示例如下:
<head>
<style>
#target_website {
position:relative;
width:128px;
height:128px;
opacity:0.00001;
z-index:2;
}
#decoy_website {
position:absolute;
width:300px;
height:400px;
z-index:1;
}
</style>
</head>
...
<body>
<div id="decoy_website">
...decoy web content here...
</div>
<iframe id="target_website" src="https://vulnerable-website.com">
</iframe>
</body>
目标网站的 iframe 会在浏览器中被定位,使目标动作与诱饵网站使用合适的宽度和高度位置值实现精确重叠。使用绝对和相对位置值以确保目标网站准确重叠诱饵,无论屏幕大小、浏览器类型和平台如何。z-index 决定了 iframe 和网站图层的叠加顺序。不透明度值定义为 0.0(或接近 0.0),以确保 iframe 内容对用户透明。浏览器点击劫持保护可能会应用基于阈值的 i 帧透明度检测(例如,Chrome 76 版包含此功能,但 Firefox 没有)。攻击者选择不透明度值,以便在不触发保护行为的情况下实现预期效果。
虽然可以按照上述方法手动创建用于检测点击劫持的演示案例,但实际上这种做法相当繁琐且耗时。在真实环境中检测点击劫持时,我们建议使用 Burp 的 Clickbandit 工具。该工具允许你使用浏览器在目标页面上执行各种操作,然后自动生成一个包含用于检测点击劫持的 HTML 代码的文件。这样一来,你无需编写任何 HTML 或 CSS 代码,就能在几秒钟内创建出用于演示点击劫持的交互式案例。


复制后,粘贴到浏览器控制台
用于破解框架的脚本/用于绕过框架限制的程序代码¶
只要网站可以被“框架化”,就有可能发生点击劫持攻击。因此,预防措施主要是限制网站的框架功能。一种常见的客户端防护方式是使用能够破坏框架的脚本。这些脚本可以通过浏览器中的 JavaScript 插件或扩展程序来实现,比如 NoScript。这类脚本通常被设计成能够执行以下一种或多种功能:
- 检查并确保当前的活动窗口是主窗口或最上层的窗口。
- 让所有框架都可见。
- 防止点击那些不可见的框架。
- 拦截并警示用户可能存在的点击劫持攻击。
破解框架的技术往往因浏览器和平台的不同而有所差异。由于 HTML 的灵活性,攻击者通常能够找到绕过这些技术的办法。由于破解框架的脚本都是用 JavaScript 编写的,因此浏览器的安全设置可以阻止这些脚本的运行;或者,浏览器可能根本不支持 JavaScript。针对破解框架的有效应对措施是使用 HTML5 的 iframe sandbox 属性。当该属性被设置为 allow-forms 或 allow-scripts 值,同时省略 allow-top-navigation 值时,破解框架的脚本就无法起作用了,因为此时 iframe 无法判断自己是否为顶层窗口。
<iframe id="victim_website" src="https://victim-website.com" sandbox="allow-forms"></iframe>
allow-forms 和 allow-scripts 的值都允许在 iframe 内执行指定的操作,但会禁止顶级导航功能。这样一来,虽然可以正常使用目标网站的功能,但却无法通过 iframe 来跳出该网站。
如何防范点击劫持攻击¶
我们讨论了在浏览器端常见的防御机制,也就是用于阻止 iframe 技术的脚本。不过,我们发现,攻击者往往能够轻易地绕过这些防御措施。因此,人们设计了基于服务器的机制来限制 iframe 的使用,从而有效防止点击劫持行为。
点击劫持是一种发生在浏览器端的攻击行为。其能否得逞,取决于浏览器的功能实现情况,以及浏览器是否遵循了现有的网络标准和最佳实践。在服务器端,可以通过对 iframe 等组件的使用加以限制来防止点击劫持。不过,这种防护措施的生效仍取决于浏览器是否遵守了这些限制条件。服务器端防止点击劫持的两种机制是 X-Frame-Options 和内容安全策略。
X-Frame-Options X-Frame-Options 设置¶
“X-Frame-Options”这一机制最初是作为非官方的响应头在 Internet Explorer 8 中引入的,随后很快被其他浏览器所采用。该机制允许网站所有者控制 iframe 或相关对象的使用方式。通过使用 deny 指令,可以禁止将某个网页嵌入到其他框架中。
或者,可以使用 sameorigin 指令来限制框架的引用范围,使其仅限于与该网站同源的页面。
或者,可以使用 allow-from 指令,指向某个特定的网站:
X-Frame-Options 这一机制在各个浏览器中的实现并不一致(例如,Chrome 76 和 Safari 12 不支持 allow-from 指令)。不过,如果将这一机制与内容安全策略相结合,作为多层次防御策略的一部分来使用,那么它就能有效防止点击劫持攻击。
CSP¶
内容安全策略(CSP)是一种用于检测和预防各类攻击的机制,能有效抵御 XSS 和点击劫持等攻击。CSP 通常在 Web 服务器上实现,作为响应头的一部分来发送给客户端。
其中,“policy”是一串由分号分隔的策略指令。CSP 向客户端浏览器提供有关允许的网页资源来源的信息,浏览器可以利用这些信息来识别和拦截各种恶意行为。
推荐的防止点击劫持的措施是在应用程序的内容安全策略中加入 frame-ancestors 指令。 frame-ancestors 'none' 指令的作用与 X-Frame-Options deny 指令类似。 frame-ancestors 'self' 指令则大致相当于 X-Frame-Options sameorigin 指令。以下内容安全策略仅允许来自同一域名的框架被嵌入到页面中:
或者,可以将框架的设置限制在特定的网站上:
为了有效防止点击劫持和 XSS 攻击,内容安全策略需要经过精心设计、实施和测试。同时,内容安全策略应作为多层次防御策略的一部分来使用。