JSONP攻防实例解析
前言
纸上得来终觉浅,绝知此事要躬行。
关于JSONP
Jsonp
(JSON with Padding)是一种跨域请求资源的解决方案,JSONP可以绕过AJAX
遵循的同源策略。
菜鸟教程存在数据(["customername1","customername2"])
,我们希望在本地展示,由于受同源策略的限制,AJAX
无法调用该页面。代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JSONP 实例</title>
<script type="text/javascript">
var request = new XMLHttpRequest();
request.onreadystatechange = function () {
if (request.readyState === 4) {
// 判断响应结果:
if (request.status === 200) {
// 成功,通过responseText拿到响应的文本:
document.getElementById("text").innerHTML=xmlhttp.responseText;
} else {
// 失败,根据响应码判断失败原因:
return request.status;
}
}
}
// 发送请求:
request.open('GET', 'http://www.runoob.com/try/ajax/jsonp.php');
request.send();
</script>
</head>
<body>
<div id="text"></div>
</body>
</html>
访问测试:python -m SimpleHTTPServer
开启HTTP服务器,默认端口8000,开启console
结果如下
Callback
为了更好的使用第三方数据,第三方允许请求方
使用自定义的callback
名称。例如:http://www.runoob.com/try/ajax/jsonp.php?jsoncallback=test
,这里的jsoncallback
参数是可以自定义的。
JSONP应用
菜鸟教程给出了一个demo
。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JSONP 实例</title>
</head>
<body>
<div id="divCustomers"></div>
<script type="text/javascript">
function callbackFunction(result, methodName)
{
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=callbackFunction"></script>
</body>
</html>
访问测试结果如下:
安全问题
JSON劫持
详见WooYun-2012-11284
,自己写了一个demo
,大牛勿喷。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JSON 劫持</title>
<script>
var info = {
"name":"admin",
"passwd":"123456"
};
function displayAuth(){
document.getElementById("name").innerHTML=info.name;
document.getElementById("passwd").innerHTML=info.passwd;
}
</script>
</head>
<body>
用户名: <span id="name"></span><br />
密码: <span id="passwd"></span><br />
<button type="button" onclick="displayAuth()">secret</button>
</body>
</html>
点击secret
按钮,显示用户名和密码。
XSS漏洞
参考知道创宇给出的demo
,访问http://127.0.0.1/getUsers.php?callback=<script>alert(/xss/)</script>
即可触发。
<?php
//getUsers.php
$callback = $_GET['callback'];
print $callback.'({"id" : "1","name" : "知道创宇"});';
?>
防护
- 检查
Referer
是否合法,因为请求是从攻击页面发起的,所以Referer
是攻击页面的URL。 - 过滤
callback
函数名及JSON
里数据的输出。
绕过
空Referer绕过
开发者由于疏忽大意,忘记设置空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>
代码里我们使用<iframe>
调用javscript
伪协议来实现空Referer
调用JSON
文件。
参考;
http://www.runoob.com/json/json-jsonp.html