opencode-api-security-testing 2.1.0 → 2.1.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.
Files changed (61) hide show
  1. package/SKILL.md +1797 -0
  2. package/core/advanced_recon.py +788 -0
  3. package/core/agentic_analyzer.py +445 -0
  4. package/core/analyzers/api_parser.py +210 -0
  5. package/core/analyzers/response_analyzer.py +212 -0
  6. package/core/analyzers/sensitive_finder.py +184 -0
  7. package/core/api_fuzzer.py +422 -0
  8. package/core/api_interceptor.py +525 -0
  9. package/core/api_parser.py +955 -0
  10. package/core/browser_tester.py +479 -0
  11. package/core/cloud_storage_tester.py +1330 -0
  12. package/core/collectors/__init__.py +23 -0
  13. package/core/collectors/api_path_finder.py +300 -0
  14. package/core/collectors/browser_collect.py +645 -0
  15. package/core/collectors/browser_collector.py +411 -0
  16. package/core/collectors/http_client.py +111 -0
  17. package/core/collectors/js_collector.py +490 -0
  18. package/core/collectors/js_parser.py +780 -0
  19. package/core/collectors/url_collector.py +319 -0
  20. package/core/context_manager.py +682 -0
  21. package/core/deep_api_tester_v35.py +844 -0
  22. package/core/deep_api_tester_v55.py +366 -0
  23. package/core/dynamic_api_analyzer.py +532 -0
  24. package/core/http_client.py +179 -0
  25. package/core/models.py +296 -0
  26. package/core/orchestrator.py +890 -0
  27. package/core/prerequisite.py +227 -0
  28. package/core/reasoning_engine.py +1042 -0
  29. package/core/response_classifier.py +606 -0
  30. package/core/runner.py +938 -0
  31. package/core/scan_engine.py +599 -0
  32. package/core/skill_executor.py +435 -0
  33. package/core/skill_executor_v2.py +670 -0
  34. package/core/skill_executor_v3.py +704 -0
  35. package/core/smart_analyzer.py +687 -0
  36. package/core/strategy_pool.py +707 -0
  37. package/core/testers/auth_tester.py +264 -0
  38. package/core/testers/idor_tester.py +200 -0
  39. package/core/testers/sqli_tester.py +211 -0
  40. package/core/testing_loop.py +655 -0
  41. package/core/utils/base_path_dict.py +255 -0
  42. package/core/utils/payload_lib.py +167 -0
  43. package/core/utils/ssrf_detector.py +220 -0
  44. package/core/verifiers/vuln_verifier.py +536 -0
  45. package/package.json +17 -13
  46. package/references/asset-discovery.md +119 -612
  47. package/references/graphql-guidance.md +65 -641
  48. package/references/intake.md +84 -0
  49. package/references/report-template.md +131 -38
  50. package/references/rest-guidance.md +55 -526
  51. package/references/severity-model.md +52 -264
  52. package/references/test-matrix.md +65 -263
  53. package/references/validation.md +53 -400
  54. package/scripts/postinstall.js +46 -0
  55. package/agents/cyber-supervisor.md +0 -55
  56. package/agents/probing-miner.md +0 -42
  57. package/agents/resource-specialist.md +0 -31
  58. package/commands/api-security-testing-scan.md +0 -59
  59. package/commands/api-security-testing-test.md +0 -49
  60. package/commands/api-security-testing.md +0 -72
  61. package/tsconfig.json +0 -17
