opencode-api-security-testing 4.0.1 → 5.0.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 (29) hide show
  1. package/package.json +48 -47
  2. package/postinstall.mjs +69 -40
  3. package/references/references/README.md +72 -0
  4. package/references/references/asset-discovery.md +119 -0
  5. package/references/references/fuzzing-patterns.md +129 -0
  6. package/references/references/graphql-guidance.md +108 -0
  7. package/references/references/intake.md +84 -0
  8. package/references/references/pua-agent.md +192 -0
  9. package/references/references/report-template.md +156 -0
  10. package/references/references/rest-guidance.md +76 -0
  11. package/references/references/severity-model.md +76 -0
  12. package/references/references/test-matrix.md +86 -0
  13. package/references/references/validation.md +78 -0
  14. package/references/references/vulnerabilities/01-sqli-tests.md +1128 -0
  15. package/references/references/vulnerabilities/02-user-enum-tests.md +423 -0
  16. package/references/references/vulnerabilities/03-jwt-tests.md +499 -0
  17. package/references/references/vulnerabilities/04-idor-tests.md +362 -0
  18. package/references/references/vulnerabilities/05-sensitive-data-tests.md +466 -0
  19. package/references/references/vulnerabilities/06-biz-logic-tests.md +501 -0
  20. package/references/references/vulnerabilities/07-security-config-tests.md +511 -0
  21. package/references/references/vulnerabilities/08-brute-force-tests.md +457 -0
  22. package/references/references/vulnerabilities/09-vulnerability-chains.md +465 -0
  23. package/references/references/vulnerabilities/10-auth-tests.md +537 -0
  24. package/references/references/vulnerabilities/11-graphql-tests.md +355 -0
  25. package/references/references/vulnerabilities/12-ssrf-tests.md +396 -0
  26. package/references/references/vulnerabilities/README.md +148 -0
  27. package/references/references/workflows.md +192 -0
  28. package/src/index.ts +153 -25
  29. package/src/src/index.ts +535 -0
