@hoanghainh/komagu 2.5.0 → 2.6.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.
- package/CHANGELOG.md +17 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/ai-run-stats.json +87 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/auth-model.md +120 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/batches/index.json +60 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/batches/injection-001.json +383 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/batches/injection-002.json +205 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/batches/privilege-001.json +838 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/batches/privilege-002.json +124 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/batches/routes-001.json +778 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/batches/routes-002.json +546 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/batches/routes-003.json +661 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/batches/routes-004.json +659 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/batches/routes-005.json +612 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/batches/routes-006.json +106 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/coverage.json +19 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/findings/bola-routes-001.json +516 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/findings/bola-routes-002.json +332 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/findings/bola-routes-003.json +218 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/findings/bola-routes-004.json +561 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/findings/bola-routes-005.json +316 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/findings/bola-routes-006.json +14 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/findings/inj-injection-001.json +782 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/findings/inj-injection-002.json +418 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/findings/priv-privilege-001.json +627 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/findings/priv-privilege-002.json +253 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-1.json +68 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-10.json +68 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-11.json +61 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-12.json +60 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-13.json +60 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-14.json +66 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-15.json +69 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-16.json +60 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-17.json +61 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-18.json +69 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-19.json +64 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-2.json +60 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-20.json +60 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-21.json +61 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-22.json +50 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-3.json +60 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-4.json +60 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-5.json +60 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-6.json +70 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-7.json +60 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-8.json +60 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/findings/verified-9.json +60 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/findings.json +4857 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/mass-assignment.candidates.json +232 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/report.ja.md +2112 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/report.md +2112 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/routes/routes-001.json +425 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/routes/routes-002.json +333 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/routes/routes-003.json +400 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/routes/routes-004.json +403 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/routes/routes-005.json +398 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/routes/routes-006.json +63 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/score.json +82 -0
- package/assess/lsa/examples/eval-run-6/gptoss-a/stack-profile.json +225 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/ai-run-stats.json +91 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/auth-model.md +120 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/batches/index.json +60 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/batches/injection-001.json +383 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/batches/injection-002.json +205 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/batches/privilege-001.json +838 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/batches/privilege-002.json +124 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/batches/routes-001.json +778 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/batches/routes-002.json +546 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/batches/routes-003.json +661 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/batches/routes-004.json +659 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/batches/routes-005.json +612 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/batches/routes-006.json +106 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/coverage.json +21 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/findings/bola-routes-001.json +593 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/findings/bola-routes-002.json +367 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/findings/bola-routes-003.json +207 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/findings/bola-routes-004.json +477 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/findings/bola-routes-005.json +341 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/findings/bola-routes-006.json +14 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/findings/inj-injection-001.json +821 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/findings/inj-injection-002.json +410 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/findings/priv-privilege-001.json +649 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/findings/priv-privilege-002.json +222 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-1.json +60 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-10.json +67 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-11.json +68 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-12.json +60 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-13.json +60 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-14.json +64 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-15.json +70 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-16.json +60 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-17.json +61 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-18.json +60 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-19.json +65 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-2.json +60 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-20.json +60 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-21.json +62 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-22.json +50 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-3.json +60 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-4.json +60 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-5.json +60 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-6.json +60 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-7.json +64 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-8.json +60 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/findings/verified-9.json +60 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/findings.json +4966 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/mass-assignment.candidates.json +232 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/routes/routes-001.json +425 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/routes/routes-002.json +333 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/routes/routes-003.json +400 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/routes/routes-004.json +403 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/routes/routes-005.json +398 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/routes/routes-006.json +63 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/score.json +87 -0
- package/assess/lsa/examples/eval-run-6/gptoss-b/stack-profile.json +225 -0
- package/assess/lsa/examples/eval-run-6/ground-truth.json +851 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/ai-run-stats.json +96 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/auth-model.md +191 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/batches/index.json +60 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/batches/injection-001.json +383 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/batches/injection-002.json +205 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/batches/privilege-001.json +838 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/batches/privilege-002.json +124 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/batches/routes-001.json +778 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/batches/routes-002.json +546 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/batches/routes-003.json +661 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/batches/routes-004.json +659 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/batches/routes-005.json +612 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/batches/routes-006.json +106 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/coverage.json +31 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/bola-routes-001.json +527 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/bola-routes-002.json +568 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/bola-routes-003.json +467 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/bola-routes-004.json +342 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/bola-routes-005.json +693 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/bola-routes-006.json +16 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/inj-injection-001.json +1123 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/inj-injection-002.json +391 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/priv-privilege-001.json +726 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/priv-privilege-002.json +306 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-1.json +137 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-10.json +106 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-11.json +81 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-12.json +135 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-13.json +135 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-14.json +135 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-15.json +110 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-16.json +116 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-17.json +141 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-18.json +135 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-19.json +140 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-2.json +135 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-20.json +82 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-21.json +74 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-22.json +99 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-3.json +140 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-4.json +145 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-5.json +135 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-6.json +135 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-7.json +87 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-8.json +125 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings/verified-9.json +135 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/findings.json +6989 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/mass-assignment.candidates.json +232 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/memory.log +36 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/routes/routes-001.json +425 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/routes/routes-002.json +333 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/routes/routes-003.json +400 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/routes/routes-004.json +403 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/routes/routes-005.json +398 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/routes/routes-006.json +63 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/score.json +106 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-nothink/stack-profile.json +225 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-partial/auth-model.md +517 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-partial/findings/bola-routes-001.json +5 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-partial/findings/bola-routes-002.json +428 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-partial/findings/bola-routes-003.json +388 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-partial/findings/bola-routes-004.json +463 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-partial/findings/bola-routes-005.json +5 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-partial/findings/bola-routes-006.json +67 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-partial/findings/inj-injection-001.json +964 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-partial/findings.partial.json +1872 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-partial/memory.log +194 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-partial/score.partial.json +108 -0
- package/assess/lsa/examples/eval-run-6/qwen-16k-partial/stack-profile.json +225 -0
- package/assess/lsa/scripts/laravel_routes.py +102 -0
- package/assess/lsa/scripts/map_routes.py +4 -1
- package/assess/lsa/tests/EVAL-RESULTS.md +126 -0
- package/assess/lsa/tests/test_eval_run_6.py +104 -0
- package/assess/lsa/tests/test_laravel_routes.py +95 -0
- package/operate/ai/client.py +22 -9
- package/operate/ai/runner.py +4 -2
- package/operate/cli/__init__.py +1 -1
- package/operate/cli/commands/scan.py +8 -1
- package/operate/tests/test_ai_reasoning_effort.py +65 -0
- package/operate/tests/test_ai_route_inventory.py +53 -0
- package/package.json +1 -1
|
@@ -0,0 +1,463 @@
|
|
|
1
|
+
{
|
|
2
|
+
"batch_id": "routes-004",
|
|
3
|
+
"findings": [
|
|
4
|
+
{
|
|
5
|
+
"finding_id": "BOLA-R-0057-1",
|
|
6
|
+
"category": "bola",
|
|
7
|
+
"subtype": "missing_ownership_check",
|
|
8
|
+
"title": "User view endpoint allows any authenticated user to view another user's record via uid parameter",
|
|
9
|
+
"route_id": "R-0057",
|
|
10
|
+
"endpoint": {
|
|
11
|
+
"method": "GET|POST",
|
|
12
|
+
"path": "/php-plain/admin.php?action=view"
|
|
13
|
+
},
|
|
14
|
+
"location": {
|
|
15
|
+
"file": "php-plain/admin.php",
|
|
16
|
+
"start_line": 6,
|
|
17
|
+
"end_line": 8
|
|
18
|
+
},
|
|
19
|
+
"evidence": [
|
|
20
|
+
{
|
|
21
|
+
"file": "php-plain/admin.php",
|
|
22
|
+
"line": 7,
|
|
23
|
+
"code": "$uid = (int)$_GET['uid'];",
|
|
24
|
+
"why": "ID from query string"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"file": "php-plain/admin.php",
|
|
28
|
+
"line": 8,
|
|
29
|
+
"code": "SELECT * FROM users WHERE id = $uid;",
|
|
30
|
+
"why": "No user_id ownership check in WHERE clause"
|
|
31
|
+
}
|
|
32
|
+
],
|
|
33
|
+
"attack_scenario": "User A sends GET /admin.php?action=view&uid=<user id of user B> and receives B's user record.",
|
|
34
|
+
"impact": "Read other users' personal data (name, email, role).",
|
|
35
|
+
"severity": "high",
|
|
36
|
+
"confidence": "high",
|
|
37
|
+
"cwe": [
|
|
38
|
+
"CWE-284",
|
|
39
|
+
"CWE-639"
|
|
40
|
+
],
|
|
41
|
+
"recommendation": "Add AND user_id = :session_user_id to the query or load the record then compare owner and return 404 on mismatch.",
|
|
42
|
+
"status": "unverified",
|
|
43
|
+
"attack_vector": {
|
|
44
|
+
"target_param": "uid"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"finding_id": "BOLA-R-0058-1",
|
|
49
|
+
"category": "bola",
|
|
50
|
+
"subtype": "missing_ownership_check",
|
|
51
|
+
"title": "User delete endpoint allows any authenticated user to delete another user's record via id parameter",
|
|
52
|
+
"route_id": "R-0058",
|
|
53
|
+
"endpoint": {
|
|
54
|
+
"method": "GET|POST",
|
|
55
|
+
"path": "/php-plain/admin.php?action=delete"
|
|
56
|
+
},
|
|
57
|
+
"location": {
|
|
58
|
+
"file": "php-plain/admin.php",
|
|
59
|
+
"start_line": 10,
|
|
60
|
+
"end_line": 12
|
|
61
|
+
},
|
|
62
|
+
"evidence": [
|
|
63
|
+
{
|
|
64
|
+
"file": "php-plain/admin.php",
|
|
65
|
+
"line": 11,
|
|
66
|
+
"code": "$id = $_POST['id'];",
|
|
67
|
+
"why": "ID from POST body"
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"file": "php-plain/admin.php",
|
|
71
|
+
"line": 12,
|
|
72
|
+
"code": "DELETE FROM users WHERE id = $id;",
|
|
73
|
+
"why": "No user_id ownership check in WHERE clause"
|
|
74
|
+
}
|
|
75
|
+
],
|
|
76
|
+
"attack_scenario": "User A sends POST /admin.php?action=delete&id=<user id of user B> and deletes B's account.",
|
|
77
|
+
"impact": "Delete other users' accounts (account takeover, data loss).",
|
|
78
|
+
"severity": "high",
|
|
79
|
+
"confidence": "high",
|
|
80
|
+
"cwe": [
|
|
81
|
+
"CWE-284",
|
|
82
|
+
"CWE-639"
|
|
83
|
+
],
|
|
84
|
+
"recommendation": "Add AND user_id = :session_user_id to the query or load the record then compare owner and return 404 on mismatch.",
|
|
85
|
+
"status": "unverified",
|
|
86
|
+
"attack_vector": {
|
|
87
|
+
"target_param": "uid"
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"finding_id": "BOLA-R-0066-1",
|
|
92
|
+
"category": "bola",
|
|
93
|
+
"subtype": "missing_ownership_check",
|
|
94
|
+
"title": "User delete endpoint allows any authenticated user to delete another user's record via id parameter",
|
|
95
|
+
"route_id": "R-0066",
|
|
96
|
+
"endpoint": {
|
|
97
|
+
"method": "POST",
|
|
98
|
+
"path": "/php-plain/admin/delete_user.php"
|
|
99
|
+
},
|
|
100
|
+
"location": {
|
|
101
|
+
"file": "php-plain/admin/delete_user.php",
|
|
102
|
+
"start_line": 5,
|
|
103
|
+
"end_line": 7
|
|
104
|
+
},
|
|
105
|
+
"evidence": [
|
|
106
|
+
{
|
|
107
|
+
"file": "php-plain/admin/delete_user.php",
|
|
108
|
+
"line": 5,
|
|
109
|
+
"code": "$id = (int)$_POST['id'];",
|
|
110
|
+
"why": "ID from POST body"
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"file": "php-plain/admin/delete_user.php",
|
|
114
|
+
"line": 6,
|
|
115
|
+
"code": "DELETE FROM users WHERE id = ?;",
|
|
116
|
+
"why": "No user_id ownership check in WHERE clause"
|
|
117
|
+
}
|
|
118
|
+
],
|
|
119
|
+
"attack_scenario": "User A sends POST /admin/delete_user.php?id=<user id of user B> and deletes B's account.",
|
|
120
|
+
"impact": "Delete other users' accounts (account takeover, data loss).",
|
|
121
|
+
"severity": "high",
|
|
122
|
+
"confidence": "high",
|
|
123
|
+
"cwe": [
|
|
124
|
+
"CWE-284",
|
|
125
|
+
"CWE-639"
|
|
126
|
+
],
|
|
127
|
+
"recommendation": "Add AND user_id = :session_user_id to the query or load the record then compare owner and return 404 on mismatch.",
|
|
128
|
+
"status": "unverified",
|
|
129
|
+
"attack_vector": {
|
|
130
|
+
"target_param": "id"
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
"finding_id": "BOLA-R-0067-1",
|
|
135
|
+
"category": "bola",
|
|
136
|
+
"subtype": "missing_ownership_check",
|
|
137
|
+
"title": "User promote endpoint allows any authenticated user to promote another user to admin via uid parameter",
|
|
138
|
+
"route_id": "R-0067",
|
|
139
|
+
"endpoint": {
|
|
140
|
+
"method": "POST",
|
|
141
|
+
"path": "/php-plain/admin/promote.php"
|
|
142
|
+
},
|
|
143
|
+
"location": {
|
|
144
|
+
"file": "php-plain/admin/promote.php",
|
|
145
|
+
"start_line": 5,
|
|
146
|
+
"end_line": 7
|
|
147
|
+
},
|
|
148
|
+
"evidence": [
|
|
149
|
+
{
|
|
150
|
+
"file": "php-plain/admin/promote.php",
|
|
151
|
+
"line": 6,
|
|
152
|
+
"code": "$stmt = $db->prepare(\"UPDATE users SET role = 'admin' WHERE id = ?\");",
|
|
153
|
+
"why": "No user_id ownership check in WHERE clause"
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
"file": "php-plain/admin/promote.php",
|
|
157
|
+
"line": 7,
|
|
158
|
+
"code": "$stmt->execute(array((int)$_POST['uid']));",
|
|
159
|
+
"why": "ID from POST body used directly"
|
|
160
|
+
}
|
|
161
|
+
],
|
|
162
|
+
"attack_scenario": "User A sends POST /admin/promote.php with uid=<user id of user B> and promotes B to admin.",
|
|
163
|
+
"impact": "Elevate privileges for other users (privilege escalation).",
|
|
164
|
+
"severity": "high",
|
|
165
|
+
"confidence": "high",
|
|
166
|
+
"cwe": [
|
|
167
|
+
"CWE-284",
|
|
168
|
+
"CWE-639"
|
|
169
|
+
],
|
|
170
|
+
"recommendation": "Add AND user_id = :session_user_id to the query or load the record then compare owner and return 404 on mismatch.",
|
|
171
|
+
"status": "unverified",
|
|
172
|
+
"attack_vector": {
|
|
173
|
+
"target_param": "uid"
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
"finding_id": "BOLA-R-0059-1",
|
|
178
|
+
"category": "bola",
|
|
179
|
+
"subtype": "missing_ownership_check",
|
|
180
|
+
"title": "User delete endpoint allows any authenticated user to delete another user's record via id parameter",
|
|
181
|
+
"route_id": "R-0059",
|
|
182
|
+
"endpoint": {
|
|
183
|
+
"method": "POST",
|
|
184
|
+
"path": "/php-plain/manage_users.php"
|
|
185
|
+
},
|
|
186
|
+
"location": {
|
|
187
|
+
"file": "php-plain/manage_users.php",
|
|
188
|
+
"start_line": 6,
|
|
189
|
+
"end_line": 7
|
|
190
|
+
},
|
|
191
|
+
"evidence": [
|
|
192
|
+
{
|
|
193
|
+
"file": "php-plain/manage_users.php",
|
|
194
|
+
"line": 6,
|
|
195
|
+
"code": "$stmt = $db->prepare(\"DELETE FROM users WHERE id = ?\");",
|
|
196
|
+
"why": "No user_id ownership check in WHERE clause"
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
"file": "php-plain/manage_users.php",
|
|
200
|
+
"line": 7,
|
|
201
|
+
"code": "$stmt->execute(array($_POST['id']));",
|
|
202
|
+
"why": "ID from POST body used directly"
|
|
203
|
+
}
|
|
204
|
+
],
|
|
205
|
+
"attack_scenario": "User A sends POST /manage_users.php?id=<user id of user B> and deletes B's account.",
|
|
206
|
+
"impact": "Delete other users' accounts (account takeover, data loss).",
|
|
207
|
+
"severity": "high",
|
|
208
|
+
"confidence": "high",
|
|
209
|
+
"cwe": [
|
|
210
|
+
"CWE-284",
|
|
211
|
+
"CWE-639"
|
|
212
|
+
],
|
|
213
|
+
"recommendation": "Add AND user_id = :session_user_id to the query or load the record then compare owner and return 404 on mismatch.",
|
|
214
|
+
"status": "unverified",
|
|
215
|
+
"attack_vector": {
|
|
216
|
+
"target_param": "id"
|
|
217
|
+
}
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
"finding_id": "BOLA-R-0061-1",
|
|
221
|
+
"category": "bola",
|
|
222
|
+
"subtype": "missing_ownership_check",
|
|
223
|
+
"title": "Order detail endpoint allows any authenticated user to view another user's order via id parameter",
|
|
224
|
+
"route_id": "R-0061",
|
|
225
|
+
"endpoint": {
|
|
226
|
+
"method": "GET",
|
|
227
|
+
"path": "/php-plain/order_detail.php"
|
|
228
|
+
},
|
|
229
|
+
"location": {
|
|
230
|
+
"file": "php-plain/order_detail.php",
|
|
231
|
+
"start_line": 5,
|
|
232
|
+
"end_line": 8
|
|
233
|
+
},
|
|
234
|
+
"evidence": [
|
|
235
|
+
{
|
|
236
|
+
"file": "php-plain/order_detail.php",
|
|
237
|
+
"line": 5,
|
|
238
|
+
"code": "$id = $_GET['id'];",
|
|
239
|
+
"why": "ID from query string"
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
"file": "php-plain/order_detail.php",
|
|
243
|
+
"line": 6,
|
|
244
|
+
"code": "SELECT * FROM orders WHERE id = $id;",
|
|
245
|
+
"why": "No user_id ownership check in WHERE clause"
|
|
246
|
+
}
|
|
247
|
+
],
|
|
248
|
+
"attack_scenario": "User A sends GET /order_detail.php?id=<order id of user B> and receives B's order details.",
|
|
249
|
+
"impact": "Read other customers' orders (name, address, amount).",
|
|
250
|
+
"severity": "high",
|
|
251
|
+
"confidence": "high",
|
|
252
|
+
"cwe": [
|
|
253
|
+
"CWE-284",
|
|
254
|
+
"CWE-639"
|
|
255
|
+
],
|
|
256
|
+
"recommendation": "Add AND user_id = :session_user_id to the query or load the order then compare owner and return 404 on mismatch.",
|
|
257
|
+
"status": "unverified",
|
|
258
|
+
"attack_vector": {
|
|
259
|
+
"target_param": "id"
|
|
260
|
+
}
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
"finding_id": "BOLA-R-0069-1",
|
|
264
|
+
"category": "bola",
|
|
265
|
+
"subtype": "missing_ownership_check",
|
|
266
|
+
"title": "Order detail endpoint allows any authenticated user to view another user's order via order_id parameter",
|
|
267
|
+
"route_id": "R-0069",
|
|
268
|
+
"endpoint": {
|
|
269
|
+
"method": "GET",
|
|
270
|
+
"path": "/orders/<int:order_id>"
|
|
271
|
+
},
|
|
272
|
+
"location": {
|
|
273
|
+
"file": "python-flask/app.py",
|
|
274
|
+
"start_line": 11,
|
|
275
|
+
"end_line": 13
|
|
276
|
+
},
|
|
277
|
+
"evidence": [
|
|
278
|
+
{
|
|
279
|
+
"file": "python-flask/app.py",
|
|
280
|
+
"line": 11,
|
|
281
|
+
"code": "def order(order_id):",
|
|
282
|
+
"why": "order_id from URL path"
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
"file": "python-flask/app.py",
|
|
286
|
+
"line": 12,
|
|
287
|
+
"code": "cur.execute(\"SELECT * FROM orders WHERE id = %s\" % order_id)",
|
|
288
|
+
"why": "No user_id ownership check in WHERE clause"
|
|
289
|
+
}
|
|
290
|
+
],
|
|
291
|
+
"attack_scenario": "User A sends GET /orders/<order id of user B> and receives B's order details.",
|
|
292
|
+
"impact": "Read other customers' orders (name, address, amount).",
|
|
293
|
+
"severity": "high",
|
|
294
|
+
"confidence": "high",
|
|
295
|
+
"cwe": [
|
|
296
|
+
"CWE-284",
|
|
297
|
+
"CWE-639"
|
|
298
|
+
],
|
|
299
|
+
"recommendation": "Add AND user_id = :session_user_id to the query or load the order then compare owner and return 404 on mismatch.",
|
|
300
|
+
"status": "unverified",
|
|
301
|
+
"attack_vector": {
|
|
302
|
+
"target_param": "order_id"
|
|
303
|
+
}
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
"finding_id": "BOLA-R-0055-verdict",
|
|
307
|
+
"category": "bola",
|
|
308
|
+
"subtype": "missing_ownership_check",
|
|
309
|
+
"title": "Missing ownership check at php-laravel/routes/web.php:9 (from auditor verdict)",
|
|
310
|
+
"route_id": "R-0055",
|
|
311
|
+
"location": {
|
|
312
|
+
"file": "php-laravel/routes/web.php",
|
|
313
|
+
"start_line": 9
|
|
314
|
+
},
|
|
315
|
+
"evidence": [
|
|
316
|
+
{
|
|
317
|
+
"file": "php-laravel/routes/web.php",
|
|
318
|
+
"line": 9,
|
|
319
|
+
"why": "The auditor judged this route 'needs_review' but wrote no finding"
|
|
320
|
+
}
|
|
321
|
+
],
|
|
322
|
+
"impact": "Generated from the auditor's 'needs_review' verdict; the model wrote no finding for it.",
|
|
323
|
+
"severity": "medium",
|
|
324
|
+
"confidence": "low",
|
|
325
|
+
"cwe": [
|
|
326
|
+
"CWE-284"
|
|
327
|
+
],
|
|
328
|
+
"recommendation": "Bind the object lookup to the current user or tenant, or check ownership before using it.",
|
|
329
|
+
"status": "unverified",
|
|
330
|
+
"endpoint": {
|
|
331
|
+
"method": "POST",
|
|
332
|
+
"path": "/account/rename"
|
|
333
|
+
},
|
|
334
|
+
"attack_vector": {
|
|
335
|
+
"target_param": "id"
|
|
336
|
+
}
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
"finding_id": "BOLA-R-0056-verdict",
|
|
340
|
+
"category": "bola",
|
|
341
|
+
"subtype": "missing_ownership_check",
|
|
342
|
+
"title": "Missing ownership check at php-laravel/routes/web.php:10 (from auditor verdict)",
|
|
343
|
+
"route_id": "R-0056",
|
|
344
|
+
"location": {
|
|
345
|
+
"file": "php-laravel/routes/web.php",
|
|
346
|
+
"start_line": 10
|
|
347
|
+
},
|
|
348
|
+
"evidence": [
|
|
349
|
+
{
|
|
350
|
+
"file": "php-laravel/routes/web.php",
|
|
351
|
+
"line": 10,
|
|
352
|
+
"why": "The auditor judged this route 'needs_review' but wrote no finding"
|
|
353
|
+
}
|
|
354
|
+
],
|
|
355
|
+
"impact": "Generated from the auditor's 'needs_review' verdict; the model wrote no finding for it.",
|
|
356
|
+
"severity": "medium",
|
|
357
|
+
"confidence": "low",
|
|
358
|
+
"cwe": [
|
|
359
|
+
"CWE-284"
|
|
360
|
+
],
|
|
361
|
+
"recommendation": "Bind the object lookup to the current user or tenant, or check ownership before using it.",
|
|
362
|
+
"status": "unverified",
|
|
363
|
+
"endpoint": {
|
|
364
|
+
"method": "POST",
|
|
365
|
+
"path": "/account/profile"
|
|
366
|
+
},
|
|
367
|
+
"attack_vector": {
|
|
368
|
+
"target_param": "id"
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
],
|
|
372
|
+
"route_verdicts": [
|
|
373
|
+
{
|
|
374
|
+
"route_id": "R-0052",
|
|
375
|
+
"verdict": "safe",
|
|
376
|
+
"reason": "POST /register creates new user data; no object identifier is manipulated to access existing owned resources"
|
|
377
|
+
},
|
|
378
|
+
{
|
|
379
|
+
"route_id": "R-0053",
|
|
380
|
+
"verdict": "safe",
|
|
381
|
+
"reason": "POST /posts creates new post data; no object identifier is manipulated to access existing owned resources"
|
|
382
|
+
},
|
|
383
|
+
{
|
|
384
|
+
"route_id": "R-0054",
|
|
385
|
+
"verdict": "safe",
|
|
386
|
+
"reason": "POST /teams creates new team data; no object identifier is manipulated to access existing owned resources"
|
|
387
|
+
},
|
|
388
|
+
{
|
|
389
|
+
"route_id": "R-0055",
|
|
390
|
+
"verdict": "needs_review",
|
|
391
|
+
"reason": "Laravel route definition only; controller implementation not visible to verify ownership check"
|
|
392
|
+
},
|
|
393
|
+
{
|
|
394
|
+
"route_id": "R-0056",
|
|
395
|
+
"verdict": "needs_review",
|
|
396
|
+
"reason": "Laravel route definition only; controller implementation not visible to verify ownership check"
|
|
397
|
+
},
|
|
398
|
+
{
|
|
399
|
+
"route_id": "R-0057",
|
|
400
|
+
"verdict": "vulnerable",
|
|
401
|
+
"finding_ids": [
|
|
402
|
+
"BOLA-R-0057-1"
|
|
403
|
+
]
|
|
404
|
+
},
|
|
405
|
+
{
|
|
406
|
+
"route_id": "R-0058",
|
|
407
|
+
"verdict": "vulnerable",
|
|
408
|
+
"finding_ids": [
|
|
409
|
+
"BOLA-R-0058-1"
|
|
410
|
+
]
|
|
411
|
+
},
|
|
412
|
+
{
|
|
413
|
+
"route_id": "R-0059",
|
|
414
|
+
"verdict": "vulnerable",
|
|
415
|
+
"finding_ids": [
|
|
416
|
+
"BOLA-R-0059-1"
|
|
417
|
+
]
|
|
418
|
+
},
|
|
419
|
+
{
|
|
420
|
+
"route_id": "R-0061",
|
|
421
|
+
"verdict": "vulnerable",
|
|
422
|
+
"finding_ids": [
|
|
423
|
+
"BOLA-R-0061-1"
|
|
424
|
+
]
|
|
425
|
+
},
|
|
426
|
+
{
|
|
427
|
+
"route_id": "R-0062",
|
|
428
|
+
"verdict": "safe",
|
|
429
|
+
"reason": "query binds user_id = $_SESSION['user_id'] at line 5 with AND user_id = ?"
|
|
430
|
+
},
|
|
431
|
+
{
|
|
432
|
+
"route_id": "R-0066",
|
|
433
|
+
"verdict": "vulnerable",
|
|
434
|
+
"finding_ids": [
|
|
435
|
+
"BOLA-R-0066-1"
|
|
436
|
+
]
|
|
437
|
+
},
|
|
438
|
+
{
|
|
439
|
+
"route_id": "R-0067",
|
|
440
|
+
"verdict": "vulnerable",
|
|
441
|
+
"finding_ids": [
|
|
442
|
+
"BOLA-R-0067-1"
|
|
443
|
+
]
|
|
444
|
+
},
|
|
445
|
+
{
|
|
446
|
+
"route_id": "R-0069",
|
|
447
|
+
"verdict": "vulnerable",
|
|
448
|
+
"finding_ids": [
|
|
449
|
+
"BOLA-R-0069-1"
|
|
450
|
+
]
|
|
451
|
+
},
|
|
452
|
+
{
|
|
453
|
+
"route_id": "R-0070",
|
|
454
|
+
"verdict": "safe",
|
|
455
|
+
"reason": "query binds user_id = current_user.id at line 20 with AND user_id = %s"
|
|
456
|
+
},
|
|
457
|
+
{
|
|
458
|
+
"route_id": "R-0071",
|
|
459
|
+
"verdict": "safe",
|
|
460
|
+
"reason": "search endpoint queries products table which is not user-owned data; no object identifier manipulation"
|
|
461
|
+
}
|
|
462
|
+
]
|
|
463
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"batch_id": "routes-006",
|
|
3
|
+
"findings": [
|
|
4
|
+
{
|
|
5
|
+
"finding_id": "BOLA-R-0065-1",
|
|
6
|
+
"category": "bola",
|
|
7
|
+
"subtype": "missing_ownership_check",
|
|
8
|
+
"title": "Product search returns all products without user ownership verification",
|
|
9
|
+
"route_id": "R-0065",
|
|
10
|
+
"endpoint": {
|
|
11
|
+
"method": "GET",
|
|
12
|
+
"path": "/php-plain/search.php"
|
|
13
|
+
},
|
|
14
|
+
"location": {
|
|
15
|
+
"file": "php-plain/search.php",
|
|
16
|
+
"start_line": 7,
|
|
17
|
+
"end_line": 15
|
|
18
|
+
},
|
|
19
|
+
"evidence": [
|
|
20
|
+
{
|
|
21
|
+
"file": "php-plain/search.php",
|
|
22
|
+
"line": 7,
|
|
23
|
+
"code": "$sql = \"SELECT id, name FROM products WHERE 1=1\";",
|
|
24
|
+
"why": "Query starts without user_id filter"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"file": "php-plain/search.php",
|
|
28
|
+
"line": 8,
|
|
29
|
+
"code": "$sql .= \" AND name LIKE '%\" . $kw . \"%'\";",
|
|
30
|
+
"why": "Only filters by search term, no ownership check"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"file": "php-plain/search.php",
|
|
34
|
+
"line": 14,
|
|
35
|
+
"code": "WHERE category = '{$_GET['cat']}'",
|
|
36
|
+
"why": "Category filter only, no user_id or owner binding"
|
|
37
|
+
}
|
|
38
|
+
],
|
|
39
|
+
"attack_scenario": "Authenticated User A sends GET /search.php?q=widget&cat=electronics with another user's product ID in results and receives products they don't own.",
|
|
40
|
+
"impact": "Read other customers' product data (names, categories, potentially prices if returned).",
|
|
41
|
+
"severity": "high",
|
|
42
|
+
"confidence": "high",
|
|
43
|
+
"cwe": [
|
|
44
|
+
"CWE-639"
|
|
45
|
+
],
|
|
46
|
+
"owasp": [
|
|
47
|
+
"API1:2023"
|
|
48
|
+
],
|
|
49
|
+
"recommendation": "Add AND user_id = :current_user_id to all product queries, or load products then compare owner and return 404 on mismatch",
|
|
50
|
+
"status": "unverified"
|
|
51
|
+
}
|
|
52
|
+
],
|
|
53
|
+
"route_verdicts": [
|
|
54
|
+
{
|
|
55
|
+
"route_id": "R-0064",
|
|
56
|
+
"verdict": "not_applicable",
|
|
57
|
+
"reason": "Registration endpoint creates new user records; no object identifier to manipulate for accessing another user's existing data"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"route_id": "R-0065",
|
|
61
|
+
"verdict": "vulnerable",
|
|
62
|
+
"finding_ids": [
|
|
63
|
+
"BOLA-R-0065-1"
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
|
+
]
|
|
67
|
+
}
|