@@ -0,0 +1,366 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ 深度 API 渗透测试引擎 v5.5 - 完美版
5
+ 100% 整合 v3.5 的所有有效模式
6
+ + v4.0 的智能学习
7
+ + 增强的 Fallback 机制
8
+ """
9
+
10
+ from playwright.sync_api import sync_playwright
11
+ from urllib.parse import urljoin, urlparse, parse_qs
12
+ import requests
13
+ import re
14
+ import json
15
+ import time
16
+ from collections import defaultdict
17
+ from typing import Dict, List, Set
18
+ from dataclasses import dataclass
19
+
20
+ @dataclass
21
+ class APIEndpoint:
22
+ url: str
23
+ method: str = 'GET'
24
+ source: str = 'unknown'
25
+ discovered_by: str = 'unknown'
26
+
27
+ @dataclass
28
+ class Vulnerability:
29
+ type: str
30
+ severity: str
31
+ endpoint: str
32
+ evidence: str = ''
33
+
34
+ @dataclass
35
+ class SensitiveData:
36
+ type: str
37
+ value: str
38
+ source: str
39
+ severity: str = 'MEDIUM'
40
+
41
+ class V35JSAnalyzer:
42
+ """100% 还原 v3.5 的 JS 分析能力"""
43
+
44
+ def __init__(self, target: str, session: requests.Session):
45
+ self.target = target
46
+ self.session = session
47
+
48
+ def analyze_js(self, js_url: str) -> Dict:
49
+ """分析 JS 文件"""
50
+ try:
51
+ response = self.session.get(js_url, timeout=10)
52
+ content = response.text
53
+
54
+ endpoints = self._extract_endpoints(content, js_url)
55
+ secrets = self._extract_secrets(content, js_url)
56
+
57
+ return {
58
+ 'endpoints': endpoints,
59
+ 'secrets': secrets,
60
+ 'js_url': js_url
61
+ }
62
+ except Exception as e:
63
+ return {'endpoints': [], 'secrets': [], 'js_url': js_url}
64
+
65
+ def _extract_endpoints(self, content: str, source: str) -> List[APIEndpoint]:
66
+ """v3.5 的完整正则模式"""
67
+ endpoints = []
68
+
69
+ # v3.5 验证有效的所有模式
70
+ patterns = [
71
+ # axios
72
+ (r'axios\.(get|post|put|delete|patch)\s*\(\s*[\'"`]([^\'"`]+)[\'"`]', 'axios'),
73
+ (r'this\.\$axios\.(get|post|put|delete|patch)\s*\(\s*[\'"`]([^\'"`]+)[\'"`]', 'vue_axios'),
74
+
75
+ # fetch
76
+ (r'fetch\s*\(\s*[\'"`]([^\'"`]+)[\'"`]', 'fetch'),
77
+
78
+ # 通用路径模式 - 关键!捕获 /login, /home 等
79
+ (r'[\'"`](/[a-z]+/[^\'"`\s?#]*)[\'"`]', 'generic_path'),
80
+ (r'[\'"`](/[a-z]+)[\'"`]', 'single_path'),
81
+
82
+ # API 路径
83
+ (r'[\'"`](/api/[^\'"`\s?#]+)[\'"`]', 'api_path'),
84
+ (r'[\'"`](/rest/[^\'"`\s?#]+)[\'"`]', 'rest_path'),
85
+
86
+ # 业务路径
87
+ (r'[\'"`](/users/[^\'"`\s?#]+)[\'"`]', 'users_path'),
88
+ (r'[\'"`](/projects/[^\'"`\s?#]+)[\'"`]', 'projects_path'),
89
+ (r'[\'"`](/organ/[^\'"`\s?#]+)[\'"`]', 'organ_path'),
90
+ ]
91
+
92
+ for pattern, pattern_type in patterns:
93
+ matches = re.findall(pattern, content, re.IGNORECASE)
94
+ for match in matches:
95
+ if isinstance(match, tuple):
96
+ method = match[0].upper() if match[0].lower() in ['get', 'post', 'put', 'delete', 'patch'] else 'GET'
97
+ url = match[1]
98
+ else:
99
+ method = 'GET'
100
+ url = match
101
+
102
+ # 清理 URL
103
+ url = url.replace('${', '{').replace('}', '')
104
+ if url.startswith('/'):
105
+ url = urljoin(self.target, url)
106
+
107
+ # 过滤:长度>3,包含 http,排除明显误报
108
+ if len(url) > 3 and 'http' in url:
109
+ skip = ['color', 'style', 'width', 'height', 'src', 'href']
110
+ if not any(s in url.lower() for s in skip):
111
+ endpoints.append(APIEndpoint(
112
+ url=url,
113
+ method=method,
114
+ source=source,
115
+ discovered_by=f'v35_{pattern_type}'
116
+ ))
117
+
118
+ return endpoints
119
+
120
+ def _extract_secrets(self, content: str, source: str) -> List[SensitiveData]:
121
+ """提取敏感信息"""
122
+ secrets = []
123
+
124
+ patterns = {
125
+ 'token': r'(?:token|auth[_-]?token)\s*[=:]\s*[\'"`]([^\'"`]{8,})[\'"`]',
126
+ 'api_key': r'(?:api[_-]?key|apikey)\s*[=:]\s*[\'"`]([^\'"`]{8,})[\'"`]',
127
+ 'password': r'(?:password|passwd)\s*[=:]\s*[\'"`]([^\'"`]+)[\'"`]',
128
+ }
129
+
130
+ for secret_type, pattern in patterns.items():
131
+ matches = re.findall(pattern, content, re.IGNORECASE)
132
+ for match in matches:
133
+ secrets.append(SensitiveData(
134
+ type=secret_type,
135
+ value=match[:100] + '...' if len(match) > 100 else match,
136
+ source=source,
137
+ severity='HIGH'
138
+ ))
139
+
140
+ return secrets
141
+
142
+ class DeepAPITesterV55:
143
+ """v5.5 完美版 - 100% v3.5 能力 + v4.0 智能"""
144
+
145
+ def __init__(self, target: str, headless: bool = True):
146
+ self.target = target.rstrip('/')
147
+ self.headless = headless
148
+
149
+ self.session = requests.Session()
150
+ self.session.headers.update({
151
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
152
+ })
153
+
154
+ self.js_analyzer = V35JSAnalyzer(target, self.session)
155
+ self.js_results: List[Dict] = []
156
+ self.endpoints: List[APIEndpoint] = []
157
+ self.vulnerabilities: List[Vulnerability] = []
158
+
159
+ def run_test(self, output_file: str = 'v55_perfect_report.md'):
160
+ """执行测试"""
161
+ print(f"\n{'='*70}")
162
+ print(f"深度 API 渗透测试 v5.5 (完美版)")
163
+ print(f"目标:{self.target}")
164
+ print(f"{'='*70}\n")
165
+
166
+ # 1. 浏览器爬取
167
+ self._crawl_with_browser()
168
+
169
+ # 2. JS 分析 (100% v3.5 能力)
170
+ print(f"\n{'='*70}")
171
+ print(f"[+] JS 分析 (v3.5 能力)")
172
+ print(f"{'='*70}\n")
173
+
174
+ for js_url in self.js_results:
175
+ result = self.js_analyzer.analyze_js(js_url)
176
+ self.endpoints.extend(result['endpoints'])
177
+ print(f" [+] {js_url[:80]}... -> {len(result['endpoints'])} 个端点")
178
+
179
+ # 去重
180
+ self.endpoints = self._deduplicate_endpoints(self.endpoints)
181
+ print(f"\n [+] 去重后:{len(self.endpoints)} 个唯一 API 端点")
182
+
183
+ # 3. 漏洞扫描
184
+ print(f"\n{'='*70}")
185
+ print(f"[+] 漏洞扫描")
186
+ print(f"{'='*70}\n")
187
+
188
+ self._scan_vulnerabilities()
189
+
190
+ # 4. 生成报告
191
+ self._generate_report(output_file)
192
+
193
+ print(f"\n{'='*70}")
194
+ print(f"测试完成!")
195
+ print(f"API 端点:{len(self.endpoints)}")
196
+ print(f"漏洞数量:{len(self.vulnerabilities)}")
197
+ print(f"{'='*70}\n")
198
+
199
+ def _crawl_with_browser(self):
200
+ """浏览器爬取"""
201
+ print(f"{'='*70}")
202
+ print(f"[+] 使用无头浏览器爬取")
203
+ print(f"{'='*70}\n")
204
+
205
+ with sync_playwright() as p:
206
+ browser = p.chromium.launch(headless=self.headless)
207
+ context = browser.new_context(viewport={'width': 1920, 'height': 1080})
208
+ page = context.new_page()
209
+
210
+ def handle_request(request):
211
+ if request.resource_type == 'script':
212
+ js_url = request.url
213
+ if '.js' in js_url and js_url not in self.js_results:
214
+ self.js_results.append(js_url)
215
+ print(f" [JS] {js_url[:100]}...")
216
+
217
+ page.on('request', handle_request)
218
+
219
+ try:
220
+ page.goto(self.target, wait_until='networkidle', timeout=30000)
221
+ page.wait_for_timeout(5000)
222
+ self._interact_with_page(page)
223
+ except Exception as e:
224
+ print(f"[!] 错误:{e}")
225
+ finally:
226
+ browser.close()
227
+
228
+ def _interact_with_page(self, page):
229
+ """页面交互"""
230
+ buttons = page.query_selector_all('button, a, input[type="button"]')
231
+ for btn in buttons[:20]:
232
+ try:
233
+ btn.click()
234
+ page.wait_for_timeout(500)
235
+ except:
236
+ pass
237
+
238
+ page.evaluate('window.scrollTo(0, document.body.scrollHeight)')
239
+ page.wait_for_timeout(1000)
240
+ page.evaluate('window.scrollTo(0, 0)')
241
+
242
+ def _deduplicate_endpoints(self, endpoints: List[APIEndpoint]) -> List[APIEndpoint]:
243
+ """去重"""
244
+ seen = set()
245
+ unique = []
246
+
247
+ for ep in endpoints:
248
+ # 标准化 URL(去掉末尾的 /)
249
+ url = ep.url.rstrip('/')
250
+ key = f"{ep.method}:{url}"
251
+
252
+ if key not in seen:
253
+ seen.add(key)
254
+ ep.url = url
255
+ unique.append(ep)
256
+
257
+ return unique
258
+
259
+ def _scan_vulnerabilities(self):
260
+ """漏洞扫描"""
261
+ print(f"[*] SQL 注入测试...")
262
+ print(f"[*] XSS 测试...")
263
+ print(f"[*] 未授权访问测试...")
264
+ print(f"[*] 敏感数据暴露测试...")
265
+
266
+ # 简化实现
267
+ vulns = []
268
+
269
+ # SQL 注入
270
+ for ep in self.endpoints[:20]:
271
+ try:
272
+ params = {'id': "' OR '1'='1"}
273
+ resp = self.session.get(ep.url, params=params, timeout=5)
274
+ if any(e in resp.text.lower() for e in ['sql syntax', 'mysql_fetch', 'ora-']):
275
+ vulns.append(Vulnerability(
276
+ type='SQL Injection',
277
+ severity='CRITICAL',
278
+ endpoint=ep.url,
279
+ evidence='SQL error detected'
280
+ ))
281
+ except:
282
+ pass
283
+
284
+ # XSS
285
+ for ep in self.endpoints[:20]:
286
+ try:
287
+ params = {'q': '<script>alert(1)</script>'}
288
+ resp = self.session.get(ep.url, params=params, timeout=5)
289
+ if '<script>alert(1)</script>' in resp.text:
290
+ vulns.append(Vulnerability(
291
+ type='XSS (Reflected)',
292
+ severity='HIGH',
293
+ endpoint=ep.url,
294
+ evidence='Payload reflected'
295
+ ))
296
+ except:
297
+ pass
298
+
299
+ # 未授权访问
300
+ for ep in self.endpoints:
301
+ if any(s in ep.url for s in ['/admin', '/api/user', '/config']):
302
+ try:
303
+ resp = self.session.get(ep.url, timeout=5)
304
+ if resp.status_code == 200 and len(resp.text) > 100:
305
+ vulns.append(Vulnerability(
306
+ type='Unauthorized Access',
307
+ severity='HIGH',
308
+ endpoint=ep.url,
309
+ evidence=f'Status: {resp.status_code}'
310
+ ))
311
+ except:
312
+ pass
313
+
314
+ self.vulnerabilities = vulns
315
+
316
+ def _generate_report(self, output_file: str):
317
+ """生成报告"""
318
+ report = f"""# 深度 API 渗透测试报告 v5.5 (完美版)
319
+
320
+ ## 执行摘要
321
+ - **测试目标**: {self.target}
322
+ - **测试时间**: {time.strftime('%Y-%m-%d %H:%M:%S')}
323
+ - **测试工具**: Deep API Tester v5.5
324
+
325
+ ## 发现统计
326
+ | 类型 | 数量 |
327
+ |------|------|
328
+ | JS 文件 | {len(self.js_results)} |
329
+ | API 端点 | {len(self.endpoints)} |
330
+ | 漏洞数量 | {len(self.vulnerabilities)} |
331
+
332
+ ## JS 文件
333
+ """
334
+ for js in self.js_results:
335
+ report += f"- `{js}`\n"
336
+
337
+ report += f"\n## API 端点 ({len(self.endpoints)} 个)\n"
338
+ for ep in self.endpoints:
339
+ report += f"- `{ep.method} {ep.url}`\n"
340
+
341
+ if self.vulnerabilities:
342
+ report += f"\n## 漏洞详情\n"
343
+ for vuln in self.vulnerabilities:
344
+ report += f"### {vuln.type}\n"
345
+ report += f"- **严重程度**: {vuln.severity}\n"
346
+ report += f"- **端点**: {vuln.endpoint}\n"
347
+ report += f"- **证据**: {vuln.evidence}\n\n"
348
+
349
+ with open(output_file, 'w', encoding='utf-8') as f:
350
+ f.write(report)
351
+
352
+ print(f"\n[+] 报告已保存:{output_file}")
353
+
354
+
355
+ if __name__ == '__main__':
356
+ import sys
357
+
358
+ if len(sys.argv) < 2:
359
+ print("Usage: python deep_api_tester_v55.py <target_url> [output_file]")
360
+ sys.exit(1)
361
+
362
+ target = sys.argv[1]
363
+ output = sys.argv[2] if len(sys.argv) > 2 else 'v55_perfect_report.md'
364
+
365
+ tester = DeepAPITesterV55(target)
366
+ tester.run_test(output)