opencode-api-security-testing 3.0.8 → 3.0.10
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/agents/api-cyber-supervisor.md +9 -3
- package/agents/api-probing-miner.md +10 -2
- package/agents/api-resource-specialist.md +44 -35
- package/agents/api-vuln-verifier.md +56 -24
- package/package.json +1 -1
- package/postinstall.mjs +1 -0
- package/preuninstall.mjs +43 -32
- package/src/index.ts +3 -100
- package/README.md +0 -74
- package/SKILL.md +0 -1797
- package/core/advanced_recon.py +0 -788
- package/core/agentic_analyzer.py +0 -445
- package/core/analyzers/api_parser.py +0 -210
- package/core/analyzers/response_analyzer.py +0 -212
- package/core/analyzers/sensitive_finder.py +0 -184
- package/core/api_fuzzer.py +0 -422
- package/core/api_interceptor.py +0 -525
- package/core/api_parser.py +0 -955
- package/core/browser_tester.py +0 -479
- package/core/cloud_storage_tester.py +0 -1330
- package/core/collectors/__init__.py +0 -23
- package/core/collectors/api_path_finder.py +0 -300
- package/core/collectors/browser_collect.py +0 -645
- package/core/collectors/browser_collector.py +0 -411
- package/core/collectors/http_client.py +0 -111
- package/core/collectors/js_collector.py +0 -490
- package/core/collectors/js_parser.py +0 -780
- package/core/collectors/url_collector.py +0 -319
- package/core/context_manager.py +0 -682
- package/core/deep_api_tester_v35.py +0 -844
- package/core/deep_api_tester_v55.py +0 -366
- package/core/dynamic_api_analyzer.py +0 -532
- package/core/http_client.py +0 -179
- package/core/models.py +0 -296
- package/core/orchestrator.py +0 -890
- package/core/prerequisite.py +0 -227
- package/core/reasoning_engine.py +0 -1042
- package/core/response_classifier.py +0 -606
- package/core/runner.py +0 -938
- package/core/scan_engine.py +0 -599
- package/core/skill_executor.py +0 -435
- package/core/skill_executor_v2.py +0 -670
- package/core/skill_executor_v3.py +0 -704
- package/core/smart_analyzer.py +0 -687
- package/core/strategy_pool.py +0 -707
- package/core/testers/auth_tester.py +0 -264
- package/core/testers/idor_tester.py +0 -200
- package/core/testers/sqli_tester.py +0 -211
- package/core/testing_loop.py +0 -655
- package/core/utils/base_path_dict.py +0 -255
- package/core/utils/payload_lib.py +0 -167
- package/core/utils/ssrf_detector.py +0 -220
- package/core/verifiers/vuln_verifier.py +0 -536
- package/references/README.md +0 -72
- package/references/asset-discovery.md +0 -119
- package/references/fuzzing-patterns.md +0 -129
- package/references/graphql-guidance.md +0 -108
- package/references/intake.md +0 -84
- package/references/pua-agent.md +0 -192
- package/references/report-template.md +0 -156
- package/references/rest-guidance.md +0 -76
- package/references/severity-model.md +0 -76
- package/references/test-matrix.md +0 -86
- package/references/validation.md +0 -78
- package/references/vulnerabilities/01-sqli-tests.md +0 -1128
- package/references/vulnerabilities/02-user-enum-tests.md +0 -423
- package/references/vulnerabilities/03-jwt-tests.md +0 -499
- package/references/vulnerabilities/04-idor-tests.md +0 -362
- package/references/vulnerabilities/05-sensitive-data-tests.md +0 -466
- package/references/vulnerabilities/06-biz-logic-tests.md +0 -501
- package/references/vulnerabilities/07-security-config-tests.md +0 -511
- package/references/vulnerabilities/08-brute-force-tests.md +0 -457
- package/references/vulnerabilities/09-vulnerability-chains.md +0 -465
- package/references/vulnerabilities/10-auth-tests.md +0 -537
- package/references/vulnerabilities/11-graphql-tests.md +0 -355
- package/references/vulnerabilities/12-ssrf-tests.md +0 -396
- package/references/vulnerabilities/README.md +0 -148
- package/references/workflows.md +0 -192
- package/src/hooks/directory-agents-injector.ts +0 -106
package/references/workflows.md
DELETED
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
# 完整扫描流程
|
|
2
|
-
|
|
3
|
-
## 场景化扫描流程
|
|
4
|
-
|
|
5
|
-
**【强制】所有扫描深度都必须使用Playwright进行JS动态采集,禁止降级**
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
【quick_scan】5分钟快速扫描
|
|
9
|
-
├─ 目标:快速发现明显漏洞
|
|
10
|
-
└─ 流程:
|
|
11
|
-
├─ HTTP/HTTPS探测 + 技术栈识别
|
|
12
|
-
├─ Playwright全流量采集(必须)
|
|
13
|
-
├─ 关键路径探测
|
|
14
|
-
└─ 快速漏洞测试
|
|
15
|
-
|
|
16
|
-
【normal_scan】20分钟标准扫描
|
|
17
|
-
├─ 目标:全面发现漏洞
|
|
18
|
-
└─ 流程:
|
|
19
|
-
├─ 所有基础探测
|
|
20
|
-
├─ Playwright全流量采集(必须)
|
|
21
|
-
├─ JS深度分析
|
|
22
|
-
├─ 关键端点测试
|
|
23
|
-
└─ 漏洞验证 + 报告输出
|
|
24
|
-
|
|
25
|
-
【deep_scan】1小时深度扫描
|
|
26
|
-
├─ 目标:完整渗透测试
|
|
27
|
-
└─ 流程:
|
|
28
|
-
├─ Playwright全流量采集(必须)
|
|
29
|
-
├─ JS深度分析(AST+正则+路径推断)
|
|
30
|
-
├─ 全量API端点测试
|
|
31
|
-
├─ 认证绕过测试矩阵
|
|
32
|
-
├─ SQL注入深入利用(判断类型+可利用性)
|
|
33
|
-
├─ 漏洞链构造
|
|
34
|
-
└─ 完整报告输出
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
## SPA应用完整采集流程
|
|
38
|
-
|
|
39
|
-
### 流程图(循环迭代模型)
|
|
40
|
-
|
|
41
|
-
```mermaid
|
|
42
|
-
flowchart TD
|
|
43
|
-
A["开始: 确定测试目标"] --> B["基础探测"]
|
|
44
|
-
B --> C{"目标可访问?"}
|
|
45
|
-
C -->|否| D["记录并尝试其他路径"]
|
|
46
|
-
D --> E{"还有未探测路径?"}
|
|
47
|
-
E -->|是| B
|
|
48
|
-
E -->|否| Z["报告: 目标不可达"]
|
|
49
|
-
C -->|是| F["识别技术栈"]
|
|
50
|
-
F --> G{"发现新资产?"}
|
|
51
|
-
G -->|是| H["创建新测试目标"]
|
|
52
|
-
H --> B
|
|
53
|
-
G -->|否| I["SPA应用?"]
|
|
54
|
-
I -->|否| J["直接探测API"]
|
|
55
|
-
J --> K["API测试"]
|
|
56
|
-
K --> L{"发现新接口?"}
|
|
57
|
-
L -->|是| M["深入分析新接口"]
|
|
58
|
-
M --> K
|
|
59
|
-
L -->|否| N{"发现新资产?"}
|
|
60
|
-
N -->|是| H
|
|
61
|
-
N -->|否| O{"发现漏洞?"}
|
|
62
|
-
I -->|是| P["全流量采集"]
|
|
63
|
-
P --> Q["JS采集"]
|
|
64
|
-
Q --> R{"发现新URL?"}
|
|
65
|
-
R -->|是| H
|
|
66
|
-
R -->|否| S["拦截XHR/Fetch"]
|
|
67
|
-
S --> T{"发现新域名?"}
|
|
68
|
-
T -->|是| H
|
|
69
|
-
T -->|否| U["深度分析JS"]
|
|
70
|
-
U --> V{"发现新API路径?"}
|
|
71
|
-
V -->|是| M
|
|
72
|
-
V -->|否| W{"发现新资产?"}
|
|
73
|
-
W -->|是| H
|
|
74
|
-
W -->|否| K
|
|
75
|
-
O -->|是| X["漏洞验证"]
|
|
76
|
-
X --> Y["输出漏洞报告"]
|
|
77
|
-
Y --> K
|
|
78
|
-
O -->|否| K
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
**核心原则**:渗透测试是**循环迭代**过程,不是线性流程!
|
|
82
|
-
|
|
83
|
-
## 阶段1:基础探测
|
|
84
|
-
|
|
85
|
-
```
|
|
86
|
-
1. HTTP探测目标可访问性
|
|
87
|
-
curl -I http://target.com
|
|
88
|
-
|
|
89
|
-
2. 技术栈识别
|
|
90
|
-
- 检查响应头Server字段
|
|
91
|
-
- 检查HTML中是否包含Vue/React/Angular关键词
|
|
92
|
-
- 检查是否包含webpack chunk引用
|
|
93
|
-
|
|
94
|
-
3. 判断是否是SPA应用
|
|
95
|
-
- /api/* 返回HTML → SPA
|
|
96
|
-
- HTML包含JS chunk路径 → Vue/React应用
|
|
97
|
-
|
|
98
|
-
4. 全流量监听
|
|
99
|
-
- 捕获所有出站请求(不只是JS)
|
|
100
|
-
- 记录所有第三方域名(CDN、分析服务等)
|
|
101
|
-
- 记录所有静态资源加载
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
## 阶段2:JS采集【强制·禁止降级】
|
|
105
|
-
|
|
106
|
-
**【禁止降级采集阶段】必须使用Playwright,不允许降级到Selenium/requests**
|
|
107
|
-
|
|
108
|
-
**【允许】分析阶段可使用curl进行补充**
|
|
109
|
-
|
|
110
|
-
```
|
|
111
|
-
【核心目标】捕获所有流量,不只分析JS文件!
|
|
112
|
-
|
|
113
|
-
1. Playwright全流量采集(必须)
|
|
114
|
-
- 使用ignore_https_errors=True处理证书问题
|
|
115
|
-
- 拦截所有请求/响应
|
|
116
|
-
- 记录流量类型(xhr/fetch/document/script/websocket)
|
|
117
|
-
|
|
118
|
-
2. 模拟用户操作(必须)
|
|
119
|
-
- 点击页面触发加载
|
|
120
|
-
- 滚动触发懒加载
|
|
121
|
-
- 填写登录表单
|
|
122
|
-
- 导航到其他页面
|
|
123
|
-
|
|
124
|
-
3. 多目标队列管理
|
|
125
|
-
TEST_QUEUE = [] # 待测试目标
|
|
126
|
-
TESTED = set() # 已测试目标
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
## 阶段3:JS深度分析
|
|
130
|
-
|
|
131
|
-
```
|
|
132
|
-
1. 提取baseURL配置(最优先!)
|
|
133
|
-
- r'baseURL\s*[:=]\s*["\']([^"\']+)["\']'
|
|
134
|
-
- r'VUE_APP_\w+["\s]*[:=]["\s]*["\']([^"\']*)["\']'
|
|
135
|
-
|
|
136
|
-
2. API端点提取
|
|
137
|
-
- r'["\'](/(?:user|auth|admin|login|logout|api|v\d)[^"\']*)["\']'
|
|
138
|
-
- r'axios\.[a-z]+\(["\']([^"\']+)["\']'
|
|
139
|
-
- r'fetch\(["\']([^"\']+)["\']'
|
|
140
|
-
|
|
141
|
-
3. 敏感信息提取
|
|
142
|
-
- IP地址、内网地址
|
|
143
|
-
- Token、API Key
|
|
144
|
-
- 外部域名
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
## 阶段4:API测试
|
|
148
|
-
|
|
149
|
-
```
|
|
150
|
-
base_path获取优先级:
|
|
151
|
-
1. 配置文件: /{app}/_app.config.js 中的 VITE_GLOB_API_URL
|
|
152
|
-
2. baseURL配置
|
|
153
|
-
3. Swagger/OpenAPI文档
|
|
154
|
-
4. nginx反向代理推测
|
|
155
|
-
5. JS路径反推
|
|
156
|
-
6. 多API共同前缀
|
|
157
|
-
7. 字典fallback
|
|
158
|
-
|
|
159
|
-
【重要】多base_path场景:
|
|
160
|
-
- 一个站点可能存在多个base_path
|
|
161
|
-
- 需要分别测试每个base_path下的端点
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
## 阶段5:漏洞验证
|
|
165
|
-
|
|
166
|
-
```
|
|
167
|
-
【多维度误报判断框架】
|
|
168
|
-
|
|
169
|
-
判断逻辑优先级:
|
|
170
|
-
1. 先看响应内容是否符合漏洞特征
|
|
171
|
-
2. 再看是否为预期响应
|
|
172
|
-
3. 最后验证利用可能性
|
|
173
|
-
|
|
174
|
-
必须先分析"正常响应应该是什么样的"
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
## 阶段6:报告输出
|
|
178
|
-
|
|
179
|
-
```
|
|
180
|
-
1. 收集测试结果
|
|
181
|
-
- 汇总所有发现的漏洞(高/中/低危)
|
|
182
|
-
- 整理API端点清单
|
|
183
|
-
- 记录安全优点
|
|
184
|
-
|
|
185
|
-
2. 利用链分析
|
|
186
|
-
- 分析独立漏洞的关联性
|
|
187
|
-
- 构建完整攻击链
|
|
188
|
-
|
|
189
|
-
3. 修复建议
|
|
190
|
-
- 按优先级排序
|
|
191
|
-
- 提供具体修复方案
|
|
192
|
-
```
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import type { PluginInput } from "@opencode-ai/plugin";
|
|
2
|
-
import { existsSync, readFileSync } from "fs";
|
|
3
|
-
import { dirname, join, resolve } from "path";
|
|
4
|
-
|
|
5
|
-
const AGENTS_FILENAME = "AGENTS.md";
|
|
6
|
-
const AGENTS_DIR = ".config/opencode/agents";
|
|
7
|
-
|
|
8
|
-
function getHomeDir(): string {
|
|
9
|
-
return process.env.HOME || process.env.USERPROFILE || "/root";
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export function createDirectoryAgentsInjectorHook(ctx: PluginInput) {
|
|
13
|
-
const injectedPaths = new Set<string>();
|
|
14
|
-
|
|
15
|
-
function resolveAgentsDir(): string | null {
|
|
16
|
-
const home = getHomeDir();
|
|
17
|
-
return join(home, AGENTS_DIR);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function findAgentsMdUp(startDir: string, agentsDir: string): string | null {
|
|
21
|
-
const home = getHomeDir();
|
|
22
|
-
let current = startDir;
|
|
23
|
-
|
|
24
|
-
while (true) {
|
|
25
|
-
const agentsPath = join(current, AGENTS_FILENAME);
|
|
26
|
-
if (existsSync(agentsPath)) {
|
|
27
|
-
return agentsPath;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
if (current === agentsDir) break;
|
|
31
|
-
const parent = dirname(current);
|
|
32
|
-
if (parent === current) break;
|
|
33
|
-
if (parent === "/" || parent === home) break;
|
|
34
|
-
current = parent;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
return null;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function getSessionKey(sessionID: string): string {
|
|
41
|
-
return `api-sec-inject-${sessionID}`;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const toolExecuteAfter = async (
|
|
45
|
-
input: { tool: string; sessionID: string; callID: string },
|
|
46
|
-
output: { title: string; output: string; metadata: unknown }
|
|
47
|
-
) => {
|
|
48
|
-
const toolName = input.tool.toLowerCase();
|
|
49
|
-
const agentsDir = resolveAgentsDir();
|
|
50
|
-
|
|
51
|
-
if (!agentsDir || !existsSync(agentsDir)) return;
|
|
52
|
-
|
|
53
|
-
if (toolName === "read") {
|
|
54
|
-
const filePath = output.title;
|
|
55
|
-
if (!filePath) return;
|
|
56
|
-
|
|
57
|
-
const resolved = resolve(filePath);
|
|
58
|
-
const dir = dirname(resolved);
|
|
59
|
-
|
|
60
|
-
if (!dir.includes(agentsDir)) return;
|
|
61
|
-
|
|
62
|
-
const cacheKey = getSessionKey(input.sessionID);
|
|
63
|
-
if (injectedPaths.has(cacheKey + resolved)) return;
|
|
64
|
-
|
|
65
|
-
const agentsPath = findAgentsMdUp(dir, agentsDir);
|
|
66
|
-
if (!agentsPath) return;
|
|
67
|
-
|
|
68
|
-
try {
|
|
69
|
-
const content = readFileSync(agentsPath, "utf-8");
|
|
70
|
-
output.output += `\n\n[Auto-injected from ${AGENTS_FILENAME}]\n${content}`;
|
|
71
|
-
injectedPaths.add(cacheKey + resolved);
|
|
72
|
-
} catch (err) {
|
|
73
|
-
console.error("[api-security-testing] Failed to inject agents:", err);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
const eventHandler = async (input: { event: { type: string; properties?: unknown } }) => {
|
|
79
|
-
const { event } = input;
|
|
80
|
-
|
|
81
|
-
if (event.type === "session.deleted" || event.type === "session.compacted") {
|
|
82
|
-
const props = event.properties as Record<string, unknown> | undefined;
|
|
83
|
-
let sessionID: string | undefined;
|
|
84
|
-
|
|
85
|
-
if (event.type === "session.deleted") {
|
|
86
|
-
sessionID = (props?.info as { id?: string })?.id;
|
|
87
|
-
} else {
|
|
88
|
-
sessionID = (props?.sessionID ?? (props?.info as { id?: string })?.id) as string | undefined;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
if (sessionID) {
|
|
92
|
-
const cacheKey = getSessionKey(sessionID);
|
|
93
|
-
for (const key of injectedPaths.keys()) {
|
|
94
|
-
if (key.startsWith(cacheKey)) {
|
|
95
|
-
injectedPaths.delete(key);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
return {
|
|
103
|
-
"tool.execute.after": toolExecuteAfter,
|
|
104
|
-
event: eventHandler,
|
|
105
|
-
};
|
|
106
|
-
}
|