内容简介:emmmmm,jsonp劫持已经是大佬们玩的剩下的了,然而在较大型的企业中还是存在不少的这种类型的漏洞,所以还是有必要学一学的。为了保护用户的安全,现代浏览器都使用了同源策略,不允许访问非同源的页面。然而还是有很多的需求去访问不同源页面的数据,怎么办?浏览器表示,拖鞋是不可能拖鞋的,一辈子都不可能拖鞋的。所以就出现了跨域这种概念。jsonp作为一种跨域方案,被广泛应用在较大互联网站点,而如果这种跨域方案存在安全问题,攻击者也可以利用。惯例,在了解jsonp劫持之前,先将前置的各种概念解释清楚。同源策略(S
简介
emmmmm,jsonp劫持已经是大佬们玩的剩下的了,然而在较大型的企业中还是存在不少的这种类型的漏洞,所以还是有必要学一学的。为了保护用户的安全,现代浏览器都使用了同源策略,不允许访问非同源的页面。然而还是有很多的需求去访问不同源页面的数据,怎么办?浏览器表示,拖鞋是不可能拖鞋的,一辈子都不可能拖鞋的。所以就出现了跨域这种概念。jsonp作为一种跨域方案,被广泛应用在较大互联网站点,而如果这种跨域方案存在安全问题,攻击者也可以利用。
SOP
惯例,在了解jsonp劫持之前,先将前置的各种概念解释清楚。同源策略(SOP),何为同源:
同协议
同域名
同端口
例: https://drops.org.cn
与:
http://drops.org.cn
不同协议
https://test.drops.org.cn
不同域名
http://drops.org.cn:8000
不同端口
于是它们都是不同源的。
正确了解SOP策略
如果不加注意,你也许会认为同源策略就是浏览器简单粗暴地阻止浏览器去请求,而恰恰相反,浏览器不会阻止脚本去访问,而是阻止 Response
。用一个小例子来试验一下。
<script src="http://cdn.static.runoob.com/libs/jquery/1.8.3/jquery.js"> $.get('https://drops.org.cn/catch.php') </script>
catch.php是放在服务器的一个脚本,记录访问日志,将ip等信息写入文件。
对以上代码进行测试发现:
服务端:
同源策略阻止了返回资源。这个时候就有人会想到,既然是浏览器阻止返回资源,那么在CSRF攻击利用中,即使无法载入资源,攻击请求已经发出。是不是可以在只验证 referer
的CSRF中伪造 referer
达成CSRF攻击。我们试验 JQuery
在一个 Ajax
添加定制 referer
头。
<script type="text/javascript" src="http://cdn.static.runoob.com/libs/jquery/1.8.3/jquery.js"> </script> <script type="text/javascript"> $(document).ready(function(){ $.ajax({ type : "get", async: false, headers: { 'Referer':'https://drops.org.cn' }, url : "https://drops.org.cn", type: "json", success : function(data) { alert(data) } }); }); </script>
当请求时,会发现浏览器阻止 Ajax
伪造Referer:
跨域与jsonp
同源策略虽然提高了安全性,但也给开发者造成了不便。于是一些常见的跨域解决方案便出现了:
- 降域
- CORS:跨域资源共享
- jsonp:Json With Padding
降域
使用于在子域名较多时,在js中使用 document.domain
降域为主域,于是整个子域都能去获取主域或则相互间加载。
CORS
跨域资源共享是一个W3C标准,是标准的跨域方案。简单来说,就是服务器只需要合理设置 Access-Control-Allow-Origin
, Access-Control-Allow-Credentials
, Access-Control-Expose-Headers
三个字段,客户端请求时加入 Origin:
字段,服务端判断该 Origin
是否在 Access-Control-Allow-Origin
规则中,若满足规则,则能成功请求数据。详细的CORS原理可在 http://www.ruanyifeng.com/blog/2016/04/cors.html
查看,写的非常详细。本文不再过多解释。
jsonp
:在html标签里,一些标签利用 src
, href
等属性去加载资源是没有跨域限制的。于是聪明的 程序员 就发明了 jsonp
这种跨域方案,虽然应用广泛,但却不是官方的。常见的可跨域标签有
<script src="..."></script> <img src="..."> <video src="..."></video> <audio src="..."></audio> <embed src="..."> <frame src="..."> <iframe src="..."></iframe> <link rel="stylesheet" href="..."> <applet code="..."></applet> <object data="..." ></object>
而jsonp就是利用 script
的 src
属性可加载任意资源的原理去进行跨域数据传输。
在现在的web等应用程序中,使用 json
传输数据是不二之选,但由于浏览器同源策略限制, javascript
无法直接去获取接口 json
数据。jsonp其实就是将json数据封装在一个js函数中,由 scipt
的 src
去请求并返回这个函数。客户端获取到该函数之后执行该函数,我们暂时将此过程称之为一个 callback
。
而客户端要运行一个js函数,则需要知道这个函数的名字,这时服务端就不能去定义一个死的函数名,这样会造成业务间的高耦合,也不安全。因此这个函数名需要客户端去传输过来,服务端将请求函数名和json数据封装。这个过程在客户端表现为jsonp需要一回调函数。接下来举个简单的例子:
服务端的代码如下
<?php header('Content-type: application/json'); //获取回调函数名 $jsoncallback = htmlspecialchars($_REQUEST ['jsoncallback']); //json数据 $json_data = '["customername1","customername2"]'; //输出jsonp格式的数据 echo $jsoncallback . "(" . $json_data . ")"; ?>
这个可以在 http://www.runoob.com/try/ajax/jsonp.php?jsoncallback=dr0op
请求。可以发现返回数据包如下:
dr0op(["customername1","customername2"])
jsoncallback
传递过去的就是函数名。服务端返回的是一个 函数调用
。可以理解为 dr0op
是一个函数,其中的 ["customername1","customername2"]
是函数参数,也是我们要传输的数据。而客户端只需要去编写一个 dr0op
函数,接收参数并处理,就获取到json数据了。这就是一个 callback
。
客户端可编写如下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>JSONP 实例</title> </head> <body> <div id="divCustomers"></div> <script type="text/javascript"> function dr0op(result) { var html = '<ul>'; for(var i = 0; i < result.length; i++) { html += '<li>' + result[i] + '</li>'; } html += '</ul>'; document.getElementById('divCustomers').innerHTML = html; } </script> <script type="text/javascript" src="http://www.runoob.com/try/ajax/jsonp.php?jsoncallback=dr0op"></script> </body> </html>
客户端获取数据库将数据写入 ul
节点中。查看输出:
可以发现,成功获取到数据。
jsonp劫持
如果jsonp传输的数据是较为敏感的数据,但是服务端并没有对客户来源页 referer
合理检测,那么攻击者只需要伪造一个页面,类似CSRF攻击那样,就可以获取敏感数据了。
这里来说一个典型的黑产案例:
有时候你不小心点击到了某个培训,医疗,或者保险之类的网站,你并没有去输入你的手机号,等一会就会有人打电话过来,问你需不需要他们的产品。这是黑产挖掘到了运营商的一个漏洞,然后利用漏洞泄漏用户手机号,将手机号发送到后台。其实这个漏洞有一部分就是jsonp劫持导致的:
至于为什么手机进行web访问运营商接口,运营商就可以获取手机号。大致因为运营商可以依据当前手机移动窝蜂网络如4G等,依据网络认证获取SIM卡手机号(非HTTP协议)。
具体的原理或许只有运营商通信商掌握。
jsonp劫持获取QQ号:
jsonp劫持泄漏信息:
空referer绕过检测
和CSRF一样,防御jsonp劫持可以去检测referer,由于直接使用浏览器打开为空的referer,而检测也会通常忽略这一点,只要攻击者让用户点击时利用浏览器特性发送空referer,即可桡过检测。
如,在 iframe
标签中使用 javascript
伪协议来实现空referer:
<iframe src="javascript:'<script>function JSON(o){alert(o.userinfo.userid);}</script><script src=http://www.qq.com/login.php?calback=JSON></script>'"></iframe>
也可以时候data伪协议实现:
data:text/plain; base64,our_base64_encoded_code
jsonp劫持防御
1、严格安全的实现 CSRF 方式调用 JSON 文件:限制 Referer 、部署一次性 Token 等。
2、严格安装 JSON 格式标准输出 Content-Type 及编码( Content-Type : application/json; charset=utf-8 )。
3、严格过滤 callback 函数名及 JSON 里数据的输出。
4、严格限制对 JSONP 输出 callback 函数名的长度(如防御上面 flash 输出的方法)。
5、其他一些比较“猥琐”的方法:如在 Callback 输出之前加入其他字符(如:、回车换行)这样不影响 JSON 文件加载,又能一定程度预防其他文件格式的输出。还比如 Gmail 早起使用 AJAX 的方式获取 JSON ,听过在输出 JSON 之前加入 while(1) ;这样的代码来防止 JS 远程调用。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。