@@ -0,0 +1,501 @@
1
+ # 业务逻辑漏洞测试
2
+
3
+ ## 1. 概述
4
+
5
+ 业务逻辑漏洞是指利用业务逻辑流程中的缺陷实现的攻击,如支付篡改、条件竞争、业务流程绕过等。
6
+
7
+ **危险等级**: 高
8
+
9
+ ## 2. 支付篡改
10
+
11
+ ### 2.1 测试点
12
+
13
+ | 接口 | 示例 |
14
+ |------|------|
15
+ | 支付下单 | `POST /api/pay` |
16
+ | 订单创建 | `POST /api/order` |
17
+ | 价格计算 | `GET /api/price` |
18
+ | 优惠券 | `POST /api/coupon/apply` |
19
+
20
+ ### 2.2 测试方法
21
+
22
+ ```bash
23
+ # 1. 金额篡改
24
+ POST /api/pay
25
+ {
26
+ "orderId": "ORDER123",
27
+ "amount": "0.01" # 尝试极小金额
28
+ }
29
+
30
+ # 2. 数量篡改
31
+ POST /api/order
32
+ {
33
+ "goodsId": "1",
34
+ "count": "-1" # 负数数量
35
+ }
36
+
37
+ # 3. 单价篡改
38
+ POST /api/order
39
+ {
40
+ "goodsId": "1",
41
+ "price": "0.01",
42
+ "count": 1
43
+ }
44
+
45
+ # 4. 汇率篡改
46
+ POST /api/pay
47
+ {
48
+ "orderId": "ORDER123",
49
+ "currency": "USD",
50
+ "amount": "0.01" # 使用低汇率币种
51
+ }
52
+
53
+ # 5. 状态篡改
54
+ POST /api/order/status
55
+ {
56
+ "orderId": "ORDER123",
57
+ "status": "paid" # 直接设为已付款
58
+ }
59
+ ```
60
+
61
+ ### 2.3 防护检查
62
+
63
+ ```bash
64
+ # 检查后端是否验证
65
+ # 1. 重新计算金额
66
+ # 2. 校验数量>0
67
+ # 3. 使用服务端汇率
68
+ # 4. 状态机校验
69
+ ```
70
+
71
+ ## 3. 条件竞争
72
+
73
+ ### 3.1 测试场景
74
+
75
+ | 场景 | 风险 |
76
+ |------|------|
77
+ | 优惠券领取 | 多次领取 |
78
+ | 库存扣减 | 超卖 |
79
+ | 余额扣款 | 重复扣款 |
80
+ | 积分增加 | 重复增加 |
81
+
82
+ ### 3.2 测试方法
83
+
84
+ ```python
85
+ import threading
86
+ import requests
87
+
88
+ def send_request():
89
+ response = requests.post(
90
+ "http://api/coupon/receive",
91
+ json={"couponId": "1"},
92
+ headers={"Authorization": "Bearer xxx"}
93
+ )
94
+ return response.json()
95
+
96
+ # 100并发请求
97
+ threads = []
98
+ for i in range(100):
99
+ t = threading.Thread(target=send_request)
100
+ threads.append(t)
101
+ t.start()
102
+
103
+ for t in threads:
104
+ t.join()
105
+
106
+ # 检查有多少人成功领取
107
+ # 应该只有1个成功
108
+ # 如果>1个 → 存在条件竞争漏洞
109
+ ```
110
+
111
+ ### 3.3 线程池并发
112
+
113
+ ```python
114
+ from concurrent.futures import ThreadPoolExecutor
115
+
116
+ def send_request():
117
+ # 请求逻辑
118
+ pass
119
+
120
+ with ThreadPoolExecutor(max_workers=100) as executor:
121
+ futures = [executor.submit(send_request) for _ in range(100)]
122
+ results = [f.result() for f in futures]
123
+ ```
124
+
125
+ ## 4. 业务流程绕过
126
+
127
+ ### 4.1 测试场景
128
+
129
+ ```bash
130
+ # 1. 跳过验证步骤
131
+ # 正常流程:选择商品 → 填写信息 → 支付 → 验证 → 完成
132
+ # 绕过:选择商品 → 支付 → 验证(跳过)
133
+
134
+ POST /api/order/complete
135
+ {"orderId": "ORDER123", "step": "verified"}
136
+
137
+ # 2. 跳过短信验证
138
+ POST /api/register
139
+ {
140
+ "username": "test",
141
+ "phone": "13800138000",
142
+ "smsCode": "000000" # 尝试空或伪造
143
+ }
144
+
145
+ # 3. 跳过图形验证码
146
+ POST /api/login
147
+ {
148
+ "username": "admin",
149
+ "password": "xxx",
150
+ "captcha": "" # 尝试为空
151
+ }
152
+ ```
153
+
154
+ ### 4.2 状态机绕过
155
+
156
+ ```bash
157
+ # 订单状态:pending → paid → shipped → completed
158
+ # 尝试跳过中间状态
159
+
160
+ POST /api/order/update
161
+ {"orderId": "123", "status": "shipped"} # 未支付就发货
162
+ ```
163
+
164
+ ## 5. 暴力破解(业务维度)
165
+
166
+ ### 5.1 优惠券码
167
+
168
+ ```python
169
+ # 6位数字优惠券:100000-999999
170
+ for i in range(100000, 100010):
171
+ code = f"{i:06d}"
172
+ resp = requests.post(
173
+ "http://api/coupon/use",
174
+ json={"code": code}
175
+ )
176
+ ```
177
+
178
+ ### 5.2 订单号预测
179
+
180
+ ```bash
181
+ # 如果订单号是顺序的
182
+ # ORDER1234567890
183
+ # ORDER1234567891
184
+ # ORDER1234567892
185
+
186
+ for i in range(10):
187
+ order_no = f"ORDER123456789{i}"
188
+ resp = requests.get(f"http://api/order/{order_no}")
189
+ ```
190
+
191
+ ## 6. 测试检查清单
192
+
193
+ ```
194
+ □ 支付篡改测试(金额、数量、状态)
195
+ □ 优惠券领取条件竞争测试
196
+ □ 库存扣减条件竞争测试
197
+ □ 业务流程跳过测试
198
+ □ 状态机绕过测试
199
+ □ 验证码绕过测试
200
+ □ 订单号/优惠券号预测测试
201
+ □ 评估漏洞利用难度和影响
202
+ ```
203
+
204
+ ## 7. 关联漏洞
205
+
206
+ | 后续漏洞 | 利用路径 |
207
+ |----------|----------|
208
+ | 0元支付 | 篡改金额为0.01 |
209
+ | 薅羊毛 | 条件竞争重复领取优惠券 |
210
+ | 刷单 | 篡改数量或绕过限制 |
211
+ | 盗窃 | 修改他人订单或地址 |
212
+
213
+ ## 8. 误报判断标准
214
+
215
+ ### 8.1 核心判断原则
216
+
217
+ ```
218
+ 【重要】业务逻辑测试的误判率极高!
219
+
220
+ 判断逻辑:
221
+ 1. 先理解正常的业务逻辑
222
+ 2. 确认"攻击"的响应是否真的绕过了业务逻辑
223
+ 3. 很多"攻击"可能是后端的正常防护
224
+
225
+ 【真实漏洞特征】
226
+ - 金额被篡改后仍能完成支付
227
+ - 负数数量被接受并执行
228
+ - 跳过验证步骤仍能完成业务
229
+ - 条件竞争真的造成了超卖
230
+
231
+ 【误报特征】
232
+ - 后端校验拒绝了异常请求
233
+ - 业务逻辑正确地拒绝了异常操作
234
+ - 接口返回错误提示而非执行成功
235
+ ```
236
+
237
+ ### 8.2 curl + 对比验证流程
238
+
239
+ ```bash
240
+ # 1. 【必须先执行】获取正常业务流程响应
241
+ curl -s -X POST http://api/order \
242
+ -H "Content-Type: application/json" \
243
+ -d '{"goodsId":"1","count":1,"price":100}' > biz_normal.json
244
+
245
+ # 2. 测试金额篡改
246
+ curl -s -X POST http://api/order \
247
+ -H "Content-Type: application/json" \
248
+ -d '{"goodsId":"1","count":1,"price":0.01}' > biz_amount_test.json
249
+
250
+ # 3. 测试数量篡改
251
+ curl -s -X POST http://api/order \
252
+ -H "Content-Type: application/json" \
253
+ -d '{"goodsId":"1","count":-1,"price":100}' > biz_count_test.json
254
+
255
+ # 4. 对比响应
256
+ diff biz_normal.json biz_amount_test.json
257
+ diff biz_normal.json biz_count_test.json
258
+
259
+ # 判断:
260
+ # - 如果异常请求被拒绝 → 后端有校验 → 不是漏洞
261
+ # - 如果异常请求被接受 → 可能是漏洞
262
+ ```
263
+
264
+ ### 8.3 业务逻辑漏洞判断矩阵
265
+
266
+ | 测试场景 | 正常响应 | 漏洞响应 | 判断 |
267
+ |----------|----------|----------|------|
268
+ | 金额0.01 | "金额不能小于1元" | 支付成功 | ⚠️ 漏洞 |
269
+ | 负数数量 | "数量必须大于0" | 订单创建成功 | ⚠️ 漏洞 |
270
+ | 跳过验证 | "请先验证" | 业务完成 | ⚠️ 漏洞 |
271
+ | 条件竞争 | 只有1人成功 | 多人成功 | ⚠️ 漏洞 |
272
+ | 优惠券重复 | "已领取过" | 多次成功 | ⚠️ 漏洞 |
273
+
274
+ ### 8.4 Python脚本(业务逻辑深度测试)
275
+
276
+ ```python
277
+ import requests
278
+ import json
279
+ import time
280
+
281
+ class BizLogicTester:
282
+ def __init__(self, target):
283
+ self.target = target
284
+ self.token = None
285
+
286
+ def set_token(self, token):
287
+ self.token = token
288
+
289
+ def get_headers(self):
290
+ headers = {"Content-Type": "application/json"}
291
+ if self.token:
292
+ headers["Authorization"] = f"Bearer {self.token}"
293
+ return headers
294
+
295
+ def test_price_tampering(self, order_data, tampered_price):
296
+ """
297
+ 测试价格篡改
298
+
299
+ 判断标准:
300
+ 1. 如果订单创建成功且价格被篡改 → 漏洞
301
+ 2. 如果订单创建失败或价格被纠正 → 安全
302
+ """
303
+ # 构造篡改后的订单
304
+ tampered_data = order_data.copy()
305
+ tampered_data['price'] = tampered_price
306
+
307
+ resp = requests.post(
308
+ f"{self.target}/order",
309
+ json=tampered_data,
310
+ headers=self.get_headers()
311
+ )
312
+
313
+ try:
314
+ data = resp.json()
315
+ except:
316
+ return None, "响应非JSON", resp
317
+
318
+ # 检查是否成功创建订单
319
+ if data.get('code') == 0 or data.get('success'):
320
+ # 检查实际金额
321
+ created_price = data.get('data', {}).get('price')
322
+ if created_price and created_price != tampered_price:
323
+ return False, f"后端纠正了金额: {tampered_price} -> {created_price}"
324
+ elif created_price == tampered_price:
325
+ return True, f"金额篡改成功: {created_price}"
326
+ else:
327
+ return None, "无法确认金额是否被篡改", data
328
+
329
+ # 检查错误消息
330
+ msg = data.get('msg', '')
331
+ if '价格' in msg or '金额' in msg:
332
+ return False, f"后端校验拒绝: {msg}"
333
+
334
+ return False, "订单创建失败", data
335
+
336
+ def test_negative_quantity(self, goods_id, count):
337
+ """
338
+ 测试负数数量
339
+
340
+ 判断标准:
341
+ 1. 如果订单创建成功 → 漏洞
342
+ 2. 如果订单创建失败 → 安全
343
+ """
344
+ resp = requests.post(
345
+ f"{self.target}/order",
346
+ json={"goodsId": goods_id, "count": count},
347
+ headers=self.get_headers()
348
+ )
349
+
350
+ try:
351
+ data = resp.json()
352
+ except:
353
+ return None, "响应非JSON", resp
354
+
355
+ if data.get('code') == 0 or data.get('success'):
356
+ return True, "负数数量被接受"
357
+
358
+ msg = data.get('msg', '')
359
+ if '数量' in msg or '参数' in msg:
360
+ return False, f"后端校验拒绝: {msg}"
361
+
362
+ return False, "订单创建失败", data
363
+
364
+ def test_race_condition(self, endpoint, data, concurrency=10):
365
+ """
366
+ 测试条件竞争
367
+
368
+ 判断标准:
369
+ 1. 并发请求
370
+ 2. 检查成功次数
371
+ 3. 如果成功次数 > 1 → 漏洞(超卖)
372
+ """
373
+ import threading
374
+
375
+ success_count = 0
376
+ lock = threading.Lock()
377
+ results = []
378
+
379
+ def send_request():
380
+ nonlocal success_count
381
+ try:
382
+ resp = requests.post(
383
+ f"{self.target}/{endpoint}",
384
+ json=data,
385
+ headers=self.get_headers(),
386
+ timeout=10
387
+ )
388
+ result = resp.json()
389
+ results.append(result)
390
+
391
+ if result.get('code') == 0 or result.get('success'):
392
+ with lock:
393
+ success_count += 1
394
+ except Exception as e:
395
+ results.append({'error': str(e)})
396
+
397
+ # 并发执行
398
+ threads = []
399
+ for _ in range(concurrency):
400
+ t = threading.Thread(target=send_request)
401
+ threads.append(t)
402
+ t.start()
403
+
404
+ for t in threads:
405
+ t.join()
406
+
407
+ # 判断
408
+ if success_count > 1:
409
+ return True, f"条件竞争漏洞:{concurrency}次请求,{success_count}次成功"
410
+ else:
411
+ return False, f"安全:{concurrency}次请求,{success_count}次成功(正常)"
412
+
413
+ def run_tests(self):
414
+ """执行完整业务逻辑测试"""
415
+ print(f"\n=== 业务逻辑漏洞测试 ===\n")
416
+
417
+ results = []
418
+
419
+ # 1. 价格篡改测试
420
+ print("[1] 测试价格篡改")
421
+ normal_data = {"goodsId": "1", "count": 1, "price": 100}
422
+ is_vuln, reason = self.test_price_tampering(normal_data, 0.01)
423
+ results.append(('价格篡改', is_vuln, reason))
424
+ print(f" 金额0.01: {reason}")
425
+
426
+ # 2. 负数数量测试
427
+ print("\n[2] 测试负数数量")
428
+ is_vuln, reason = self.test_negative_quantity("1", -1)
429
+ results.append(('负数数量', is_vuln, reason))
430
+ print(f" 数量-1: {reason}")
431
+
432
+ # 3. 条件竞争测试(优惠券场景)
433
+ print("\n[3] 测试条件竞争(优惠券领取)")
434
+ is_vuln, reason = self.test_race_condition(
435
+ "coupon/receive",
436
+ {"couponId": "1"},
437
+ concurrency=10
438
+ )
439
+ results.append(('条件竞争', is_vuln, reason))
440
+ print(f" 优惠券领取: {reason}")
441
+
442
+ return results
443
+
444
+ # 使用示例
445
+ if __name__ == "__main__":
446
+ tester = BizLogicTester("http://api")
447
+ tester.set_token("user_token")
448
+ results = tester.run_tests()
449
+
450
+ print("\n=== 测试结果汇总 ===")
451
+ for vuln_type, is_vuln, reason in results:
452
+ status = "⚠️ 漏洞" if is_vuln else "✅ 安全"
453
+ print(f"[{status}] {vuln_type}: {reason}")
454
+ ```
455
+
456
+ ## 9. 实战判断案例
457
+
458
+ ### 案例1:后端正确校验金额
459
+
460
+ ```
461
+ 【场景】:篡改金额被后端拒绝
462
+
463
+ curl测试:
464
+ curl -X POST /api/order -d '{"goodsId":"1","price":0.01}'
465
+ → {"code":1001,"msg":"金额不能小于1元"}
466
+
467
+ 判断:
468
+ - 后端正确校验了金额
469
+ - 响应包含错误提示
470
+ - 结论:【安全】后端有防护
471
+ ```
472
+
473
+ ### 案例2:价格篡改漏洞
474
+
475
+ ```
476
+ 【场景】:篡改金额后订单创建成功
477
+
478
+ curl测试:
479
+ curl -X POST /api/order -d '{"goodsId":"1","price":0.01}'
480
+ → {"code":0,"msg":"下单成功","orderId":"ORDER123","price":0.01}
481
+
482
+ 判断:
483
+ - 订单创建成功
484
+ - 金额被篡改为0.01
485
+ - 结论:【确认漏洞】价格篡改漏洞
486
+ ```
487
+
488
+ ### 案例3:负数数量漏洞
489
+
490
+ ```
491
+ 【场景】:负数数量导致"刷单"
492
+
493
+ curl测试:
494
+ curl -X POST /api/order -d '{"goodsId":"1","count":-5}'
495
+ → {"code":0,"msg":"下单成功","count":-5}
496
+
497
+ 判断:
498
+ - 负数数量被接受
499
+ - 可能导致"白嫖"或资金问题
500
+ - 结论:【确认漏洞】数量篡改漏洞
501
+ ```