opencode-api-security-testing 3.0.9 → 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 +22 -19
- package/agents/api-probing-miner.md +34 -10
- package/agents/api-resource-specialist.md +49 -20
- package/agents/api-vuln-verifier.md +69 -18
- package/package.json +1 -1
- package/postinstall.mjs +1 -0
- package/preuninstall.mjs +43 -32
- package/src/index.ts +6 -3
- 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
|
@@ -1,501 +0,0 @@
|
|
|
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
|
-
```
|