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
package/package.json
CHANGED
|
@@ -1,48 +1,48 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "opencode-api-security-testing",
|
|
3
|
-
"version": "5.
|
|
4
|
-
"description": "API Security Testing Plugin for OpenCode - Automated vulnerability scanning and penetration testing",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "src/index.ts",
|
|
7
|
-
"files": [
|
|
8
|
-
"src/",
|
|
9
|
-
"agents/",
|
|
10
|
-
"core/",
|
|
11
|
-
"references/",
|
|
12
|
-
"SKILL.md",
|
|
13
|
-
"postinstall.mjs",
|
|
14
|
-
"preuninstall.mjs"
|
|
15
|
-
],
|
|
16
|
-
"scripts": {
|
|
17
|
-
"postinstall": "node postinstall.mjs",
|
|
18
|
-
"preuninstall": "node preuninstall.mjs",
|
|
19
|
-
"init": "node init.mjs"
|
|
20
|
-
},
|
|
21
|
-
"keywords": [
|
|
22
|
-
"opencode",
|
|
23
|
-
"opencode-plugin",
|
|
24
|
-
"security",
|
|
25
|
-
"api-security",
|
|
26
|
-
"pentest",
|
|
27
|
-
"vulnerability-scanning"
|
|
28
|
-
],
|
|
29
|
-
"author": "steveopen1",
|
|
30
|
-
"license": "MIT",
|
|
31
|
-
"repository": {
|
|
32
|
-
"type": "git",
|
|
33
|
-
"url": "https://github.com/steveopen1/skill-play"
|
|
34
|
-
},
|
|
35
|
-
"homepage": "https://github.com/steveopen1/skill-play/tree/main/agent-plugins/OPENCODE/api-security-testing",
|
|
36
|
-
"peerDependencies": {
|
|
37
|
-
"@opencode-ai/plugin": "^1.1.19",
|
|
38
|
-
"@opencode-ai/sdk": "^1.1.19"
|
|
39
|
-
},
|
|
40
|
-
"dependencies": {
|
|
41
|
-
"@opencode-ai/plugin": "^1.1.19",
|
|
42
|
-
"@opencode-ai/sdk": "^1.1.19"
|
|
43
|
-
},
|
|
44
|
-
"devDependencies": {
|
|
45
|
-
"@types/node": "^25.5.2",
|
|
46
|
-
"typescript": "^6.0.2"
|
|
47
|
-
}
|
|
48
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "opencode-api-security-testing",
|
|
3
|
+
"version": "5.2.1",
|
|
4
|
+
"description": "API Security Testing Plugin for OpenCode - Automated vulnerability scanning and penetration testing",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "src/index.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"src/",
|
|
9
|
+
"agents/",
|
|
10
|
+
"core/",
|
|
11
|
+
"references/",
|
|
12
|
+
"SKILL.md",
|
|
13
|
+
"postinstall.mjs",
|
|
14
|
+
"preuninstall.mjs"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"postinstall": "node postinstall.mjs",
|
|
18
|
+
"preuninstall": "node preuninstall.mjs",
|
|
19
|
+
"init": "node init.mjs"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"opencode",
|
|
23
|
+
"opencode-plugin",
|
|
24
|
+
"security",
|
|
25
|
+
"api-security",
|
|
26
|
+
"pentest",
|
|
27
|
+
"vulnerability-scanning"
|
|
28
|
+
],
|
|
29
|
+
"author": "steveopen1",
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "https://github.com/steveopen1/skill-play"
|
|
34
|
+
},
|
|
35
|
+
"homepage": "https://github.com/steveopen1/skill-play/tree/main/agent-plugins/OPENCODE/api-security-testing",
|
|
36
|
+
"peerDependencies": {
|
|
37
|
+
"@opencode-ai/plugin": "^1.1.19",
|
|
38
|
+
"@opencode-ai/sdk": "^1.1.19"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@opencode-ai/plugin": "^1.1.19",
|
|
42
|
+
"@opencode-ai/sdk": "^1.1.19"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@types/node": "^25.5.2",
|
|
46
|
+
"typescript": "^6.0.2"
|
|
47
|
+
}
|
|
48
|
+
}
|
package/postinstall.mjs
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* postinstall.mjs - API Security Testing Plugin
|
|
3
5
|
*
|
|
4
6
|
* Installs:
|
|
5
|
-
* 1. agents to ~/.
|
|
6
|
-
* 2.
|
|
7
|
-
* 3. SKILL.md and references to ~/.config/opencode/skills/api-security-testing/
|
|
7
|
+
* 1. agents to ~/.config/opencode/agents/
|
|
8
|
+
* 2. SKILL.md and references to ~/.config/opencode/skills/api-security-testing/
|
|
8
9
|
*/
|
|
9
10
|
|
|
10
11
|
import { copyFileSync, existsSync, mkdirSync, readdirSync } from "node:fs";
|
|
@@ -19,42 +20,11 @@ function getOpencodeBaseDir() {
|
|
|
19
20
|
return join(home, ".config", "opencode");
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
function getClaudeBaseDir() {
|
|
23
|
-
const home = process.env.HOME || process.env.USERPROFILE || "/root";
|
|
24
|
-
return join(home, ".claude");
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function copyDirRecursive(src, dest) {
|
|
28
|
-
if (!existsSync(dest)) {
|
|
29
|
-
mkdirSync(dest, { recursive: true });
|
|
30
|
-
}
|
|
31
|
-
const items = readdirSync(src, { withFileTypes: true });
|
|
32
|
-
let count = 0;
|
|
33
|
-
for (const item of items) {
|
|
34
|
-
const srcPath = join(src, item.name);
|
|
35
|
-
const destPath = join(dest, item.name);
|
|
36
|
-
try {
|
|
37
|
-
if (item.isDirectory()) {
|
|
38
|
-
copyDirRecursive(srcPath, destPath);
|
|
39
|
-
} else {
|
|
40
|
-
copyFileSync(srcPath, destPath);
|
|
41
|
-
count++;
|
|
42
|
-
}
|
|
43
|
-
} catch (err) {
|
|
44
|
-
console.error(` ✗ ${item.name}: ${err.message}`);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
return count;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
23
|
function main() {
|
|
51
24
|
const packageRoot = __dirname;
|
|
52
25
|
const agentsSourceDir = join(packageRoot, "agents");
|
|
53
|
-
const
|
|
54
|
-
const
|
|
55
|
-
const opencodeAgentsDir = join(opencodeBaseDir, "agents");
|
|
56
|
-
const claudeAgentsDir = join(claudeBaseDir, "agents");
|
|
57
|
-
const skillTargetDir = join(opencodeBaseDir, "skills", "api-security-testing");
|
|
26
|
+
const agentsTargetDir = join(getOpencodeBaseDir(), "agents");
|
|
27
|
+
const skillTargetDir = join(getOpencodeBaseDir(), "skills", "api-security-testing");
|
|
58
28
|
|
|
59
29
|
console.log("[api-security-testing] Installing...");
|
|
60
30
|
console.log(` Package root: ${packageRoot}`);
|
|
@@ -62,17 +32,17 @@ function main() {
|
|
|
62
32
|
let totalInstalled = 0;
|
|
63
33
|
let totalFailed = 0;
|
|
64
34
|
|
|
65
|
-
// 1. Install agents
|
|
66
|
-
console.log("\n[1/
|
|
35
|
+
// 1. Install agents
|
|
36
|
+
console.log("\n[1/3] Installing agents...");
|
|
67
37
|
if (existsSync(agentsSourceDir)) {
|
|
68
|
-
if (!existsSync(
|
|
69
|
-
mkdirSync(
|
|
38
|
+
if (!existsSync(agentsTargetDir)) {
|
|
39
|
+
mkdirSync(agentsTargetDir, { recursive: true });
|
|
70
40
|
}
|
|
71
41
|
|
|
72
42
|
const files = readdirSync(agentsSourceDir).filter(f => f.endsWith(".md"));
|
|
73
43
|
for (const file of files) {
|
|
74
44
|
try {
|
|
75
|
-
copyFileSync(join(agentsSourceDir, file), join(
|
|
45
|
+
copyFileSync(join(agentsSourceDir, file), join(agentsTargetDir, file));
|
|
76
46
|
console.log(` ✓ ${file}`);
|
|
77
47
|
totalInstalled++;
|
|
78
48
|
} catch (err) {
|
|
@@ -82,27 +52,8 @@ function main() {
|
|
|
82
52
|
}
|
|
83
53
|
}
|
|
84
54
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
if (!existsSync(opencodeAgentsDir)) {
|
|
88
|
-
mkdirSync(opencodeAgentsDir, { recursive: true });
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
const files = readdirSync(agentsSourceDir).filter(f => f.endsWith(".md"));
|
|
92
|
-
for (const file of files) {
|
|
93
|
-
try {
|
|
94
|
-
copyFileSync(join(agentsSourceDir, file), join(opencodeAgentsDir, file));
|
|
95
|
-
console.log(` ✓ ${file}`);
|
|
96
|
-
totalInstalled++;
|
|
97
|
-
} catch (err) {
|
|
98
|
-
console.error(` ✗ ${file}: ${err.message}`);
|
|
99
|
-
totalFailed++;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// 3. Install SKILL.md
|
|
105
|
-
console.log("\n[3/4] Installing SKILL.md...");
|
|
55
|
+
// 2. Install SKILL.md
|
|
56
|
+
console.log("\n[2/3] Installing SKILL.md...");
|
|
106
57
|
const skillSource = join(packageRoot, "SKILL.md");
|
|
107
58
|
if (existsSync(skillSource)) {
|
|
108
59
|
if (!existsSync(skillTargetDir)) {
|
|
@@ -118,15 +69,36 @@ function main() {
|
|
|
118
69
|
}
|
|
119
70
|
}
|
|
120
71
|
|
|
121
|
-
//
|
|
122
|
-
console.log("\n[
|
|
72
|
+
// 3. Install references
|
|
73
|
+
console.log("\n[3/3] Installing references...");
|
|
123
74
|
const refsSourceDir = join(packageRoot, "references");
|
|
124
75
|
const refsTargetDir = join(skillTargetDir, "references");
|
|
125
76
|
if (existsSync(refsSourceDir)) {
|
|
77
|
+
if (!existsSync(refsTargetDir)) {
|
|
78
|
+
mkdirSync(refsTargetDir, { recursive: true });
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function copyDir(src, dest) {
|
|
82
|
+
const items = readdirSync(src);
|
|
83
|
+
for (const item of items) {
|
|
84
|
+
const srcPath = join(src, item);
|
|
85
|
+
const destPath = join(dest, item);
|
|
86
|
+
try {
|
|
87
|
+
copyFileSync(srcPath, destPath);
|
|
88
|
+
totalInstalled++;
|
|
89
|
+
} catch {
|
|
90
|
+
if (existsSync(srcPath) && !srcPath.endsWith(".md")) {
|
|
91
|
+
mkdirSync(destPath, { recursive: true });
|
|
92
|
+
copyDir(srcPath, destPath);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
126
98
|
try {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
99
|
+
copyDir(refsSourceDir, refsTargetDir);
|
|
100
|
+
console.log(" ✓ references/");
|
|
101
|
+
totalInstalled++;
|
|
130
102
|
} catch (err) {
|
|
131
103
|
console.error(` ✗ references/: ${err.message}`);
|
|
132
104
|
totalFailed++;
|
|
@@ -136,8 +108,7 @@ function main() {
|
|
|
136
108
|
console.log(`\n========================================`);
|
|
137
109
|
if (totalFailed === 0) {
|
|
138
110
|
console.log(`✓ Installed ${totalInstalled} file(s)`);
|
|
139
|
-
console.log(`\nAgents
|
|
140
|
-
console.log(`Agents (OpenCode native): ${opencodeAgentsDir}`);
|
|
111
|
+
console.log(`\nAgents: ${agentsTargetDir}`);
|
|
141
112
|
console.log(`Skill: ${skillTargetDir}`);
|
|
142
113
|
console.log(`\n⚠️ IMPORTANT: Restart OpenCode to discover new agents`);
|
|
143
114
|
} else {
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
# API Security Testing 参考资源
|
|
2
|
-
|
|
3
|
-
## 核心文件
|
|
4
|
-
|
|
5
|
-
| 文件 | 内容 |
|
|
6
|
-
|------|------|
|
|
7
|
-
| `pua-agent.md` | PUA自动测试Agent,强制深入不放弃 |
|
|
8
|
-
| `fuzzing-patterns.md` | API Fuzzing字典 |
|
|
9
|
-
| `report-template.md` | 安全测试报告模板 |
|
|
10
|
-
|
|
11
|
-
## vulnerabilities/ 漏洞测试方法
|
|
12
|
-
|
|
13
|
-
| 文件 | 内容 |
|
|
14
|
-
|------|------|
|
|
15
|
-
| `vulnerabilities/01-sqli-tests.md` | SQL注入测试 + WAF绕过 |
|
|
16
|
-
| `vulnerabilities/02-user-enum-tests.md` | 用户枚举测试 |
|
|
17
|
-
| `vulnerabilities/03-jwt-tests.md` | JWT认证测试 |
|
|
18
|
-
| `vulnerabilities/04-idor-tests.md` | IDOR越权测试 |
|
|
19
|
-
| `vulnerabilities/05-sensitive-data-tests.md` | 敏感信息泄露 |
|
|
20
|
-
| `vulnerabilities/06-biz-logic-tests.md` | 业务逻辑漏洞 |
|
|
21
|
-
| `vulnerabilities/07-security-config-tests.md` | 安全配置漏洞 |
|
|
22
|
-
| `vulnerabilities/08-brute-force-tests.md` | 暴力破解测试 |
|
|
23
|
-
| `vulnerabilities/09-vulnerability-chains.md` | 漏洞关联联想 |
|
|
24
|
-
| `vulnerabilities/10-auth-tests.md` | OAuth/SAML/2FA测试 |
|
|
25
|
-
| `vulnerabilities/11-graphql-tests.md` | GraphQL安全测试 |
|
|
26
|
-
| `vulnerabilities/12-ssrf-tests.md` | SSRF测试 |
|
|
27
|
-
|
|
28
|
-
## PUA Agent 使用
|
|
29
|
-
|
|
30
|
-
### 核心思想
|
|
31
|
-
|
|
32
|
-
```
|
|
33
|
-
【PUA自动模式】
|
|
34
|
-
- 发现线索 → 自动深入
|
|
35
|
-
- 不等待用户指令
|
|
36
|
-
- 压力升级直到完成
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
### 压力升级机制
|
|
40
|
-
|
|
41
|
-
| 失败次数 | 级别 | 行动 |
|
|
42
|
-
|---------|------|------|
|
|
43
|
-
| 1次 | L1 | 换方法继续 |
|
|
44
|
-
| 2次 | L2 | 强制检查清单 |
|
|
45
|
-
| 3次 | L3 | 报告进度并继续 |
|
|
46
|
-
| 4次+ | L4 | 尝试其他方向 |
|
|
47
|
-
|
|
48
|
-
### 不放弃原则
|
|
49
|
-
|
|
50
|
-
```
|
|
51
|
-
遇到以下情况必须继续:
|
|
52
|
-
□ 端点404 → 尝试POST方法
|
|
53
|
-
□ 被WAF拦截 → 换payload
|
|
54
|
-
□ 返回HTML → 继续API测试
|
|
55
|
-
□ 找不到配置 → 搜索其他JS
|
|
56
|
-
□ 一个端点失败 → 测试同类端点
|
|
57
|
-
□ 说"无法测试" → 必须穷举所有方法
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
### 进度追踪表
|
|
61
|
-
|
|
62
|
-
```
|
|
63
|
-
阶段1: [████████░░] 80%
|
|
64
|
-
阶段2: [████░░░░░░░] 40%
|
|
65
|
-
阶段3: [░░░░░░░░░░░] 0%
|
|
66
|
-
阶段4: [░░░░░░░░░░░] 0%
|
|
67
|
-
|
|
68
|
-
发现:
|
|
69
|
-
├─ CORS漏洞: 18个端点
|
|
70
|
-
├─ SQL注入: 待测试
|
|
71
|
-
└─ 新线索: /ipark-wxlite/*
|
|
72
|
-
```
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
# Asset Discovery Guidance
|
|
2
|
-
|
|
3
|
-
将原始 API 材料转换为紧凑的安全相关清单。
|
|
4
|
-
|
|
5
|
-
## 目标
|
|
6
|
-
|
|
7
|
-
识别对安全测试最重要的 API 部分。
|
|
8
|
-
|
|
9
|
-
## 核心表面
|
|
10
|
-
|
|
11
|
-
- base URL(s)
|
|
12
|
-
- versioning scheme
|
|
13
|
-
- routes 或 operations
|
|
14
|
-
- methods
|
|
15
|
-
- content types
|
|
16
|
-
- auth schemes
|
|
17
|
-
|
|
18
|
-
## 信任边界
|
|
19
|
-
|
|
20
|
-
- public vs authenticated endpoints
|
|
21
|
-
- user vs admin operations
|
|
22
|
-
- internal vs external APIs
|
|
23
|
-
- service-to-service 或 callback flows
|
|
24
|
-
- tenant 或 organization 边界
|
|
25
|
-
|
|
26
|
-
## 敏感对象
|
|
27
|
-
|
|
28
|
-
关注以下对象:
|
|
29
|
-
- users
|
|
30
|
-
- roles
|
|
31
|
-
- teams
|
|
32
|
-
- organizations
|
|
33
|
-
- invoices
|
|
34
|
-
- payments
|
|
35
|
-
- orders
|
|
36
|
-
- files
|
|
37
|
-
- secrets
|
|
38
|
-
- API keys
|
|
39
|
-
- tokens
|
|
40
|
-
- audit logs
|
|
41
|
-
- exports
|
|
42
|
-
- configuration objects
|
|
43
|
-
|
|
44
|
-
## 高风险操作模式
|
|
45
|
-
|
|
46
|
-
标记与以下相关的 endpoints 或 mutations:
|
|
47
|
-
- create/update/delete user
|
|
48
|
-
- role assignment
|
|
49
|
-
- permission change
|
|
50
|
-
- password reset
|
|
51
|
-
- token issue 或 refresh
|
|
52
|
-
- export 或 bulk download
|
|
53
|
-
- import 或 bulk update
|
|
54
|
-
- file upload
|
|
55
|
-
- webhook registration
|
|
56
|
-
- callback URL configuration
|
|
57
|
-
- search 或 filter on sensitive entities
|
|
58
|
-
- internal admin dashboards 或 debug endpoints
|
|
59
|
-
|
|
60
|
-
## REST 提示
|
|
61
|
-
|
|
62
|
-
优先包含模式的 endpoints:
|
|
63
|
-
- `/admin`
|
|
64
|
-
- `/internal`
|
|
65
|
-
- `/users`
|
|
66
|
-
- `/roles`
|
|
67
|
-
- `/permissions`
|
|
68
|
-
- `/export`
|
|
69
|
-
- `/import`
|
|
70
|
-
- `/search`
|
|
71
|
-
- `/upload`
|
|
72
|
-
- `/files`
|
|
73
|
-
- `/billing`
|
|
74
|
-
- `/settings`
|
|
75
|
-
- `/token`
|
|
76
|
-
- `/auth`
|
|
77
|
-
- `/debug`
|
|
78
|
-
|
|
79
|
-
同时注意:
|
|
80
|
-
- bulk 操作
|
|
81
|
-
- object IDs in path 或 query
|
|
82
|
-
- 同一资源上隐藏的替代方法
|
|
83
|
-
- 不一致的版本化 endpoints
|
|
84
|
-
|
|
85
|
-
## GraphQL 提示
|
|
86
|
-
|
|
87
|
-
优先:
|
|
88
|
-
- 变更 roles、permissions 或 state 的 mutations
|
|
89
|
-
- 暴露嵌套对象遍历的 fields
|
|
90
|
-
- admin-only resolvers
|
|
91
|
-
- schema introspection 暴露
|
|
92
|
-
- 带敏感链接数据的宽对象图
|
|
93
|
-
- 可能意外扩展访问的 connection 或 pagination 模式
|
|
94
|
-
|
|
95
|
-
## 资产摘要格式
|
|
96
|
-
|
|
97
|
-
优先简洁输出:
|
|
98
|
-
|
|
99
|
-
```
|
|
100
|
-
- Base URLs:
|
|
101
|
-
- API type:
|
|
102
|
-
- Auth schemes:
|
|
103
|
-
- Roles observed or assumed:
|
|
104
|
-
- Sensitive objects:
|
|
105
|
-
- High-risk operations:
|
|
106
|
-
- Trust boundaries:
|
|
107
|
-
- Unknown areas:
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
## 优先级规则
|
|
111
|
-
|
|
112
|
-
当表面较大时,优先深度在:
|
|
113
|
-
1. auth 和 role 变更
|
|
114
|
-
2. user 和 tenant 数据
|
|
115
|
-
3. export/import 和 bulk 操作
|
|
116
|
-
4. file 和 callback 流程
|
|
117
|
-
5. 金融或行政操作
|
|
118
|
-
|
|
119
|
-
不要在低风险的只读 metadata endpoints 上浪费空间,除非它们支持更广泛的滥用路径。
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
# Fuzzing 字典
|
|
2
|
-
|
|
3
|
-
## API前缀字典
|
|
4
|
-
|
|
5
|
-
```python
|
|
6
|
-
common_api_prefixes = [
|
|
7
|
-
# 协议/网关
|
|
8
|
-
"/gateway", "/proxy", "/route", "/ingress",
|
|
9
|
-
"/api-gateway", "/openapi", "/open/api",
|
|
10
|
-
# 版本前缀
|
|
11
|
-
"/v1", "/v2", "/v3", "/v4", "/v5",
|
|
12
|
-
"/api/v1", "/api/v2", "/api/v3",
|
|
13
|
-
"/rest", "/rest/api", "/graphql",
|
|
14
|
-
# 管理后台
|
|
15
|
-
"/admin", "/admin/api", "/manager", "/backend",
|
|
16
|
-
"/backoffice", "/cms",
|
|
17
|
-
# 业务模块
|
|
18
|
-
"/user", "/users", "/member", "/members",
|
|
19
|
-
"/order", "/orders", "/trade", "/transaction",
|
|
20
|
-
"/product", "/goods", "/shop", "/store",
|
|
21
|
-
"/payment", "/pay", "/finance", "/account",
|
|
22
|
-
"/file", "/upload", "/oss", "/storage",
|
|
23
|
-
"/message", "/notify", "/sms", "/email",
|
|
24
|
-
"/admin", "/authority", "/system", "/config",
|
|
25
|
-
# 微服务
|
|
26
|
-
"/service", "/services", "/rpc", "/grpc",
|
|
27
|
-
"/auth", "/oauth", "/sso", "/cas",
|
|
28
|
-
# 移动端
|
|
29
|
-
"/mobile", "/app", "/ios", "/android",
|
|
30
|
-
"/miniapp", "/wechat", "/applet",
|
|
31
|
-
]
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
## API端点字典
|
|
35
|
-
|
|
36
|
-
```python
|
|
37
|
-
common_api_endpoints = [
|
|
38
|
-
# 通用CRUD
|
|
39
|
-
"login", "logout", "register", "list", "add", "delete", "modify",
|
|
40
|
-
"getList", "getListOfPage", "detail", "getInfo", "profile",
|
|
41
|
-
# 用户相关
|
|
42
|
-
"user", "user/list", "user/add", "user/delete", "user/modify",
|
|
43
|
-
"user/profile", "user/restPassword", "user/enable", "user/disable",
|
|
44
|
-
# 角色权限
|
|
45
|
-
"role", "role/list", "role/add", "role/delete", "role/modify",
|
|
46
|
-
"menu", "menu/list", "menu/add", "menu/delete", "menu/modify",
|
|
47
|
-
# 文件操作
|
|
48
|
-
"file", "upload", "download", "import", "export",
|
|
49
|
-
"imgUpload", "avatar", "attachment",
|
|
50
|
-
]
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
## Fuzzing测试流程
|
|
54
|
-
|
|
55
|
-
```python
|
|
56
|
-
for prefix in common_api_prefixes:
|
|
57
|
-
for endpoint in common_api_endpoints:
|
|
58
|
-
url = target + prefix + "/" + endpoint
|
|
59
|
-
response = requests.get(url)
|
|
60
|
-
# 记录返回200的接口
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
## API根路径探测
|
|
64
|
-
|
|
65
|
-
```python
|
|
66
|
-
root_paths = [
|
|
67
|
-
"/", "/login", "/auth", "/oauth", "/sso", "/cas",
|
|
68
|
-
"/health", "/healthz", "/ready", "/status", "/info",
|
|
69
|
-
"/metrics", "/ping", "/actuator",
|
|
70
|
-
]
|
|
71
|
-
|
|
72
|
-
for path in root_paths:
|
|
73
|
-
url = api_base + path
|
|
74
|
-
response = requests.get(url)
|
|
75
|
-
if "json" in response.headers.get("Content-Type", ""):
|
|
76
|
-
# 发现可访问的接口
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
## 业务端点模板扩展
|
|
80
|
-
|
|
81
|
-
```
|
|
82
|
-
发现的模式: /{module}/{operation}
|
|
83
|
-
可能存在的端点:
|
|
84
|
-
- /{module}/list → 列表查询
|
|
85
|
-
- /{module}/add → 新增创建
|
|
86
|
-
- /{module}/modify → 修改更新
|
|
87
|
-
- /{module}/delete → 删除操作
|
|
88
|
-
- /{module}/detail → 详情查看
|
|
89
|
-
- /{module}/getInfo → 信息获取
|
|
90
|
-
- /{module}/export → 导出数据
|
|
91
|
-
- /{module}/import → 导入数据
|
|
92
|
-
|
|
93
|
-
RESTful风格:
|
|
94
|
-
- GET /{resource}/{id} → 获取详情
|
|
95
|
-
- PUT /{resource}/{id} → 完整更新
|
|
96
|
-
- DELETE /{resource}/{id} → 删除资源
|
|
97
|
-
- PATCH /{resource}/{id} → 部分更新
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
## 非通用base_path字典
|
|
101
|
-
|
|
102
|
-
```python
|
|
103
|
-
extended_base_paths = [
|
|
104
|
-
# 协议/网关
|
|
105
|
-
"/gateway", "/proxy", "/route", "/ingress",
|
|
106
|
-
"/api-gateway", "/openapi", "/open/api",
|
|
107
|
-
# 版本前缀
|
|
108
|
-
"/v1", "/v2", "/v3", "/v4", "/v5",
|
|
109
|
-
"/api/v1", "/api/v2", "/api/v3",
|
|
110
|
-
"/rest", "/rest/api", "/graphql",
|
|
111
|
-
# 管理后台
|
|
112
|
-
"/admin", "/manager", "/manage", "/console",
|
|
113
|
-
"/backend", "/backoffice", "/cms",
|
|
114
|
-
# 业务模块
|
|
115
|
-
"/user", "/users", "/member", "/members",
|
|
116
|
-
"/order", "/orders", "/trade", "/transaction",
|
|
117
|
-
"/product", "/goods", "/shop", "/store",
|
|
118
|
-
"/payment", "/pay", "/finance", "/account",
|
|
119
|
-
"/file", "/upload", "/oss", "/storage",
|
|
120
|
-
"/message", "/notify", "/sms", "/email",
|
|
121
|
-
"/admin", "/authority", "/system", "/config",
|
|
122
|
-
# 微服务
|
|
123
|
-
"/service", "/services", "/rpc", "/grpc",
|
|
124
|
-
"/auth", "/oauth", "/sso", "/cas",
|
|
125
|
-
# 移动端
|
|
126
|
-
"/mobile", "/app", "/ios", "/android",
|
|
127
|
-
"/miniapp", "/wechat", "/applet",
|
|
128
|
-
]
|
|
129
|
-
```
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
# GraphQL Guidance
|
|
2
|
-
|
|
3
|
-
分析 GraphQL API 时使用。
|
|
4
|
-
|
|
5
|
-
## 关注领域
|
|
6
|
-
|
|
7
|
-
### 字段级授权
|
|
8
|
-
|
|
9
|
-
- resolver 是否正确检查权限
|
|
10
|
-
- 嵌套查询是否泄露数据
|
|
11
|
-
- 是否缺少 admin-only 字段
|
|
12
|
-
|
|
13
|
-
### 嵌套遍历
|
|
14
|
-
|
|
15
|
-
- `type User { friends: [User!]! }` 可导致递归查询
|
|
16
|
-
- `type Post { author: User }` 允许遍历
|
|
17
|
-
- 是否限制遍历深度
|
|
18
|
-
|
|
19
|
-
### Resolver 边界
|
|
20
|
-
|
|
21
|
-
- 一个 resolver 是否调用另一个 service
|
|
22
|
-
- 是否存在 SSRF 风险
|
|
23
|
-
- 是否有命令注入点
|
|
24
|
-
|
|
25
|
-
### Mutation 滥用
|
|
26
|
-
|
|
27
|
-
- 未经授权的状态变更
|
|
28
|
-
- 条件 mutation(如 admin-only mutation)
|
|
29
|
-
- 批量 mutation 导致的问题
|
|
30
|
-
|
|
31
|
-
### Introspection 暴露
|
|
32
|
-
|
|
33
|
-
- 是否禁用 introspection
|
|
34
|
-
- 是否暴露敏感字段
|
|
35
|
-
- Schema 文档是否包含敏感信息
|
|
36
|
-
|
|
37
|
-
## 常见风险信号
|
|
38
|
-
|
|
39
|
-
- ` IntrospectionQuery` 可访问
|
|
40
|
-
- 缺少 query 复杂度限制
|
|
41
|
-
- 缺少 query 深度限制
|
|
42
|
-
- 缺少字段权限检查
|
|
43
|
-
- mutation 接受任意输入
|
|
44
|
-
- 嵌套查询无限制
|
|
45
|
-
|
|
46
|
-
## 测试重点
|
|
47
|
-
|
|
48
|
-
### 1. 枚举攻击
|
|
49
|
-
|
|
50
|
-
```graphql
|
|
51
|
-
# 枚举所有用户
|
|
52
|
-
query {
|
|
53
|
-
users {
|
|
54
|
-
id
|
|
55
|
-
username
|
|
56
|
-
email
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
### 2. 嵌套遍历
|
|
62
|
-
|
|
63
|
-
```graphql
|
|
64
|
-
# 递归遍历 friendships
|
|
65
|
-
query {
|
|
66
|
-
user(id: 1) {
|
|
67
|
-
friends {
|
|
68
|
-
friends {
|
|
69
|
-
friends {
|
|
70
|
-
id
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
### 3. 权限绕过
|
|
79
|
-
|
|
80
|
-
```graphql
|
|
81
|
-
# 尝试 admin 字段
|
|
82
|
-
query {
|
|
83
|
-
user(id: 1) {
|
|
84
|
-
isAdmin
|
|
85
|
-
role
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
### 4. mutation 滥用
|
|
91
|
-
|
|
92
|
-
```graphql
|
|
93
|
-
# 未经授权的 mutation
|
|
94
|
-
mutation {
|
|
95
|
-
updateUser(id: 1, role: "admin") {
|
|
96
|
-
id
|
|
97
|
-
role
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
## 防护检查
|
|
103
|
-
|
|
104
|
-
- [ ] 是否限制查询复杂度
|
|
105
|
-
- [ ] 是否限制查询深度
|
|
106
|
-
- [ ] 是否禁用 introspection
|
|
107
|
-
- [ ] resolver 是否有权限检查
|
|
108
|
-
- [ ] 是否过滤敏感字段
|