简介
点击劫持是一种视觉上的欺骗手段。攻击者使用一个透明的,不可见的iframe,覆盖在一个网页上,然后诱使用户在该网页上操作,在不知情的情况下点击透明的iframe页面,点击一些功能性的按钮。
如下攻击者在恶意页面http://example.com/demo.html中嵌入一个目标页面的iframe:
<!DOCTYPE html>
<html>
<head>
<style>
iframe{
position:absolute;
top:-800px;
width:400px;
height:1000px;
z-index:999;
opacity:0.8;
}
button{
posion:absolute;
top:40px;
left:40px;
z-index:1;
width:80px;
height:30px;
}
</style>
</head>
<body>
<iframe src="http://****"></iframe>
<button>Click Here</button>
</body>
</html>
这个iframe页面是完全透明、不可见的,用户看到的是只有Click Here按钮的页面。
其中iframe和button都必须通过绝对定位,z-index才会生效;
然后通过设置iframe的长宽,以及调整top,left属性的值来更改其位置,可以使iframe页面内的任何部分覆盖到任何地方;
同时z-index值要设置的足够大,使iframe位于所有页面最上层;
最后通过设置opacity来控制iframe页面的透明度,当其为0时,则iframe页面完全透明。这样就可以实施点击劫持攻击。
图片 覆盖攻击
Cross Site Image Overlaying(XSIO)攻击,即通过调整图片的style属性,使图片覆盖在攻击者指定的任意位置,可以将图片伪装一个正常的链接、按钮甚至文字,完全改变网站要表达的意思。
由于<img>标签在很多系统中对用户时开放的,因此在现实中有非常多的站点存在被XSIO攻击的可能。在防御XSIO攻击时,需要检查用户提交的HTML代码中,<img>标签的style属性是否可能导致图片浮出边界。
拖拽劫持与数据窃取
拖拽劫持
的思路是诱使用户从隐藏的、不可见的iframe页面中拖拽
出攻击者希望得到的数据,放到攻击者能控制的另一个页面,从而窃取数据。
现代浏览器对拖拽劫持做了一定的防御,无法从跨域的iframe页面中拖拽出数据,但是在不同的窗口
之间跨域拖拽数据是可行的。这就增加了实施攻击的难度,因为要诱骗受害者同时打开两个窗口。
其他劫持方式
Filejacking的劫持攻击可以窃取本机用户文件。采用Webkit引擎的浏览器支持上传整个文件夹,如果攻击者构造一个“下载页面”(实为上传文件),用户在选择目录时没仔细看就容易把整个本地文件夹直接上传。后来浏览器为避免此类攻击,会为用户跳出确认对话框。
防御点击劫持
针对这种类型的劫持,一般通过禁止跨域的iframe来防范。
Frame Busting
可以写一段JavaScrip代码禁止iframe嵌套,这种方法叫Frame Busting
。
比如
if(top.location!=location){
top.location=self.location;
}
常见的检测方式还有
if(top!=self)
if(top.location!=self.location)
if(top.location!=location)
if(parent.frames.length>0)
if(window!=top)
if(window.top!=window.self)
if(parent&&parent!=window)
等等
由于是用Java Script写的,控制能力不是很强,因为有很多办法可以绕过。
Cookie的SameSite属性
当把会话的Cookie属性设置成Strict
或Lax
模式时,iframe跨站点加载页面时就不会发送该Cookie,所以iframe页面将处于未登录状态,攻击者就无法实施攻击了。
X-Frame-Options
HTTP头——X-Frame-Options可以说就是为了解决劫持攻击而生的,主流的浏览器都支持这个特性,它有3个可选值。
1. DENY(拒绝当前页面通过iframe被加载)
2. SAMEORIGIN(当前页面只能被同源的其他页面通过iframe加载,在嵌套多层iframe时也要求所有上层页面都同源)
3. ALLOW-FROM=url(可以定义允许哪些URL能通过iframe加载当前页面)
虽然主流的浏览器都支持X-Frame-Options,但它并没有成为HTTP标准,而HTTP标准主推另一个更强大的做法,即CSP的frame-ancestors指令。
CSP:frame-ancestors
该指令用于指示哪些源可以加载当前页面,其用法非常灵活 ,有如下几种:
- hots:指定的域名或者泛域名可以加载。
- ’self‘:与当前URL同源的网站可以加载。
- ’none‘:任何源都不允许加载。
Content-Security-Policy: frame-ancestors 'self' https://example.com;
允许当前源及http://example.com的页面
作为当前页面的父页面
。