场景复现:小李登陆某网站后,没过多久弹出一段“有趣的”连接,好奇心趋势下小李打开了连接...,跟着提示点来点去,最后啥都没看到,啥都没干成。郁闷之余关闭连接地址后惊奇的发如今已经登陆的网站页面竟然多了几行操做记录,且操做记录正是属于本身!心态 爆炸...javascript
经过用户的点击完成了一系列操做,可是用户对此并不知晓发生了什么?
复制代码
这种攻击利用HTML中的<iframe>
标签的透明属性,就像在一幅画上铺了一层透明的纸,画就是攻击页面,透明的纸就是用户登陆的网站页面。用户看到的是攻击页面,但其实这个页面之上是网站的页面,网站页面被透明化,攻击页面和网站页面的按钮位置、点击方式几乎都如出一辙。这时用户看到的是攻击页面,用户觉得本身操做的也是攻击页面,可是实际上操做的确实网站页面;若是这个网站是用户的邮箱、银行帐户,而且你还噼里啪啦操做了一堆,内心顿时有点凉!html
登陆某网站后,弹出了一段“点击和美女聊天的连接",当用户点击了“和美女聊天”的连接后,在已经登陆的博客发表了一篇帖子...java
<!doctype html>
<html> <head> <meta charset="utf-8"/> <title>clickhijack</title> </head> <!--background是本地的一张有趣的图片 --> <body style="background:url(clickjacking.jpeg) no-repeat;background-size: cover;"> <!-- src是笔者本地启动的nodejs项目添加评论页面--> <iframe style="opacity:0.3" src="http://localhost:3000/post/1" width="1260" height="600"></iframe> </body> </html>
复制代码
页面显示的效果是这样:
node
页面真实的效果是这样:
这里将iframe
的透明度改为了0.5nginx
固然真实的攻击页面内容会很丰富很吸引人。笔者这里只作演示,攻击思路是同样的。浏览器
经过案例分析得知,点击劫持的产生是基于iframe
发生的,咱们防护的思路也应该是基于此。安全
Top属性返回当前窗口的最顶层浏览器窗口。markdown
该属性返回对一个顶级窗口的只读引用。若是窗口自己就是一个顶级窗口,top 属性存放对窗口自身的引用。若是窗口是一个框架,那么 top 属性引用包含框架的顶层窗口。框架
下面的例子窗口是否在一个框架中,若是是,则跳出框架;async
<!--下面案例来自W3c -->
<html>
<head>
<script type="text/javascript"> function breakout() { if (window.top != window.self) { window.top.location = "test.html" } } </script>
</head>
<body>
<form>
Click the button to break out of the frame:
<input type="button" onclick="breakout()" value="Break out!">
</form>
</body>
</html>
复制代码
了解top
属性的同时,咱们便可把top
属性应用到点击劫持中。
正常的页面top属性和window属性对比:
top
>Window {window: Window, self: Window, document: document, name: "", location: Location, …}
top.location
>Location {ancestorOrigins: DOMStringList, href: "http://localhost:3000/post/1", origin: "http://localhost:3000", protocol: "http:", host: "localhost:3000", …}
window
>Window {window: Window, self: Window, document: document, name: "", location: Location, …}
top===window
>true
复制代码
点击劫持的页面top属性和window属性对比:
top
>global {0: Window, window: global, self: global, location: {…}, closed: false, frames: global, …}
top.location
>{then: undefined, Symbol(Symbol.toStringTag): undefined, Symbol(Symbol.hasInstance): undefined, Symbol(Symbol.isConcatSpreadable): undefined, replace: ƒ}
window
>Window {window: Window, self: Window, document: document, name: "", location: Location, …}
top===window
//false
复制代码
由以上区别作基础便可进行判断,示例代码以下:
<script type="text/javascript">
if (top.location != windowlocation)
{
top.location = window.location
}
</script>
复制代码
到此彷佛是解决了点击劫持的问题,可是真的100%解决了吗?答案确定是没有。
只要能禁止执行脚本就会再次触发攻击!刚好iframe
中的sandbox
恰好有这做用.
<iframe>
标签的 sandbox 属性若是被规定为空字符串(sandbox=""),sandbox 属性将会启用一系列对行内框架中内容的额外限制。
sandbox 属性的值既能够是一个空字符串(应用全部的限制),也能够是空格分隔的预约义值列表(将移除特定的限制)。
<iframe sandbox="value">
复制代码
值 | 描述 |
---|---|
"" | 应用如下全部的限制。 |
allow-same-origin | 容许 iframe 内容被视为与包含文档有相同的来源。 |
allow-top-navigation | 容许 iframe 内容从包含文档导航(加载)内容。 |
allow-forms | 容许表单提交。 |
allow-scripts | 容许脚本执行。 |
了解sanbox属性后,咱们便可将设置属性就能再次触发攻击!
示例:
<iframe style="opacity:0.3" src="http://localhost:3000/post/1" width="1260" height="600" sandbox="allow-forms"></iframe>
<!-- 容许表单提交事件,剩下的都会被禁止 -->
复制代码
这时又能够开始点击劫持攻击了!
The X-Frame-Options HTTP 响应头是用来给浏览器 指示容许一个页面 能否在 <frame>
, <iframe>
, <embed>
或者 <object>
中展示的标记。站点能够经过确保网站没有被嵌入到别人的站点里面,从而避免 clickjacking 攻击。
X-Frame-Options 有三个可能的值
X-Frame-Options: deny
X-Frame-Options: sameorigin
X-Frame-Options: allow-from https://example.com/
复制代码
值 | 描述 |
---|---|
deny | 表示该页面不容许在frame中展现,及时是相同域名页面的嵌套 |
sameorigin | 表示该页面能够在相同域名页面的 frame 中展现。 |
allow-from uri | 表示该页面能够在指定来源的 frame 中展现。 |
Note: 设置 meta 标签是无效的!例如 没有任何效果。不要这样用!只有当像下面示例那样设置 HTTP 头 X-Frame-Options 才会生效。
要将 Apache 的配置 X-Frame-Options 设置成 deny , 按以下配置去设置你的站点:
Header set X-Frame-Options "deny"
要将 Apache 的配置 X-Frame-Options 设置成 allow-from,在配置里添加:
Header set X-Frame-Options "allow-from example.com/"
配置 nginx 发送 X-Frame-Options 响应头,把下面这行添加到 'http', 'server' 或者 'location' 的配置中:
add_header X-Frame-Options sameorigin always;
示例代码:
//有可能被攻击的页面直接禁止被内嵌->DENY
router.all('/*', async function(ctx, next){
ctx.set('X-Frame-Options','DENY')
await next();
});
复制代码
X-FRAME_OPTIONS浏览器兼容性良好,读者可放心使用。
详细兼容性状况读者可参考文末X-FRAME_OPTIONS
参考资料
...
百度百科——点击劫持
W3school-top属性
W3school-<iframe>
标签的sandbox属性
MDN-X-Frame-Options
点击劫持对于WEB安全来说,相当重要。尤为是对iframe
嵌套项目来说。 本文记录的是笔者在开发过程当中遇到问题引起的思考和探索。可供有相似问题的读者参考。 其余安全方面的文章笔者会持续更新,欢迎各位读者提出意见和建议。