@hoanghainh/komagu 2.0.0 → 2.0.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 (130) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +1 -1
  3. package/assess/lsa/examples/eval-run-4/ground-truth.json +823 -0
  4. package/assess/lsa/examples/eval-run-4/iter0-gptoss-a/ai-run-stats.json +58 -0
  5. package/assess/lsa/examples/eval-run-4/iter0-gptoss-a/coverage.json +85 -0
  6. package/assess/lsa/examples/eval-run-4/iter0-gptoss-a/findings/priv-privilege-001.json +822 -0
  7. package/assess/lsa/examples/eval-run-4/iter0-gptoss-a/findings/priv-privilege-002.json +393 -0
  8. package/assess/lsa/examples/eval-run-4/iter0-gptoss-a/findings.json +4477 -0
  9. package/assess/lsa/examples/eval-run-4/iter0-gptoss-a/mass-assignment.candidates.json +232 -0
  10. package/assess/lsa/examples/eval-run-4/iter0-gptoss-a/routes/routes-001.json +425 -0
  11. package/assess/lsa/examples/eval-run-4/iter0-gptoss-a/routes/routes-002.json +333 -0
  12. package/assess/lsa/examples/eval-run-4/iter0-gptoss-a/routes/routes-003.json +400 -0
  13. package/assess/lsa/examples/eval-run-4/iter0-gptoss-a/routes/routes-004.json +403 -0
  14. package/assess/lsa/examples/eval-run-4/iter0-gptoss-a/routes/routes-005.json +398 -0
  15. package/assess/lsa/examples/eval-run-4/iter0-gptoss-a/routes/routes-006.json +63 -0
  16. package/assess/lsa/examples/eval-run-4/iter0-gptoss-a/score.json +120 -0
  17. package/assess/lsa/examples/eval-run-4/iter1-gptoss-a/ai-run-stats.json +55 -0
  18. package/assess/lsa/examples/eval-run-4/iter1-gptoss-a/coverage.json +50 -0
  19. package/assess/lsa/examples/eval-run-4/iter1-gptoss-a/findings/priv-privilege-001.json +613 -0
  20. package/assess/lsa/examples/eval-run-4/iter1-gptoss-a/findings/priv-privilege-002.json +287 -0
  21. package/assess/lsa/examples/eval-run-4/iter1-gptoss-a/findings.json +4870 -0
  22. package/assess/lsa/examples/eval-run-4/iter1-gptoss-a/mass-assignment.candidates.json +232 -0
  23. package/assess/lsa/examples/eval-run-4/iter1-gptoss-a/routes/routes-001.json +425 -0
  24. package/assess/lsa/examples/eval-run-4/iter1-gptoss-a/routes/routes-002.json +333 -0
  25. package/assess/lsa/examples/eval-run-4/iter1-gptoss-a/routes/routes-003.json +400 -0
  26. package/assess/lsa/examples/eval-run-4/iter1-gptoss-a/routes/routes-004.json +403 -0
  27. package/assess/lsa/examples/eval-run-4/iter1-gptoss-a/routes/routes-005.json +398 -0
  28. package/assess/lsa/examples/eval-run-4/iter1-gptoss-a/routes/routes-006.json +63 -0
  29. package/assess/lsa/examples/eval-run-4/iter1-gptoss-a/score.json +107 -0
  30. package/assess/lsa/examples/eval-run-4/iter1-gptoss-b/ai-run-stats.json +58 -0
  31. package/assess/lsa/examples/eval-run-4/iter1-gptoss-b/coverage.json +92 -0
  32. package/assess/lsa/examples/eval-run-4/iter1-gptoss-b/findings/priv-privilege-001.json +645 -0
  33. package/assess/lsa/examples/eval-run-4/iter1-gptoss-b/findings/priv-privilege-002.json +222 -0
  34. package/assess/lsa/examples/eval-run-4/iter1-gptoss-b/findings.json +4859 -0
  35. package/assess/lsa/examples/eval-run-4/iter1-gptoss-b/mass-assignment.candidates.json +232 -0
  36. package/assess/lsa/examples/eval-run-4/iter1-gptoss-b/routes/routes-001.json +425 -0
  37. package/assess/lsa/examples/eval-run-4/iter1-gptoss-b/routes/routes-002.json +333 -0
  38. package/assess/lsa/examples/eval-run-4/iter1-gptoss-b/routes/routes-003.json +400 -0
  39. package/assess/lsa/examples/eval-run-4/iter1-gptoss-b/routes/routes-004.json +403 -0
  40. package/assess/lsa/examples/eval-run-4/iter1-gptoss-b/routes/routes-005.json +398 -0
  41. package/assess/lsa/examples/eval-run-4/iter1-gptoss-b/routes/routes-006.json +63 -0
  42. package/assess/lsa/examples/eval-run-4/iter1-gptoss-b/score.json +121 -0
  43. package/assess/lsa/examples/eval-run-4/iter1-qwen-a-incomplete/coverage.json +111 -0
  44. package/assess/lsa/examples/eval-run-4/iter1-qwen-a-incomplete/findings/priv-privilege-001.json +6 -0
  45. package/assess/lsa/examples/eval-run-4/iter1-qwen-a-incomplete/findings/priv-privilege-002.json +344 -0
  46. package/assess/lsa/examples/eval-run-4/iter1-qwen-a-incomplete/findings.json +3544 -0
  47. package/assess/lsa/examples/eval-run-4/iter1-qwen-a-incomplete/mass-assignment.candidates.json +232 -0
  48. package/assess/lsa/examples/eval-run-4/iter1-qwen-a-incomplete/routes/routes-001.json +425 -0
  49. package/assess/lsa/examples/eval-run-4/iter1-qwen-a-incomplete/routes/routes-002.json +333 -0
  50. package/assess/lsa/examples/eval-run-4/iter1-qwen-a-incomplete/routes/routes-003.json +400 -0
  51. package/assess/lsa/examples/eval-run-4/iter1-qwen-a-incomplete/routes/routes-004.json +403 -0
  52. package/assess/lsa/examples/eval-run-4/iter1-qwen-a-incomplete/routes/routes-005.json +398 -0
  53. package/assess/lsa/examples/eval-run-4/iter1-qwen-a-incomplete/routes/routes-006.json +63 -0
  54. package/assess/lsa/examples/eval-run-4/iter1-qwen-a-incomplete/score.json +123 -0
  55. package/assess/lsa/examples/eval-run-4/iter2-gptoss-a/ai-run-stats.json +50 -0
  56. package/assess/lsa/examples/eval-run-4/iter2-gptoss-a/coverage.json +42 -0
  57. package/assess/lsa/examples/eval-run-4/iter2-gptoss-a/findings/priv-privilege-001.json +540 -0
  58. package/assess/lsa/examples/eval-run-4/iter2-gptoss-a/findings/priv-privilege-002.json +238 -0
  59. package/assess/lsa/examples/eval-run-4/iter2-gptoss-a/findings.json +4383 -0
  60. package/assess/lsa/examples/eval-run-4/iter2-gptoss-a/findings.sarif +8729 -0
  61. package/assess/lsa/examples/eval-run-4/iter2-gptoss-a/mass-assignment.candidates.json +232 -0
  62. package/assess/lsa/examples/eval-run-4/iter2-gptoss-a/report.ja.md +1911 -0
  63. package/assess/lsa/examples/eval-run-4/iter2-gptoss-a/report.md +1911 -0
  64. package/assess/lsa/examples/eval-run-4/iter2-gptoss-a/routes/routes-001.json +425 -0
  65. package/assess/lsa/examples/eval-run-4/iter2-gptoss-a/routes/routes-002.json +333 -0
  66. package/assess/lsa/examples/eval-run-4/iter2-gptoss-a/routes/routes-003.json +400 -0
  67. package/assess/lsa/examples/eval-run-4/iter2-gptoss-a/routes/routes-004.json +403 -0
  68. package/assess/lsa/examples/eval-run-4/iter2-gptoss-a/routes/routes-005.json +398 -0
  69. package/assess/lsa/examples/eval-run-4/iter2-gptoss-a/routes/routes-006.json +63 -0
  70. package/assess/lsa/examples/eval-run-4/iter2-gptoss-a/score.json +101 -0
  71. package/assess/lsa/examples/eval-run-4/iter2-gptoss-a/stack-profile.json +226 -0
  72. package/assess/lsa/examples/eval-run-4/iter2-gptoss-b/ai-run-stats.json +54 -0
  73. package/assess/lsa/examples/eval-run-4/iter2-gptoss-b/coverage.json +66 -0
  74. package/assess/lsa/examples/eval-run-4/iter2-gptoss-b/findings/priv-privilege-001.json +440 -0
  75. package/assess/lsa/examples/eval-run-4/iter2-gptoss-b/findings/priv-privilege-002.json +229 -0
  76. package/assess/lsa/examples/eval-run-4/iter2-gptoss-b/findings.json +3424 -0
  77. package/assess/lsa/examples/eval-run-4/iter2-gptoss-b/mass-assignment.candidates.json +232 -0
  78. package/assess/lsa/examples/eval-run-4/iter2-gptoss-b/routes/routes-001.json +425 -0
  79. package/assess/lsa/examples/eval-run-4/iter2-gptoss-b/routes/routes-002.json +333 -0
  80. package/assess/lsa/examples/eval-run-4/iter2-gptoss-b/routes/routes-003.json +400 -0
  81. package/assess/lsa/examples/eval-run-4/iter2-gptoss-b/routes/routes-004.json +403 -0
  82. package/assess/lsa/examples/eval-run-4/iter2-gptoss-b/routes/routes-005.json +398 -0
  83. package/assess/lsa/examples/eval-run-4/iter2-gptoss-b/routes/routes-006.json +63 -0
  84. package/assess/lsa/examples/eval-run-4/iter2-gptoss-b/score.json +120 -0
  85. package/assess/lsa/examples/eval-run-5/gptoss-a/ai-run-stats.json +88 -0
  86. package/assess/lsa/examples/eval-run-5/gptoss-a/coverage.json +36 -0
  87. package/assess/lsa/examples/eval-run-5/gptoss-a/findings/priv-privilege-001.json +530 -0
  88. package/assess/lsa/examples/eval-run-5/gptoss-a/findings/priv-privilege-002.json +248 -0
  89. package/assess/lsa/examples/eval-run-5/gptoss-a/findings.json +4766 -0
  90. package/assess/lsa/examples/eval-run-5/gptoss-a/findings.sarif +9326 -0
  91. package/assess/lsa/examples/eval-run-5/gptoss-a/mass-assignment.candidates.json +232 -0
  92. package/assess/lsa/examples/eval-run-5/gptoss-a/report.ja.md +2011 -0
  93. package/assess/lsa/examples/eval-run-5/gptoss-a/report.md +2011 -0
  94. package/assess/lsa/examples/eval-run-5/gptoss-a/routes/routes-001.json +425 -0
  95. package/assess/lsa/examples/eval-run-5/gptoss-a/routes/routes-002.json +333 -0
  96. package/assess/lsa/examples/eval-run-5/gptoss-a/routes/routes-003.json +400 -0
  97. package/assess/lsa/examples/eval-run-5/gptoss-a/routes/routes-004.json +403 -0
  98. package/assess/lsa/examples/eval-run-5/gptoss-a/routes/routes-005.json +398 -0
  99. package/assess/lsa/examples/eval-run-5/gptoss-a/routes/routes-006.json +63 -0
  100. package/assess/lsa/examples/eval-run-5/gptoss-a/score.json +80 -0
  101. package/assess/lsa/examples/eval-run-5/gptoss-a/stack-profile.json +226 -0
  102. package/assess/lsa/examples/eval-run-5/gptoss-b/ai-run-stats.json +83 -0
  103. package/assess/lsa/examples/eval-run-5/gptoss-b/coverage.json +44 -0
  104. package/assess/lsa/examples/eval-run-5/gptoss-b/findings/priv-privilege-001.json +579 -0
  105. package/assess/lsa/examples/eval-run-5/gptoss-b/findings/priv-privilege-002.json +268 -0
  106. package/assess/lsa/examples/eval-run-5/gptoss-b/findings.json +3913 -0
  107. package/assess/lsa/examples/eval-run-5/gptoss-b/mass-assignment.candidates.json +232 -0
  108. package/assess/lsa/examples/eval-run-5/gptoss-b/routes/routes-001.json +425 -0
  109. package/assess/lsa/examples/eval-run-5/gptoss-b/routes/routes-002.json +333 -0
  110. package/assess/lsa/examples/eval-run-5/gptoss-b/routes/routes-003.json +400 -0
  111. package/assess/lsa/examples/eval-run-5/gptoss-b/routes/routes-004.json +403 -0
  112. package/assess/lsa/examples/eval-run-5/gptoss-b/routes/routes-005.json +398 -0
  113. package/assess/lsa/examples/eval-run-5/gptoss-b/routes/routes-006.json +63 -0
  114. package/assess/lsa/examples/eval-run-5/gptoss-b/score.json +94 -0
  115. package/assess/lsa/examples/eval-run-5/ground-truth.json +823 -0
  116. package/assess/lsa/prompts/35-privilege-auditor.md +3 -1
  117. package/assess/lsa/tests/EVAL-RESULTS.md +156 -0
  118. package/assess/lsa/tests/score_findings.py +58 -0
  119. package/assess/lsa/tests/test_eval_run_4.py +73 -0
  120. package/assess/lsa/tests/test_eval_run_5.py +73 -0
  121. package/assess/lsa/tests/test_privilege_tier2.py +30 -0
  122. package/operate/ai/anchoring.py +130 -0
  123. package/operate/ai/client.py +13 -0
  124. package/operate/ai/context.py +105 -0
  125. package/operate/ai/runner.py +197 -69
  126. package/operate/cli/__init__.py +1 -1
  127. package/operate/cli/commands/scan.py +1 -1
  128. package/operate/tests/test_ai_anchoring.py +184 -0
  129. package/operate/tests/test_headless_ai.py +148 -1
  130. package/package.json +1 -1
@@ -0,0 +1,2011 @@
1
+ # Security Audit Report — repo
2
+
3
+ > **Classification: CONFIDENTIAL.** AI-assisted static review. All findings require human review (record decisions in `review-log.md`, created from `templates/review-log.md`) before they are shared outside the team.
4
+
5
+ | Item | Value |
6
+ |---|---|
7
+ | Date | 2026-10-31 |
8
+ | Kit version | 0.3.1 |
9
+ | Scope | BOLA/IDOR; SQL/HQL/NoSQL queries built from input; BFLA (missing role checks); mass assignment |
10
+ | Stacks | php, php-codeigniter, php-laravel, java-servlet, java-jsp, java-struts1, java-spring-mvc, java-mybatis, java-hibernate, dotnet-webforms, dotnet-handlers, dotnet-mvc, classic-asp, perl-cgi, coldfusion, node-express, python-flask, sql-procedures |
11
+ | Endpoints inventoried | 74 (candidates: 74) |
12
+ | Endpoints audited for BOLA | 74 |
13
+ | Injection candidates reviewed | 38 |
14
+ | Privileged routes audited for BFLA | 0 |
15
+ | Mass assignment candidates reviewed | 15 |
16
+
17
+ ## 1. Executive summary
18
+
19
+ <!-- LLM: reporter agent writes max 8 bullets here -->
20
+
21
+ ## 2. Findings overview
22
+
23
+ | Severity | critical | high | medium | low | info |
24
+ |---|---|---|---|---|---|
25
+ | Count | 50 | 43 | 6 | 0 | 0 |
26
+
27
+ | Category | Count |
28
+ |---|---|
29
+ | bola | 42 |
30
+ | sql_injection | 30 |
31
+ | nosql_injection | 5 |
32
+ | bfla | 12 |
33
+ | mass_assignment | 10 |
34
+
35
+ Status: unverified=0, confirmed=57, likely=42, rejected=2, needs_review=0
36
+
37
+ ## Trend and time to fix
38
+
39
+ | Date | Open | New | Regressed | Fixed | Suppressed |
40
+ |---|---|---|---|---|---|
41
+ | 2026-10-31 | 99 | 99 | 0 | 0 | 0 |
42
+
43
+ No findings fixed yet.
44
+
45
+ ## 3. Findings
46
+
47
+ | ID | Sev | Conf | Status | Category | Endpoint | Location | Title |
48
+ |---|---|---|---|---|---|---|---|
49
+ | BFLA-R-0003-1 | critical | high | confirmed | bfla | | `classic-asp/shop/member.asp:9` | Unrestricted member deletion in classic‑ASP |
50
+ | BFLA-R-0007-1 | critical | high | confirmed | bfla | | `dotnet-legacy/Web/Controllers/AdminController.cs:12` | Unrestricted user deletion in ASP.NET MVC |
51
+ | BFLA-R-0009-1 | critical | high | confirmed | bfla | | `dotnet-legacy/Web/Controllers/AdminController.cs:30` | Export endpoint controlled by request parameter |
52
+ | BFLA-R-0023-1 | critical | medium | likely | bfla | | `java-legacy/src/com/acme/web/AdminUserController.java:13` | Unrestricted user deletion in Spring MVC |
53
+ | BFLA-R-0030-1 | critical | medium | likely | bfla | | `node-express/routes/admin.js:8` | Unrestricted user deletion in Express.js |
54
+ | BFLA-R-0032-1 | critical | medium | likely | bfla | | `node-express/routes/admin.js:16` | Export endpoint controlled by query parameter in Express.js |
55
+ | BFLA-R-0057-1 | critical | medium | likely | bfla | | `php-plain/admin.php:6` | Unrestricted user view in PHP |
56
+ | BFLA-R-0058-1 | critical | medium | likely | bfla | | `php-plain/admin.php:10` | Unrestricted user deletion in PHP |
57
+ | BFLA-R-0059-1 | critical | medium | likely | bfla | | `php-plain/manage_users.php:1` | Client‑side admin check allows user deletion in PHP |
58
+ | BFLA-R-0063-1 | critical | medium | likely | bfla | | `php-plain/profile.php:1` | Privilege escalation via role field in profile update |
59
+ | BFLA-R-0066-1 | critical | medium | likely | bfla | | `php-plain/admin/delete_user.php:1` | Unrestricted user deletion in PHP |
60
+ | BFLA-R-0067-1 | critical | medium | likely | bfla | | `php-plain/admin/promote.php:1` | Privilege escalation via role promotion in PHP |
61
+ | INJ-I-0001 | critical | high | confirmed | sql_injection | | `classic-asp/shop/member.asp:6` | SQL Injection in classic-asp/shop/member.asp:6 |
62
+ | INJ-I-0002 | critical | high | confirmed | sql_injection | | `classic-asp/shop/member.asp:7` | SQL Injection in classic-asp/shop/member.asp:7 |
63
+ | INJ-I-0003 | critical | high | confirmed | sql_injection | | `classic-asp/shop/member.asp:10` | SQL Injection in classic-asp/shop/member.asp:10 |
64
+ | INJ-I-0004 | critical | high | confirmed | sql_injection | | `classic-asp/shop/order.asp:6` | SQL Injection in classic-asp/shop/order.asp:6 |
65
+ | INJ-I-0006 | critical | high | confirmed | sql_injection | | `coldfusion/app/OrderService.cfc:5` | SQL Injection in coldfusion/app/OrderService.cfc:5 |
66
+ | INJ-I-0007 | critical | high | confirmed | sql_injection | | `coldfusion/app/order.cfm:3` | SQL Injection in coldfusion/app/order.cfm:3 |
67
+ | INJ-I-0008-1 | critical | medium | likely | sql_injection | | `dotnet-legacy/Web/Controllers/InvoiceController.cs:28` | SQL Injection in dotnet-legacy/Web/Controllers/InvoiceController.cs:28 |
68
+ | INJ-I-0009 | critical | high | confirmed | sql_injection | | `dotnet-legacy/Web/Orders/EditOrder.aspx.vb:7` | SQL Injection in dotnet-legacy/Web/Orders/EditOrder.aspx.vb:7 |
69
+ | INJ-I-0010 | critical | high | confirmed | sql_injection | | `dotnet-legacy/Web/Orders/EditOrder.aspx.vb:8` | SQL Injection in dotnet-legacy/Web/Orders/EditOrder.aspx.vb:8 |
70
+ | INJ-I-0011-1 | critical | high | confirmed | sql_injection | | `dotnet-legacy/Web/Orders/OrderDetail.aspx.cs:13` | SQL Injection in dotnet-legacy/Web/Orders/OrderDetail.aspx.cs:13 |
71
+ | INJ-I-0011-3 | critical | high | confirmed | sql_injection | | `dotnet-legacy/Web/Orders/OrderDetail.aspx.cs:13` | SQL Injection in dotnet-legacy/Web/Orders/OrderDetail.aspx.cs:20 |
72
+ | INJ-I-0012 | critical | high | confirmed | sql_injection | | `dotnet-legacy/Web/Orders/OrderDetail.aspx.cs:19` | SQL Injection in dotnet-legacy/Web/Orders/OrderDetail.aspx.cs:19 |
73
+ | INJ-I-0013 | critical | high | confirmed | sql_injection | | `dotnet-legacy/Web/Orders/OrderDetail.aspx.cs:20` | SQL Injection in dotnet-legacy/Web/Orders/OrderDetail.aspx.cs:20 |
74
+ | INJ-I-0014 | critical | medium | likely | sql_injection | | `java-legacy/WebContent/order/detail.jsp:5` | SQL Injection in java-legacy/WebContent/order/detail.jsp:5 |
75
+ | INJ-I-0015-1 | critical | medium | likely | sql_injection | | `java-legacy/src/com/acme/mapper/OrderMapper.xml:9` | SQL Injection in java-legacy/src/com/acme/mapper/OrderMapper.xml:9 |
76
+ | INJ-I-0016 | critical | medium | likely | sql_injection | | `java-legacy/src/com/acme/struts/EditUserAction.java:13` | SQL Injection in java-legacy/src/com/acme/struts/EditUserAction.java:13 |
77
+ | INJ-I-0017 | critical | medium | likely | sql_injection | | `java-legacy/src/com/acme/web/InvoiceController.java:29` | SQL Injection in java-legacy/src/com/acme/web/InvoiceController.java:29 |
78
+ | INJ-I-0018-1 | critical | medium | likely | sql_injection | | `java-legacy/src/com/acme/web/OrderServlet.java:15` | SQL Injection in java-legacy/src/com/acme/web/OrderServlet.java:15 |
79
+ | INJ-I-0020-1 | critical | medium | likely | sql_injection | | `node-express/routes/orders.js:17` | SQL Injection in node-express/routes/orders.js:17 |
80
+ | INJ-I-0020-3 | critical | high | confirmed | nosql_injection | | `node-express/routes/orders.js:17` | NoSQL Injection in node-express/routes/orders.js:25 |
81
+ | INJ-I-0020-4 | critical | high | confirmed | sql_injection | | `node-express/routes/orders.js:17` | SQL Injection in node-express/routes/orders.js:29 |
82
+ | INJ-I-0021 | critical | high | confirmed | sql_injection | | `node-express/routes/orders.js:29` | SQL Injection in node-express/routes/orders.js:29 |
83
+ | INJ-I-0022 | critical | high | confirmed | nosql_injection | | `node-express/routes/orders.js:21` | NoSQL Injection in node-express/routes/orders.js:21 |
84
+ | INJ-I-0023 | critical | high | confirmed | nosql_injection | | `node-express/routes/orders.js:25` | NoSQL Injection in node-express/routes/orders.js:25 |
85
+ | INJ-I-0024-1 | critical | high | confirmed | sql_injection | | `perl-cgi/cgi-bin/order.cgi:13` | SQL Injection in perl-cgi/cgi-bin/order.cgi:13 |
86
+ | INJ-I-0025 | critical | high | confirmed | sql_injection | | `perl-cgi/cgi-bin/order.cgi:19` | SQL Injection in perl-cgi/cgi-bin/order.cgi:19 |
87
+ | INJ-I-0026-1 | critical | high | confirmed | sql_injection | | `php-codeigniter/application/controllers/Invoice.php:10` | SQL Injection in php-codeigniter/application/controllers/Invoice.php:10 |
88
+ | INJ-I-0028 | critical | high | confirmed | sql_injection | | `php-plain/admin.php:12` | SQL Injection in php-plain/admin.php:12 |
89
+ | INJ-I-0029-2 | critical | high | confirmed | nosql_injection | | `php-plain/mongo_find.php:5` | NoSQL Injection in php-plain/mongo_find.php:6 |
90
+ | INJ-I-0030 | critical | high | confirmed | nosql_injection | | `php-plain/mongo_find.php:6` | NoSQL Injection in php-plain/mongo_find.php:6 |
91
+ | INJ-I-0031-1 | critical | high | confirmed | sql_injection | | `php-plain/order_detail.php:6` | SQL Injection in php-plain/order_detail.php:6 |
92
+ | INJ-I-0032-1 | critical | high | confirmed | sql_injection | | `php-plain/search.php:8` | SQL Injection in php-plain/search.php:7 |
93
+ | INJ-I-0032-2 | critical | high | confirmed | sql_injection | | `php-plain/search.php:8` | SQL Injection in php-plain/search.php:12 |
94
+ | INJ-I-0036-1 | critical | high | confirmed | sql_injection | | `python-flask/app.py:29` | SQL Injection in python-flask/app.py:29 |
95
+ | INJ-I-0037-1 | critical | high | confirmed | sql_injection | | `sql-procs/sp_search_orders.sql:5` | SQL Injection in sql-procs/sp_search_orders.sql:5 |
96
+ | MASS-M-0003-1 | critical | medium | likely | mass_assignment | | `java-legacy/src/com/acme/web/AccountController.java:14` | Unrestricted role binding in Spring MVC |
97
+ | MASS-M-0004-1 | critical | medium | likely | mass_assignment | | `java-legacy/src/com/acme/web/AccountController.java:27` | Unrestricted role binding in Spring MVC (duplicate) |
98
+ | MASS-M-0005-1 | critical | medium | likely | mass_assignment | | `java-legacy/src/com/acme/web/ProfileServlet.java:12` | Unrestricted role binding via BeanUtils in Java Servlet |
99
+ | BOLA-R-0001 | high | high | confirmed | bola | ANY /user/edit.do | `java-legacy/src/com/acme/struts/EditUserAction.java:10` | BOLA in ANY /user/edit.do: missing owner verification |
100
+ | BOLA-R-0002 | high | high | confirmed | bola | ANY /classic-asp/shop/member.asp?mode=edit | `classic-asp/shop/member.asp:6` | BOLA in ANY /classic-asp/shop/member.asp?mode=edit: missing owner verification |
101
+ | BOLA-R-0003 | high | high | confirmed | bola | ANY /classic-asp/shop/member.asp?mode=delete | `classic-asp/shop/member.asp:9` | BOLA in ANY /classic-asp/shop/member.asp?mode=delete: missing owner verification |
102
+ | BOLA-R-0004 | high | high | confirmed | bola | ANY /classic-asp/shop/order.asp | `classic-asp/shop/order.asp:5` | BOLA in ANY /classic-asp/shop/order.asp: missing owner verification on first query |
103
+ | BOLA-R-0005 | high | high | confirmed | bola | ANY /coldfusion/app/OrderService.cfc?method=getOrder | `coldfusion/app/OrderService.cfc:4` | BOLA in ANY /coldfusion/app/OrderService.cfc?method=getOrder: missing owner verification |
104
+ | BOLA-R-0006 | high | high | confirmed | bola | ANY /coldfusion/app/order.cfm | `coldfusion/app/order.cfm:2` | BOLA in ANY /coldfusion/app/order.cfm: missing owner verification on first query |
105
+ | BOLA-R-0007 | high | high | confirmed | bola | POST /Admin/DeleteUser | `dotnet-legacy/Web/Controllers/AdminController.cs:12` | BOLA in POST /Admin/DeleteUser: missing owner verification |
106
+ | BOLA-R-0009 | high | high | confirmed | bola | POST /Admin/Export | `dotnet-legacy/Web/Controllers/AdminController.cs:30` | BOLA in POST /Admin/Export: missing role check allows data exposure |
107
+ | BOLA-R-0010 | high | medium | likely | bola | POST /Customer/Edit | `dotnet-legacy/Web/Controllers/CustomerController.cs:12` | BOLA in POST /Customer/Edit: missing owner verification |
108
+ | BOLA-R-0011 | high | medium | likely | bola | POST /Customer/EditName | `dotnet-legacy/Web/Controllers/CustomerController.cs:20` | BOLA in POST /Customer/EditName: missing owner verification |
109
+ | BOLA-R-0012 | high | medium | likely | bola | POST /Customer/Refresh | `dotnet-legacy/Web/Controllers/CustomerController.cs:27` | BOLA in POST /Customer/Refresh: missing owner verification |
110
+ | BOLA-R-0013 | high | high | confirmed | bola | ANY /Invoice/Details | `dotnet-legacy/Web/Controllers/InvoiceController.cs:11` | BOLA in GET /Invoice/Details: missing owner verification |
111
+ | BOLA-R-0015 | high | high | confirmed | bola | POST /Invoice/Search | `dotnet-legacy/Web/Controllers/InvoiceController.cs:26` | BOLA in POST /Invoice/Search: missing owner verification |
112
+ | BOLA-R-0016 | high | high | confirmed | bola | ANY /dotnet-legacy/Web/Handlers/GetFile.ashx | `dotnet-legacy/Web/Handlers/GetFile.ashx:8` | BOLA in ANY /dotnet-legacy/Web/Handlers/GetFile.ashx: missing owner verification |
113
+ | BOLA-R-0017 | high | high | confirmed | bola | ANY /dotnet-legacy/Web/Orders/EditOrder.aspx | `dotnet-legacy/Web/Orders/EditOrder.aspx.vb:7` | BOLA in ANY /dotnet-legacy/Web/Orders/EditOrder.aspx.vb: missing owner verification |
114
+ | BOLA-R-0018 | high | high | confirmed | bola | ANY /dotnet-legacy/Web/Orders/OrderDetail.aspx | `dotnet-legacy/Web/Orders/OrderDetail.aspx.cs:10` | BOLA in ANY /dotnet-legacy/Web/Orders/OrderDetail.aspx.cs: missing owner verification |
115
+ | BOLA-R-0019 | high | high | confirmed | bola | ANY /java-legacy/WebContent/order/detail.jsp | `java-legacy/WebContent/order/detail.jsp:3` | BOLA in ANY /java-legacy/WebContent/order/detail.jsp: missing owner verification |
116
+ | BOLA-R-0020 | high | high | confirmed | bola | POST /account/save | `java-legacy/src/com/acme/web/AccountController.java:14` | BOLA in POST /account/save: missing owner verification |
117
+ | BOLA-R-0021 | high | high | confirmed | bola | POST /account/rename | `java-legacy/src/com/acme/web/AccountController.java:20` | BOLA in POST /account/rename: missing owner verification |
118
+ | BOLA-R-0022 | high | medium | likely | bola | PUT /account/api | `java-legacy/src/com/acme/web/AccountController.java:27` | BOLA in PUT /account/api: missing owner verification |
119
+ | BOLA-R-0023 | high | medium | likely | bola | POST /admin/users/{id}/delete | `java-legacy/src/com/acme/web/AdminUserController.java:13` | BOLA in POST /admin/users/{id}/delete: missing owner verification |
120
+ | BOLA-R-0025 | high | medium | likely | bola | GET /invoices/{id} | `java-legacy/src/com/acme/web/InvoiceController.java:15` | BOLA in GET /invoices/{id}: missing owner verification |
121
+ | BOLA-R-0027 | high | medium | likely | bola | GET /invoices/search | `java-legacy/src/com/acme/web/InvoiceController.java:27` | BOLA in GET /invoices/search: missing owner verification |
122
+ | BOLA-R-0028 | high | medium | likely | bola | GET /order/view | `java-legacy/src/com/acme/web/OrderServlet.java:11` | BOLA in GET /order/view: missing owner verification |
123
+ | BOLA-R-0029 | high | high | confirmed | bola | POST <see web.xml servlet-mapping> | `java-legacy/src/com/acme/web/ProfileServlet.java:9` | BOLA in POST /ProfileServlet: missing owner verification |
124
+ | BOLA-R-0030 | high | high | confirmed | bola | POST /admin/users/:id/delete | `node-express/routes/admin.js:8` | BOLA in POST /admin/users/:id/delete: missing owner verification |
125
+ | BOLA-R-0033 | high | high | confirmed | bola | GET /orders/:id | `node-express/routes/orders.js:8` | BOLA in GET /orders/:id: missing owner verification |
126
+ | BOLA-R-0038 | high | high | confirmed | bola | GET /stats | `node-express/routes/orders.js:28` | BOLA in GET /stats: missing owner verification |
127
+ | BOLA-R-0043 | high | high | confirmed | bola | ANY /perl-cgi/cgi-bin/order.cgi | `perl-cgi/cgi-bin/order.cgi:13` | BOLA in ANY /perl-cgi/cgi-bin/order.cgi: missing owner verification |
128
+ | BOLA-R-0044 | high | high | confirmed | bola | ANY /invoice/view/{id} | `php-codeigniter/application/controllers/Invoice.php:10` | BOLA in ANY /invoice/view/{id}: missing owner verification |
129
+ | BOLA-R-0046 | high | medium | likely | bola | ANY /invoice/update | `php-codeigniter/application/controllers/Invoice.php:23` | BOLA in ANY /invoice/update: missing owner verification |
130
+ | BOLA-R-0057-1 | high | medium | likely | bola | GET /php-plain/admin.php?action=view | `php-plain/admin.php:8` | BOLA in GET /php-plain/admin.php?action=view: missing admin authorization |
131
+ | BOLA-R-0057-2 | high | medium | likely | bola | POST /php-plain/admin.php?action=delete | `php-plain/admin.php:6` | BOLA in POST /php-plain/admin.php?action=delete: missing admin authorization |
132
+ | BOLA-R-0058-1 | high | medium | likely | bola | GET /php-plain/admin.php?action=view | `php-plain/admin.php:10` | BOLA in GET /php-plain/admin.php?action=view: missing admin authorization |
133
+ | BOLA-R-0058-2 | high | medium | likely | bola | POST /php-plain/admin.php?action=delete | `php-plain/admin.php:12` | BOLA in POST /php-plain/admin.php?action=delete: missing admin authorization |
134
+ | BOLA-R-0059-1 | high | high | confirmed | bola | POST /php-plain/manage_users.php | `php-plain/manage_users.php:6` | BOLA in POST /php-plain/manage_users.php: missing admin authorization |
135
+ | BOLA-R-0061-1 | high | medium | likely | bola | GET /php-plain/order_detail.php | `php-plain/order_detail.php:6` | BOLA in GET /php-plain/order_detail.php: missing ownership verification |
136
+ | BOLA-R-0066-1 | high | high | confirmed | bola | POST /php-plain/admin/delete_user.php | `php-plain/admin/delete_user.php:6` | BOLA in POST /php-plain/admin/delete_user.php: missing admin authorization |
137
+ | BOLA-R-0067-1 | high | high | confirmed | bola | POST /php-plain/admin/promote.php | `php-plain/admin/promote.php:6` | BOLA in POST /php-plain/admin/promote.php: missing admin authorization |
138
+ | BOLA-R-0069-1 | high | high | confirmed | bola | GET /orders/<int:order_id> | `python-flask/app.py:12` | BOLA in GET /orders/<int:order_id>: missing ownership verification |
139
+ | BOLA-R-0073 | high | medium | likely | bola | POST /users/<int:uid>/name | `python-flask/profile.py:16` | BOLA in POST /users/<uid>/name: missing owner verification |
140
+ | BOLA-R-0074 | high | medium | likely | bola | PATCH /users/<int:uid> | `python-flask/profile.py:24` | BOLA in PATCH /users/<uid>: missing owner verification |
141
+ | MASS-M-0009-1 | high | medium | likely | mass_assignment | | `php-laravel/app/Http/Controllers/AccountController.php:23` | Team creation allows owner_id to be set by any user |
142
+ | MASS-M-0006-1 | medium | medium | likely | mass_assignment | | `node-express/routes/profile.js:8` | Profile update binds entire request body to User model |
143
+ | MASS-M-0007-1 | medium | medium | likely | mass_assignment | | `node-express/routes/profile.js:16` | Profile update binds entire request body to User model |
144
+ | MASS-M-0008-1 | medium | medium | likely | mass_assignment | | `php-laravel/app/Http/Controllers/AccountController.php:13` | User registration binds entire request body to User model |
145
+ | MASS-M-0010-1 | medium | medium | likely | mass_assignment | | `php-laravel/app/Http/Controllers/AccountController.php:36` | Team creation binds entire request body to Team model |
146
+ | MASS-M-0014-1 | medium | medium | likely | mass_assignment | | `python-flask/profile.py:10` | User creation binds entire request JSON to User model |
147
+ | MASS-M-0015-1 | medium | medium | likely | mass_assignment | | `python-flask/profile.py:27` | PATCH endpoint sets arbitrary attributes from request JSON |
148
+
149
+ ### BFLA-R-0003-1 — Unrestricted member deletion in classic‑ASP
150
+
151
+ - **Severity / confidence:** critical / high
152
+ - **Status:** confirmed
153
+ - **Category:** bfla (missing_role_check) — CWE-285
154
+ - **Endpoint:** - -
155
+ - **Location:** `classic-asp/shop/member.asp:9`
156
+
157
+ **Impact.** Any authenticated user can delete any member record
158
+
159
+ **Evidence.**
160
+
161
+ - `classic-asp/shop/member.asp:10` — DELETE statement executed without admin check
162
+ - `classic-asp/shop/member.asp:1` — only session login check, no role verification
163
+
164
+ **Recommendation.** Add an admin role check before executing the DELETE
165
+
166
+ *Verifier:* confirmed — checked: classic-asp/shop/member.asp:1-10, classic-asp/shop/inc/auth.asp:1-3. The included auth.asp only verifies a logged‑in session; it does not enforce an admin role. The delete case uses the member_id from the query string without any role check.
167
+
168
+ ### BFLA-R-0007-1 — Unrestricted user deletion in ASP.NET MVC
169
+
170
+ - **Severity / confidence:** critical / high
171
+ - **Status:** confirmed
172
+ - **Category:** bfla (missing_role_check) — CWE-285
173
+ - **Endpoint:** - -
174
+ - **Location:** `dotnet-legacy/Web/Controllers/AdminController.cs:12`
175
+
176
+ **Impact.** Any authenticated user can delete any user account
177
+
178
+ **Evidence.**
179
+
180
+ - `dotnet-legacy/Web/Controllers/AdminController.cs:12` — DeleteUser action lacks [Authorize(Roles="Admin")]
181
+
182
+ **Recommendation.** Add [Authorize(Roles="Admin")] to DeleteUser action
183
+
184
+ *Verifier:* confirmed — checked: dotnet-legacy/Web/Controllers/AdminController.cs:6-12. The controller is marked with [Authorize], allowing any authenticated user. The DeleteUser action lacks a role restriction, so any authenticated user can delete any account.
185
+
186
+ ### BFLA-R-0009-1 — Export endpoint controlled by request parameter
187
+
188
+ - **Severity / confidence:** critical / high
189
+ - **Status:** confirmed
190
+ - **Category:** bfla (role_from_request) — CWE-285
191
+ - **Endpoint:** - -
192
+ - **Location:** `dotnet-legacy/Web/Controllers/AdminController.cs:30`
193
+
194
+ **Impact.** Any authenticated user can export all user data
195
+
196
+ **Evidence.**
197
+
198
+ - `dotnet-legacy/Web/Controllers/AdminController.cs:32` — Request.QueryString["isAdmin"] == "true" allows export
199
+ - `dotnet-legacy/Web/Controllers/AdminController.cs:30` — no server‑side role check
200
+
201
+ **Recommendation.** Validate admin role from session before allowing export
202
+
203
+ *Verifier:* confirmed — checked: dotnet-legacy/Web/Controllers/AdminController.cs:30-34. Export logic relies solely on a request query string parameter. No server‑side role validation is performed, allowing any authenticated user to trigger the export.
204
+
205
+ ### BFLA-R-0023-1 — Unrestricted user deletion in Spring MVC
206
+
207
+ - **Severity / confidence:** critical / medium
208
+ - **Status:** likely
209
+ - **Category:** bfla (missing_role_check) — CWE-285
210
+ - **Endpoint:** - -
211
+ - **Location:** `java-legacy/src/com/acme/web/AdminUserController.java:13`
212
+
213
+ **Impact.** Any authenticated user can delete any user
214
+
215
+ **Evidence.**
216
+
217
+ - `java-legacy/src/com/acme/web/AdminUserController.java:13` — delete method lacks @PreAuthorize
218
+ - `java-legacy/src/com/acme/web/AdminUserController.java:19` — other actions have @PreAuthorize, but not this one
219
+
220
+ **Recommendation.** Add @PreAuthorize("hasRole('ADMIN')") to delete method
221
+
222
+ *Verifier:* likely — checked: java-legacy/src/com/acme/web/AdminUserController.java lines 13-15, java-legacy/src/com/acme/web/AdminUserController.java lines 19-21. The delete method lacks any @PreAuthorize or other role guard in the visible code. No global filter or security configuration is shown in the provided context, so a compensating control cannot be confirmed.
223
+
224
+ ### BFLA-R-0030-1 — Unrestricted user deletion in Express.js
225
+
226
+ - **Severity / confidence:** critical / medium
227
+ - **Status:** likely
228
+ - **Category:** bfla (missing_role_check) — CWE-285
229
+ - **Endpoint:** - -
230
+ - **Location:** `node-express/routes/admin.js:8`
231
+
232
+ **Impact.** Any authenticated user can delete any user
233
+
234
+ **Evidence.**
235
+
236
+ - `node-express/routes/admin.js:8` — no requireAdmin middleware applied
237
+
238
+ **Recommendation.** Add requireAdmin middleware to the delete route
239
+
240
+ *Verifier:* likely — checked: node-express/routes/admin.js lines 8-9. The delete route uses only ensureLoggedIn; the requireAdmin middleware is not applied in the visible snippet, and no other role check is present.
241
+
242
+ ### BFLA-R-0032-1 — Export endpoint controlled by query parameter in Express.js
243
+
244
+ - **Severity / confidence:** critical / medium
245
+ - **Status:** likely
246
+ - **Category:** bfla (role_from_request) — CWE-285
247
+ - **Endpoint:** - -
248
+ - **Location:** `node-express/routes/admin.js:16`
249
+
250
+ **Impact.** Any authenticated user can export all user data
251
+
252
+ **Evidence.**
253
+
254
+ - `node-express/routes/admin.js:17` — req.query.isAdmin === 'true' allows export
255
+ - `node-express/routes/admin.js:16` — no role check before export
256
+
257
+ **Recommendation.** Validate admin role from session before allowing export
258
+
259
+ *Verifier:* likely — checked: node-express/routes/admin.js lines 16-18. The export endpoint checks only a query parameter for admin status; no session‑based role verification is shown in the snippet.
260
+
261
+ ### BFLA-R-0057-1 — Unrestricted user view in PHP
262
+
263
+ - **Severity / confidence:** critical / medium
264
+ - **Status:** likely
265
+ - **Category:** bfla (missing_role_check) — CWE-285
266
+ - **Endpoint:** - -
267
+ - **Location:** `php-plain/admin.php:6`
268
+
269
+ **Impact.** Any authenticated user can view any user record
270
+
271
+ **Evidence.**
272
+
273
+ - `php-plain/admin.php:6` — SELECT * FROM users WHERE id = ... executed without admin check
274
+ - `php-plain/admin.php:2` — only session login check, no role verification
275
+
276
+ **Recommendation.** Add admin role check before executing the SELECT
277
+
278
+ *Verifier:* likely — checked: php-plain/admin.php lines 2-8, php-plain/inc/auth.php lines 1-7. The included auth file performs only a login check; there is no admin role guard before the SELECT statement in the visible code.
279
+
280
+ ### BFLA-R-0058-1 — Unrestricted user deletion in PHP
281
+
282
+ - **Severity / confidence:** critical / medium
283
+ - **Status:** likely
284
+ - **Category:** bfla (missing_role_check) — CWE-285
285
+ - **Endpoint:** - -
286
+ - **Location:** `php-plain/admin.php:10`
287
+
288
+ **Impact.** Any authenticated user can delete any user record
289
+
290
+ **Evidence.**
291
+
292
+ - `php-plain/admin.php:10` — DELETE executed without admin check
293
+ - `php-plain/admin.php:2` — only session login check, no role verification
294
+
295
+ **Recommendation.** Add admin role check before executing the DELETE
296
+
297
+ *Verifier:* likely — checked: php-plain/admin.php lines 10-12, php-plain/inc/auth.php lines 1-7. The DELETE statement is executed without any admin role check in the visible code, and the included auth file does not provide such a guard.
298
+
299
+ ### BFLA-R-0059-1 — Client‑side admin check allows user deletion in PHP
300
+
301
+ - **Severity / confidence:** critical / medium
302
+ - **Status:** likely
303
+ - **Category:** bfla (client_side_role_check) — CWE-285
304
+ - **Endpoint:** - -
305
+ - **Location:** `php-plain/manage_users.php:1`
306
+
307
+ **Impact.** Any authenticated user can delete any user record
308
+
309
+ **Evidence.**
310
+
311
+ - `php-plain/manage_users.php:5` — DELETE executed without server‑side admin check
312
+ - `php-plain/manage_users.php:11` — role check only in HTML, not in handler
313
+
314
+ **Recommendation.** Add server‑side admin check before executing the DELETE
315
+
316
+ *Verifier:* likely — checked: php-plain/manage_users.php, php-plain/inc/auth.php, php-plain/inc/db.php. Deletion is performed on POST without a server‑side role check; the role check appears only in the HTML output.
317
+
318
+ ### BFLA-R-0063-1 — Privilege escalation via role field in profile update
319
+
320
+ - **Severity / confidence:** critical / medium
321
+ - **Status:** likely
322
+ - **Category:** bfla (role_from_request) — CWE-285
323
+ - **Endpoint:** - -
324
+ - **Location:** `php-plain/profile.php:1`
325
+
326
+ **Impact.** Any authenticated user can change their own role
327
+
328
+ **Evidence.**
329
+
330
+ - `php-plain/profile.php:10` — role set from $_POST['role'] without admin check
331
+ - `php-plain/profile.php:2` — only session login check, no role verification
332
+
333
+ **Recommendation.** Validate role changes against allowed values and enforce admin checks
334
+
335
+ *Verifier:* likely — checked: php-plain/profile.php, php-plain/inc/auth.php, php-plain/inc/db.php. The role field is updated directly from POST data with no admin verification in the visible code.
336
+
337
+ ### BFLA-R-0066-1 — Unrestricted user deletion in PHP
338
+
339
+ - **Severity / confidence:** critical / medium
340
+ - **Status:** likely
341
+ - **Category:** bfla (missing_role_check) — CWE-285
342
+ - **Endpoint:** - -
343
+ - **Location:** `php-plain/admin/delete_user.php:1`
344
+
345
+ **Impact.** Any authenticated user can delete any user record
346
+
347
+ **Evidence.**
348
+
349
+ - `php-plain/admin/delete_user.php:6` — DELETE executed without admin check
350
+ - `php-plain/admin/delete_user.php:2` — only session login check, no role verification
351
+
352
+ **Recommendation.** Add admin role check before executing the DELETE
353
+
354
+ *Verifier:* likely — checked: php-plain/admin/delete_user.php, php-plain/inc/auth.php, php-plain/inc/db.php. No role or ownership check is present in the visible code. The included auth file only verifies session existence.
355
+
356
+ ### BFLA-R-0067-1 — Privilege escalation via role promotion in PHP
357
+
358
+ - **Severity / confidence:** critical / medium
359
+ - **Status:** likely
360
+ - **Category:** bfla (role_from_request) — CWE-285
361
+ - **Endpoint:** - -
362
+ - **Location:** `php-plain/admin/promote.php:1`
363
+
364
+ **Impact.** Any authenticated user can promote themselves to admin
365
+
366
+ **Evidence.**
367
+
368
+ - `php-plain/admin/promote.php:5` — role set from $_POST['is_admin'] without admin check
369
+ - `php-plain/admin/promote.php:2` — only session login check, no role verification
370
+
371
+ **Recommendation.** Validate admin role from session before allowing role changes
372
+
373
+ *Verifier:* likely — checked: php-plain/admin/promote.php, php-plain/inc/auth.php, php-plain/inc/db.php. The code sets the role directly from POST data without any server‑side admin check. No compensating control is visible.
374
+
375
+ ### INJ-I-0001 — SQL Injection in classic-asp/shop/member.asp:6
376
+
377
+ - **Severity / confidence:** critical / high
378
+ - **Status:** confirmed
379
+ - **Category:** sql_injection (string_concatenation) — CWE-89
380
+ - **Endpoint:** - -
381
+ - **Location:** `classic-asp/shop/member.asp:6`
382
+
383
+ **Evidence.**
384
+
385
+ - `classic-asp/shop/member.asp:6` — Unsanitized input concatenated into query (member_id later)
386
+ `sql = "UPDATE members SET name = '" & Replace(Request.Form("name"), "'", "''") & "'"`
387
+ - `classic-asp/shop/member.asp:7` — Unsanitized input concatenated into query
388
+ `sql = sql & " WHERE member_id = " & Request.Form("member_id")`
389
+ - `classic-asp/shop/member.asp:8` — Query executed without parameter binding
390
+ `conn.Execute sql`
391
+
392
+ **Recommendation.** Use parameterized queries
393
+
394
+ *Verifier:* confirmed — checked: classic-asp/shop/member.asp:6-8, classic-asp/shop/inc/auth.asp:1-3. The SQL UPDATE statement is built via string concatenation with unsanitized form values. The included auth.asp only verifies that a user is logged in; it does not provide parameter binding or sanitization.
395
+
396
+ ### INJ-I-0002 — SQL Injection in classic-asp/shop/member.asp:7
397
+
398
+ - **Severity / confidence:** critical / high
399
+ - **Status:** confirmed
400
+ - **Category:** sql_injection (string_concatenation) — CWE-89
401
+ - **Endpoint:** - -
402
+ - **Location:** `classic-asp/shop/member.asp:7`
403
+
404
+ **Evidence.**
405
+
406
+ - `classic-asp/shop/member.asp:7` — Unsanitized input concatenated into query
407
+ `sql = sql & " WHERE member_id = " & Request.Form("member_id")`
408
+ - `classic-asp/shop/member.asp:8` — Query executed without parameter binding
409
+ `conn.Execute sql`
410
+
411
+ **Recommendation.** Use parameterized queries
412
+
413
+ *Verifier:* confirmed — checked: classic-asp/shop/member.asp:7-8, classic-asp/shop/inc/auth.asp:1-3. The WHERE clause is concatenated with an unsanitized form value. No parameter binding or integer cast is present.
414
+
415
+ ### INJ-I-0003 — SQL Injection in classic-asp/shop/member.asp:10
416
+
417
+ - **Severity / confidence:** critical / high
418
+ - **Status:** confirmed
419
+ - **Category:** sql_injection (string_concatenation) — CWE-89
420
+ - **Endpoint:** - -
421
+ - **Location:** `classic-asp/shop/member.asp:10`
422
+
423
+ **Evidence.**
424
+
425
+ - `classic-asp/shop/member.asp:10` — Unsanitized input concatenated into query
426
+ `conn.Execute "DELETE FROM members WHERE member_id = " & Request.QueryString("member_id")`
427
+
428
+ **Recommendation.** Use parameterized queries
429
+
430
+ *Verifier:* confirmed — checked: classic-asp/shop/member.asp:10, classic-asp/shop/inc/auth.asp:1-3. The DELETE statement concatenates an unsanitized query string value. No sanitization or parameter binding is visible.
431
+
432
+ ### INJ-I-0004 — SQL Injection in classic-asp/shop/order.asp:6
433
+
434
+ - **Severity / confidence:** critical / high
435
+ - **Status:** confirmed
436
+ - **Category:** sql_injection (string_concatenation) — CWE-89
437
+ - **Endpoint:** - -
438
+ - **Location:** `classic-asp/shop/order.asp:6`
439
+
440
+ **Evidence.**
441
+
442
+ - `classic-asp/shop/order.asp:6` — Unsanitized input concatenated into query
443
+ `Set rs = conn.Execute("SELECT * FROM orders WHERE id = " & id)`
444
+
445
+ **Recommendation.** Use parameterized queries
446
+
447
+ *Verifier:* confirmed — checked: classic-asp/shop/order.asp lines 5-6, classic-asp/shop/order.asp line 12. The query at line 6 concatenates the unsanitized request parameter directly into the SQL statement. No ownership check or parameter binding is performed before execution. The subsequent query at line 12 includes a user_id filter, but it does not mitigate the vulnerability in the first query.
448
+
449
+ ### INJ-I-0006 — SQL Injection in coldfusion/app/OrderService.cfc:5
450
+
451
+ - **Severity / confidence:** critical / high
452
+ - **Status:** confirmed
453
+ - **Category:** sql_injection (string_concatenation) — CWE-89
454
+ - **Endpoint:** - -
455
+ - **Location:** `coldfusion/app/OrderService.cfc:5`
456
+
457
+ **Evidence.**
458
+
459
+ - `coldfusion/app/OrderService.cfc:5` — Unsanitized input concatenated into query
460
+ `SELECT * FROM orders WHERE id = #arguments.orderId#`
461
+
462
+ **Recommendation.** Use cfqueryparam to bind parameters
463
+
464
+ *Verifier:* confirmed — checked: coldfusion/app/OrderService.cfc lines 3-6. The query at line 5 directly interpolates the unvalidated argument `orderId` into the SQL string. No parameter binding, type casting, or ownership check is present.
465
+
466
+ ### INJ-I-0007 — SQL Injection in coldfusion/app/order.cfm:3
467
+
468
+ - **Severity / confidence:** critical / high
469
+ - **Status:** confirmed
470
+ - **Category:** sql_injection (string_concatenation) — CWE-89
471
+ - **Endpoint:** - -
472
+ - **Location:** `coldfusion/app/order.cfm:3`
473
+
474
+ **Evidence.**
475
+
476
+ - `coldfusion/app/order.cfm:3` — Unsanitized input concatenated into query
477
+ `SELECT * FROM orders WHERE id = #url.id#`
478
+
479
+ **Recommendation.** Use cfqueryparam to bind parameters
480
+
481
+ *Verifier:* confirmed — checked: coldfusion/app/order.cfm lines 2-4. The query at line 3 concatenates the unsanitized `url.id` into the SQL statement. Although a subsequent query uses `cfqueryparam` and a user_id filter, the first query remains vulnerable.
482
+
483
+ ### INJ-I-0008-1 — SQL Injection in dotnet-legacy/Web/Controllers/InvoiceController.cs:28
484
+
485
+ - **Severity / confidence:** critical / medium
486
+ - **Status:** likely
487
+ - **Category:** sql_injection (string_concatenation) — CWE-89
488
+ - **Endpoint:** - -
489
+ - **Location:** `dotnet-legacy/Web/Controllers/InvoiceController.cs:28`
490
+
491
+ **Evidence.**
492
+
493
+ - `dotnet-legacy/Web/Controllers/InvoiceController.cs:27` — source: POST body
494
+ `var customer = Request.Form["customer"];`
495
+ - `dotnet-legacy/Web/Controllers/InvoiceController.cs:28` — unsanitized concatenation
496
+ `var list = db.Database.SqlQuery<Invoice>("SELECT * FROM Invoices WHERE Customer = '" + customer + "'").ToList();`
497
+
498
+ **Recommendation.** Use parameterized queries
499
+
500
+ *Verifier:* likely — checked: dotnet-legacy/Web/Controllers/InvoiceController.cs lines 25-29 (Search action). No parameter binding, casting, or allow‑list is visible in the provided code context. The raw concatenation of `customer` into the SQL string remains a potential injection vector.
501
+
502
+ ### INJ-I-0009 — SQL Injection in dotnet-legacy/Web/Orders/EditOrder.aspx.vb:7
503
+
504
+ - **Severity / confidence:** critical / high
505
+ - **Status:** confirmed
506
+ - **Category:** sql_injection (string_concatenation) — CWE-89
507
+ - **Endpoint:** - -
508
+ - **Location:** `dotnet-legacy/Web/Orders/EditOrder.aspx.vb:7`
509
+
510
+ **Evidence.**
511
+
512
+ - `dotnet-legacy/Web/Orders/EditOrder.aspx.vb:7` — Unsanitized input concatenated into query
513
+ `Dim sql As String = "UPDATE Orders SET Note = '" & txtNote.Text & "'"`
514
+ - `dotnet-legacy/Web/Orders/EditOrder.aspx.vb:8` — Unsanitized input concatenated into query
515
+ `sql &= " WHERE OrderId = " & hfOrderId.Value`
516
+ - `dotnet-legacy/Web/Orders/EditOrder.aspx.vb:10` — Query executed without parameter binding
517
+ `cmd.ExecuteNonQuery()`
518
+
519
+ **Recommendation.** Use parameterized queries
520
+
521
+ *Verifier:* confirmed — checked: dotnet-legacy/Web/Orders/EditOrder.aspx.vb lines 6-8. The SQL string is built by concatenating `txtNote.Text` and `hfOrderId.Value` without any parameterization or type casting. No ownership check is performed before execution.
522
+
523
+ ### INJ-I-0010 — SQL Injection in dotnet-legacy/Web/Orders/EditOrder.aspx.vb:8
524
+
525
+ - **Severity / confidence:** critical / high
526
+ - **Status:** confirmed
527
+ - **Category:** sql_injection (string_concatenation) — CWE-89
528
+ - **Endpoint:** - -
529
+ - **Location:** `dotnet-legacy/Web/Orders/EditOrder.aspx.vb:8`
530
+
531
+ **Evidence.**
532
+
533
+ - `dotnet-legacy/Web/Orders/EditOrder.aspx.vb:8` — Unsanitized input concatenated into query
534
+ `sql &= " WHERE OrderId = " & hfOrderId.Value`
535
+ - `dotnet-legacy/Web/Orders/EditOrder.aspx.vb:10` — Query executed without parameter binding
536
+ `cmd.ExecuteNonQuery()`
537
+
538
+ **Recommendation.** Use parameterized queries
539
+
540
+ *Verifier:* confirmed — checked: dotnet-legacy/Web/Orders/EditOrder.aspx.vb lines 7-8. Same as INJ-I-0009: the query is constructed via string concatenation with user-supplied values and executed without parameter binding or ownership validation.
541
+
542
+ ### INJ-I-0011-1 — SQL Injection in dotnet-legacy/Web/Orders/OrderDetail.aspx.cs:13
543
+
544
+ - **Severity / confidence:** critical / high
545
+ - **Status:** confirmed
546
+ - **Category:** sql_injection (string_concatenation) — CWE-89
547
+ - **Endpoint:** - -
548
+ - **Location:** `dotnet-legacy/Web/Orders/OrderDetail.aspx.cs:13`
549
+
550
+ **Evidence.**
551
+
552
+ - `dotnet-legacy/Web/Orders/OrderDetail.aspx.cs:13` — Unsanitized input concatenated into query
553
+ `var cmd = new SqlCommand("SELECT * FROM Orders WHERE OrderId = " + id, conn);`
554
+ - `dotnet-legacy/Web/Orders/OrderDetail.aspx.cs:14` — Query executed without parameter binding
555
+ `conn.Open();`
556
+
557
+ **Recommendation.** Use parameterized queries
558
+
559
+ *Verifier:* confirmed — checked: line 13. The query at line 13 concatenates the unsanitized request parameter "id" directly into the SQL string and is executed immediately. No ownership, role check, integer cast, or allow‑list is present in the visible code.
560
+
561
+ ### INJ-I-0011-3 — SQL Injection in dotnet-legacy/Web/Orders/OrderDetail.aspx.cs:20
562
+
563
+ - **Severity / confidence:** critical / high
564
+ - **Status:** confirmed
565
+ - **Category:** sql_injection (string_interpolation) — CWE-89
566
+ - **Endpoint:** - -
567
+ - **Location:** `dotnet-legacy/Web/Orders/OrderDetail.aspx.cs:13`
568
+
569
+ **Evidence.**
570
+
571
+ - `dotnet-legacy/Web/Orders/OrderDetail.aspx.cs:20` — Unsanitized input concatenated into query
572
+ `string sql3 = $"DELETE FROM Carts WHERE CartId = {Request.Form["cart"]}";`
573
+ - `dotnet-legacy/Web/Orders/OrderDetail.aspx.cs:22` — Query executed without parameter binding
574
+ `new SqlCommand(sql3, conn).ExecuteNonQuery();`
575
+
576
+ **Recommendation.** Use parameterized queries
577
+
578
+ *Verifier:* confirmed — checked: line 20. The interpolated string at line 20 directly injects the unsanitized form parameter "cart" into a DELETE statement, executed at line 22. No protection is evident.
579
+
580
+ ### INJ-I-0012 — SQL Injection in dotnet-legacy/Web/Orders/OrderDetail.aspx.cs:19
581
+
582
+ - **Severity / confidence:** critical / high
583
+ - **Status:** confirmed
584
+ - **Category:** sql_injection (string_concatenation) — CWE-89
585
+ - **Endpoint:** - -
586
+ - **Location:** `dotnet-legacy/Web/Orders/OrderDetail.aspx.cs:19`
587
+
588
+ **Evidence.**
589
+
590
+ - `dotnet-legacy/Web/Orders/OrderDetail.aspx.cs:19` — Unsanitized input concatenated into query
591
+ `string sql2 = string.Format("SELECT * FROM Logs WHERE Ref = '{0}'", Request["ref"]);`
592
+ - `dotnet-legacy/Web/Orders/OrderDetail.aspx.cs:21` — Query executed without parameter binding
593
+ `new SqlCommand(sql2, conn).ExecuteReader();`
594
+
595
+ **Recommendation.** Use parameterized queries
596
+
597
+ *Verifier:* confirmed — checked: line 19. Same as INJ-I-0011-2: unsanitized "ref" is concatenated into SQL and executed without parameter binding.
598
+
599
+ ### INJ-I-0013 — SQL Injection in dotnet-legacy/Web/Orders/OrderDetail.aspx.cs:20
600
+
601
+ - **Severity / confidence:** critical / high
602
+ - **Status:** confirmed
603
+ - **Category:** sql_injection (string_interpolation) — CWE-89
604
+ - **Endpoint:** - -
605
+ - **Location:** `dotnet-legacy/Web/Orders/OrderDetail.aspx.cs:20`
606
+
607
+ **Evidence.**
608
+
609
+ - `dotnet-legacy/Web/Orders/OrderDetail.aspx.cs:20` — Unsanitized input concatenated into query
610
+ `string sql3 = $"DELETE FROM Carts WHERE CartId = {Request.Form["cart"]}";`
611
+ - `dotnet-legacy/Web/Orders/OrderDetail.aspx.cs:22` — Query executed without parameter binding
612
+ `new SqlCommand(sql3, conn).ExecuteNonQuery();`
613
+
614
+ **Recommendation.** Use parameterized queries
615
+
616
+ *Verifier:* confirmed — checked: line 20. Duplicate finding ID; same issue as INJ-I-0011-3.
617
+
618
+ ### INJ-I-0014 — SQL Injection in java-legacy/WebContent/order/detail.jsp:5
619
+
620
+ - **Severity / confidence:** critical / medium
621
+ - **Status:** likely
622
+ - **Category:** sql_injection (string_concatenation) — CWE-89
623
+ - **Endpoint:** - -
624
+ - **Location:** `java-legacy/WebContent/order/detail.jsp:5`
625
+
626
+ **Evidence.**
627
+
628
+ - `java-legacy/WebContent/order/detail.jsp:5` — Unsanitized input concatenated into query
629
+ `ResultSet rs = c.createStatement().executeQuery("SELECT * FROM orders WHERE order_no = '" + no + "'");`
630
+
631
+ **Recommendation.** Use PreparedStatement with parameters
632
+
633
+ *Verifier:* likely — checked: java-legacy/WebContent/order/detail.jsp lines 1-7. The JSP page concatenates the request parameter directly into a SQL query without any parameter binding, casting, or ownership check visible in the provided code context.
634
+
635
+ ### INJ-I-0015-1 — SQL Injection in java-legacy/src/com/acme/mapper/OrderMapper.xml:9
636
+
637
+ - **Severity / confidence:** critical / medium
638
+ - **Status:** likely
639
+ - **Category:** sql_injection (template_placeholder) — CWE-89
640
+ - **Endpoint:** - -
641
+ - **Location:** `java-legacy/src/com/acme/mapper/OrderMapper.xml:9`
642
+
643
+ **Evidence.**
644
+
645
+ - `java-legacy/src/com/acme/mapper/OrderMapper.xml:9` — raw string substitution unsanitized
646
+ `ORDER BY ${orderBy}`
647
+
648
+ **Recommendation.** Use parameterized queries or allow-list ORDER BY columns
649
+
650
+ *Verifier:* likely — checked: java-legacy/src/com/acme/mapper/OrderMapper.xml lines 8-10 (ORDER BY clause). The `${orderBy}` placeholder is substituted directly into the SQL string with no visible allow‑list or type enforcement in the provided snippet.
651
+
652
+ ### INJ-I-0016 — SQL Injection in java-legacy/src/com/acme/struts/EditUserAction.java:13
653
+
654
+ - **Severity / confidence:** critical / medium
655
+ - **Status:** likely
656
+ - **Category:** sql_injection (string_concatenation) — CWE-89
657
+ - **Endpoint:** - -
658
+ - **Location:** `java-legacy/src/com/acme/struts/EditUserAction.java:13`
659
+
660
+ **Evidence.**
661
+
662
+ - `java-legacy/src/com/acme/struts/EditUserAction.java:13` — Unsanitized input concatenated into query
663
+ `PreparedStatement ps = conn.prepareStatement("UPDATE users SET email = '" + email + "' WHERE id = " + userId);`
664
+ - `java-legacy/src/com/acme/struts/EditUserAction.java:14` — Query executed without parameter binding
665
+ `ps.executeUpdate();`
666
+
667
+ **Recommendation.** Use PreparedStatement with parameters
668
+
669
+ *Verifier:* likely — checked: java-legacy/src/com/acme/struts/EditUserAction.java lines 1-17. The action builds an UPDATE statement by concatenating user-supplied values without using prepared statement parameters or any ownership verification in the visible code.
670
+
671
+ ### INJ-I-0017 — SQL Injection in java-legacy/src/com/acme/web/InvoiceController.java:29
672
+
673
+ - **Severity / confidence:** critical / medium
674
+ - **Status:** likely
675
+ - **Category:** sql_injection (string_concatenation) — CWE-89
676
+ - **Endpoint:** - -
677
+ - **Location:** `java-legacy/src/com/acme/web/InvoiceController.java:29`
678
+
679
+ **Evidence.**
680
+
681
+ - `java-legacy/src/com/acme/web/InvoiceController.java:29` — Unsanitized input concatenated into query
682
+ `model.addAttribute("list", session.createQuery("from Invoice i where i.customer = '" + customer + "'").list());`
683
+
684
+ **Recommendation.** Use parameterized HQL/JPQL
685
+
686
+ *Verifier:* likely — checked: java-legacy/src/com/acme/web/InvoiceController.java lines 9-31. The controller concatenates the 'customer' request parameter into an HQL query without parameter binding or ownership checks in the shown snippet.
687
+
688
+ ### INJ-I-0018-1 — SQL Injection in java-legacy/src/com/acme/web/OrderServlet.java:15
689
+
690
+ - **Severity / confidence:** critical / medium
691
+ - **Status:** likely
692
+ - **Category:** sql_injection (string_concatenation) — CWE-89
693
+ - **Endpoint:** - -
694
+ - **Location:** `java-legacy/src/com/acme/web/OrderServlet.java:15`
695
+
696
+ **Evidence.**
697
+
698
+ - `java-legacy/src/com/acme/web/OrderServlet.java:11` — source: request parameter
699
+ `String id = request.getParameter("orderId");`
700
+ - `java-legacy/src/com/acme/web/OrderServlet.java:15` — unsanitized concatenation
701
+ `ResultSet rs = stmt.executeQuery("SELECT * FROM orders WHERE id = '" + id + "'");`
702
+
703
+ **Recommendation.** Use prepared statements
704
+
705
+ *Verifier:* likely — checked: java-legacy/src/com/acme/web/OrderServlet.java lines 13-15 (first query). The `id` parameter is concatenated into the SQL string without any casting or validation in the shown code.
706
+
707
+ ### INJ-I-0020-1 — SQL Injection in node-express/routes/orders.js:17
708
+
709
+ - **Severity / confidence:** critical / medium
710
+ - **Status:** likely
711
+ - **Category:** sql_injection (string_concatenation) — CWE-89
712
+ - **Endpoint:** - -
713
+ - **Location:** `node-express/routes/orders.js:17`
714
+
715
+ **Evidence.**
716
+
717
+ - `node-express/routes/orders.js:17` — Unsanitized input concatenated into query
718
+ `db.query("SELECT * FROM reports WHERE month = '" + req.query.month + "'", function (e, rows) { res.json(rows); });`
719
+
720
+ **Recommendation.** Use parameterized queries
721
+
722
+ *Verifier:* likely — checked: node-express/routes/orders.js lines 1-32. The route constructs a raw SQL query by concatenating req.query.month without any type casting, parameter binding, or ownership verification in the visible code.
723
+
724
+ ### INJ-I-0020-3 — NoSQL Injection in node-express/routes/orders.js:25
725
+
726
+ - **Severity / confidence:** critical / high
727
+ - **Status:** confirmed
728
+ - **Category:** nosql_injection (operator_injection) — CWE-89
729
+ - **Endpoint:** - -
730
+ - **Location:** `node-express/routes/orders.js:17`
731
+
732
+ **Evidence.**
733
+
734
+ - `node-express/routes/orders.js:25` — Unescaped string used in $where expression
735
+ `db.collection('items').find({ $where: "this.name == '" + req.query.n + "'" }).toArray(function (e, r) { res.json(r); });`
736
+
737
+ **Recommendation.** Avoid $where; use parameterized queries or safe operators
738
+
739
+ *Verifier:* confirmed — checked: lines 24-26 of node-express/routes/orders.js. The query concatenates user input into a $where expression with no sanitization or allow‑list. The only guard is ensureLoggedIn, which only verifies authentication, not ownership or input validation.
740
+
741
+ ### INJ-I-0020-4 — SQL Injection in node-express/routes/orders.js:29
742
+
743
+ - **Severity / confidence:** critical / high
744
+ - **Status:** confirmed
745
+ - **Category:** sql_injection (string_interpolation) — CWE-89
746
+ - **Endpoint:** - -
747
+ - **Location:** `node-express/routes/orders.js:17`
748
+
749
+ **Evidence.**
750
+
751
+ - `node-express/routes/orders.js:29` — Unsanitized input interpolated into query
752
+ `db.query('SELECT COUNT(*) AS n FROM orders WHERE shop_id = ${req.query.shop}', function (e, r) { res.json(r); });`
753
+
754
+ **Recommendation.** Use parameterized queries
755
+
756
+ *Verifier:* confirmed — checked: lines 28-30 of node-express/routes/orders.js. The SQL statement interpolates req.query.shop directly into the query string. No cast, parameter binding, or ownership check is present.
757
+
758
+ ### INJ-I-0021 — SQL Injection in node-express/routes/orders.js:29
759
+
760
+ - **Severity / confidence:** critical / high
761
+ - **Status:** confirmed
762
+ - **Category:** sql_injection (string_interpolation) — CWE-89
763
+ - **Endpoint:** - -
764
+ - **Location:** `node-express/routes/orders.js:29`
765
+
766
+ **Evidence.**
767
+
768
+ - `node-express/routes/orders.js:29` — Unsanitized input interpolated into query
769
+ `db.query('SELECT COUNT(*) AS n FROM orders WHERE shop_id = ${req.query.shop}', function (e, r) { res.json(r); });`
770
+
771
+ **Recommendation.** Use parameterized queries
772
+
773
+ *Verifier:* confirmed — checked: lines 28-30 of node-express/routes/orders.js. Same as INJ-I-0020-4; the route is identical and lacks any compensating control.
774
+
775
+ ### INJ-I-0022 — NoSQL Injection in node-express/routes/orders.js:21
776
+
777
+ - **Severity / confidence:** critical / high
778
+ - **Status:** confirmed
779
+ - **Category:** nosql_injection (operator_injection) — CWE-89
780
+ - **Endpoint:** - -
781
+ - **Location:** `node-express/routes/orders.js:21`
782
+
783
+ **Evidence.**
784
+
785
+ - `node-express/routes/orders.js:21` — Unvalidated request body used directly as query filter
786
+ `db.collection('users').findOne(req.body, function (e, u) { res.json(!!u); });`
787
+
788
+ **Recommendation.** Validate and whitelist query parameters; avoid passing raw request body to findOne
789
+
790
+ *Verifier:* confirmed — checked: lines 20-22 of node-express/routes/orders.js. The request body is passed directly to findOne without validation or sanitization. No authentication guard is applied to this POST /login route.
791
+
792
+ ### INJ-I-0023 — NoSQL Injection in node-express/routes/orders.js:25
793
+
794
+ - **Severity / confidence:** critical / high
795
+ - **Status:** confirmed
796
+ - **Category:** nosql_injection (operator_injection) — CWE-89
797
+ - **Endpoint:** - -
798
+ - **Location:** `node-express/routes/orders.js:25`
799
+
800
+ **Evidence.**
801
+
802
+ - `node-express/routes/orders.js:25` — Unescaped string used in $where expression
803
+ `db.collection('items').find({ $where: "this.name == '" + req.query.n + "'" }).toArray(function (e, r) { res.json(r); });`
804
+
805
+ **Recommendation.** Avoid $where; use parameterized queries or safe operators
806
+
807
+ *Verifier:* confirmed — checked: lines 24-26 of node-express/routes/orders.js. Identical to INJ-I-0020-3; no sanitization or allow‑list is present.
808
+
809
+ ### INJ-I-0024-1 — SQL Injection in perl-cgi/cgi-bin/order.cgi:13
810
+
811
+ - **Severity / confidence:** critical / high
812
+ - **Status:** confirmed
813
+ - **Category:** sql_injection (string_concatenation) — CWE-89
814
+ - **Endpoint:** - -
815
+ - **Location:** `perl-cgi/cgi-bin/order.cgi:13`
816
+
817
+ **Evidence.**
818
+
819
+ - `perl-cgi/cgi-bin/order.cgi:13` — Unsanitized input concatenated into query
820
+ `my $sth = $dbh->prepare("SELECT * FROM orders WHERE id = $id");`
821
+
822
+ **Recommendation.** Use parameterized queries
823
+
824
+ *Verifier:* confirmed — checked: perl-cgi/cgi-bin/order.cgi line 13, perl-cgi/cgi-bin/order.cgi line 11-14. The query concatenates the unsanitized $id directly into the SQL string. No integer cast, parameter binding, or ownership check is present in the visible code.
825
+
826
+ ### INJ-I-0025 — SQL Injection in perl-cgi/cgi-bin/order.cgi:19
827
+
828
+ - **Severity / confidence:** critical / high
829
+ - **Status:** confirmed
830
+ - **Category:** sql_injection (string_concatenation) — CWE-89
831
+ - **Endpoint:** - -
832
+ - **Location:** `perl-cgi/cgi-bin/order.cgi:19`
833
+
834
+ **Evidence.**
835
+
836
+ - `perl-cgi/cgi-bin/order.cgi:19` — Unsanitized input concatenated into query
837
+ `$dbh->do("DELETE FROM carts WHERE cart_id = " . $q->param('cart'));`
838
+
839
+ **Recommendation.** Use parameterized queries
840
+
841
+ *Verifier:* confirmed — checked: perl-cgi/cgi-bin/order.cgi line 19, perl-cgi/cgi-bin/order.cgi line 18-20. Same as INJ-I-0024-2; unsanitized input used in a DELETE statement with no protection.
842
+
843
+ ### INJ-I-0026-1 — SQL Injection in php-codeigniter/application/controllers/Invoice.php:10
844
+
845
+ - **Severity / confidence:** critical / high
846
+ - **Status:** confirmed
847
+ - **Category:** sql_injection (string_concatenation) — CWE-89
848
+ - **Endpoint:** - -
849
+ - **Location:** `php-codeigniter/application/controllers/Invoice.php:10`
850
+
851
+ **Evidence.**
852
+
853
+ - `php-codeigniter/application/controllers/Invoice.php:9` — source: URL segment
854
+ `$id = $this->uri->segment(3);`
855
+ - `php-codeigniter/application/controllers/Invoice.php:10` — unsanitized concatenation
856
+ `$q = $this->db->query("SELECT * FROM invoices WHERE id = $id");`
857
+
858
+ **Recommendation.** Use parameterized queries
859
+
860
+ *Verifier:* confirmed — checked: php-codeigniter/application/controllers/Invoice.php:9-10. The query concatenates the raw $id parameter without any sanitization, casting, or parameter binding. No ownership or role check is present in the visible code.
861
+
862
+ ### INJ-I-0028 — SQL Injection in php-plain/admin.php:12
863
+
864
+ - **Severity / confidence:** critical / high
865
+ - **Status:** confirmed
866
+ - **Category:** sql_injection (string_concatenation) — CWE-89
867
+ - **Endpoint:** - -
868
+ - **Location:** `php-plain/admin.php:12`
869
+
870
+ **Evidence.**
871
+
872
+ - `php-plain/admin.php:12` — Unsanitized input concatenated into query
873
+ `mysql_query("DELETE FROM users WHERE id = $id");`
874
+
875
+ **Recommendation.** Use parameterized queries
876
+
877
+ *Verifier:* confirmed — checked: php-plain/admin.php line 12, php-plain/admin.php lines 5-13. The DELETE query uses the raw $_POST['id'] value. No cast, parameter binding, or ownership check is present. The included auth.php only verifies login, not admin role.
878
+
879
+ ### INJ-I-0029-2 — NoSQL Injection in php-plain/mongo_find.php:6
880
+
881
+ - **Severity / confidence:** critical / high
882
+ - **Status:** confirmed
883
+ - **Category:** nosql_injection (operator_injection) — CWE-89
884
+ - **Endpoint:** - -
885
+ - **Location:** `php-plain/mongo_find.php:5`
886
+
887
+ **Evidence.**
888
+
889
+ - `php-plain/mongo_find.php:6` — Unescaped string used in $where expression
890
+ `$docs = $coll->find(array('$where' => "this.name == '" . $_GET['n'] . "'"));`
891
+
892
+ **Recommendation.** Avoid $where; use parameterized queries or safe operators
893
+
894
+ *Verifier:* confirmed — checked: php-plain/mongo_find.php line 6, php-plain/mongo_find.php lines 1-6. The $where expression concatenates the unsanitized $_GET['n'] value. No sanitization or ownership check is visible.
895
+
896
+ ### INJ-I-0030 — NoSQL Injection in php-plain/mongo_find.php:6
897
+
898
+ - **Severity / confidence:** critical / high
899
+ - **Status:** confirmed
900
+ - **Category:** nosql_injection (operator_injection) — CWE-89
901
+ - **Endpoint:** - -
902
+ - **Location:** `php-plain/mongo_find.php:6`
903
+
904
+ **Evidence.**
905
+
906
+ - `php-plain/mongo_find.php:6` — Unescaped string used in $where expression
907
+ `$docs = $coll->find(array('$where' => "this.name == '" . $_GET['n'] . "'"));`
908
+
909
+ **Recommendation.** Avoid $where; use parameterized queries or safe operators
910
+
911
+ *Verifier:* confirmed — checked: php-plain/mongo_find.php, php-plain/inc/auth.php. The query concatenates user input into a $where expression with no sanitisation or ownership check. The included auth file only verifies login, not object ownership.
912
+
913
+ ### INJ-I-0031-1 — SQL Injection in php-plain/order_detail.php:6
914
+
915
+ - **Severity / confidence:** critical / high
916
+ - **Status:** confirmed
917
+ - **Category:** sql_injection (string_concatenation) — CWE-89
918
+ - **Endpoint:** - -
919
+ - **Location:** `php-plain/order_detail.php:6`
920
+
921
+ **Evidence.**
922
+
923
+ - `php-plain/order_detail.php:5` — source: GET parameter
924
+ `$id = $_GET['id'];`
925
+ - `php-plain/order_detail.php:6` — unsanitized input concatenated into query
926
+ `$res = mysql_query("SELECT * FROM orders WHERE id = " . $id);`
927
+
928
+ **Recommendation.** Use parameterized queries
929
+
930
+ *Verifier:* confirmed — checked: php-plain/order_detail.php, php-plain/inc/auth.php. The SQL statement concatenates the GET id directly. No ownership or role guard is present in the visible code.
931
+
932
+ ### INJ-I-0032-1 — SQL Injection in php-plain/search.php:7
933
+
934
+ - **Severity / confidence:** critical / high
935
+ - **Status:** confirmed
936
+ - **Category:** sql_injection (string_concatenation) — CWE-89
937
+ - **Endpoint:** - -
938
+ - **Location:** `php-plain/search.php:8`
939
+
940
+ **Evidence.**
941
+
942
+ - `php-plain/search.php:5` — source: GET parameter
943
+ `$kw = addslashes($_GET['q']);`
944
+ - `php-plain/search.php:6` — source: GET parameter
945
+ `$sort = $_GET['sort'];`
946
+ - `php-plain/search.php:7` — query start
947
+ `$sql = "SELECT id, name FROM products WHERE 1=1";`
948
+ - `php-plain/search.php:8` — unsanitized input concatenated
949
+ `$sql .= " AND name LIKE '%" . $kw . "%'";`
950
+ - `php-plain/search.php:9` — unsanitized ORDER BY
951
+ `$sql .= " ORDER BY " . $sort;`
952
+ - `php-plain/search.php:11` — sink
953
+ `$res = mysql_query($sql);`
954
+
955
+ **Recommendation.** Use parameterized queries and allow-list ORDER BY
956
+
957
+ *Verifier:* confirmed — checked: php-plain/search.php, php-plain/inc/auth.php, php-plain/inc/db.php. Both the keyword and ORDER BY values are unsanitised and no allow‑list or ownership check is visible.
958
+
959
+ ### INJ-I-0032-2 — SQL Injection in php-plain/search.php:12
960
+
961
+ - **Severity / confidence:** critical / high
962
+ - **Status:** confirmed
963
+ - **Category:** sql_injection (string_interpolation) — CWE-89
964
+ - **Endpoint:** - -
965
+ - **Location:** `php-plain/search.php:8`
966
+
967
+ **Evidence.**
968
+
969
+ - `php-plain/search.php:14` — unsanitized interpolation
970
+ `WHERE category = '{$_GET['cat']}'`
971
+ - `php-plain/search.php:16` — sink
972
+ `$res2 = mysql_query($q);`
973
+
974
+ **Recommendation.** Use parameterized queries
975
+
976
+ *Verifier:* confirmed — checked: php-plain/search.php, php-plain/inc/auth.php, php-plain/inc/db.php. The interpolated category value is used directly in the query with no sanitisation or ownership guard.
977
+
978
+ ### INJ-I-0036-1 — SQL Injection in python-flask/app.py:29
979
+
980
+ - **Severity / confidence:** critical / high
981
+ - **Status:** confirmed
982
+ - **Category:** sql_injection (string_interpolation) — CWE-89
983
+ - **Endpoint:** - -
984
+ - **Location:** `python-flask/app.py:29`
985
+
986
+ **Evidence.**
987
+
988
+ - `python-flask/app.py:27` — source: query parameter
989
+ `q = request.args.get('q', '')`
990
+ - `python-flask/app.py:29` — unsanitized interpolation
991
+ `cur.execute(f"SELECT * FROM products WHERE name LIKE '%{q}%'")`
992
+
993
+ **Recommendation.** Use parameterized queries
994
+
995
+ *Verifier:* confirmed — checked: python-flask/app.py. The f‑string interpolates the query parameter directly into the SQL. The @login_required decorator only ensures authentication, not ownership or parameter validation.
996
+
997
+ ### INJ-I-0037-1 — SQL Injection in sql-procs/sp_search_orders.sql:5
998
+
999
+ - **Severity / confidence:** critical / high
1000
+ - **Status:** confirmed
1001
+ - **Category:** sql_injection (stored_procedure_dynamic_sql) — CWE-89
1002
+ - **Endpoint:** - -
1003
+ - **Location:** `sql-procs/sp_search_orders.sql:5`
1004
+
1005
+ **Evidence.**
1006
+
1007
+ - `sql-procs/sp_search_orders.sql:5` — unsanitized dynamic SQL
1008
+ `SET @sql = 'SELECT * FROM Orders WHERE Customer = ''' + @Customer + ''' ORDER BY ' + @Sort`
1009
+ - `sql-procs/sp_search_orders.sql:6` — sink
1010
+ `EXEC(@sql)`
1011
+
1012
+ **Recommendation.** Use sp_executesql with parameters
1013
+
1014
+ *Verifier:* confirmed — checked: sql-procs/sp_search_orders.sql:5-6. Dynamic SQL is built by concatenating @Customer and @Sort directly into the statement. No allow‑list, integer cast, or parameterized execution is visible.
1015
+
1016
+ ### MASS-M-0003-1 — Unrestricted role binding in Spring MVC
1017
+
1018
+ - **Severity / confidence:** critical / medium
1019
+ - **Status:** likely
1020
+ - **Category:** mass_assignment (privileged_field_writable) — CWE-915
1021
+ - **Endpoint:** - -
1022
+ - **Location:** `java-legacy/src/com/acme/web/AccountController.java:14`
1023
+
1024
+ **Impact.** Any authenticated user can set the role field of an Account
1025
+
1026
+ **Evidence.**
1027
+
1028
+ - `java-legacy/src/com/acme/web/AccountController.java:14` — Location taken from the Tier 1 inventory
1029
+
1030
+ **Recommendation.** Bind only allowed fields or set role server‑side
1031
+
1032
+ *Verifier:* likely — checked: java-legacy/src/com/acme/web/AccountController.java. The controller accepts a full Account model via @ModelAttribute and persists it without any field‑level binding or role restrictions shown.
1033
+
1034
+ ### MASS-M-0004-1 — Unrestricted role binding in Spring MVC (duplicate)
1035
+
1036
+ - **Severity / confidence:** critical / medium
1037
+ - **Status:** likely
1038
+ - **Category:** mass_assignment (privileged_field_writable) — CWE-915
1039
+ - **Endpoint:** - -
1040
+ - **Location:** `java-legacy/src/com/acme/web/AccountController.java:27`
1041
+
1042
+ **Impact.** Any authenticated user can set the role field of an Account
1043
+
1044
+ **Evidence.**
1045
+
1046
+ - `java-legacy/src/com/acme/web/AccountController.java:27` — Location taken from the Tier 1 inventory
1047
+
1048
+ **Recommendation.** Bind only allowed fields or set role server‑side
1049
+
1050
+ *Verifier:* likely — checked: AccountController.update method (lines 13-28), AccountDao.save invocation. No ownership or role check, no allow‑list, and no type cast is visible in the provided code context.
1051
+
1052
+ ### MASS-M-0005-1 — Unrestricted role binding via BeanUtils in Java Servlet
1053
+
1054
+ - **Severity / confidence:** critical / medium
1055
+ - **Status:** likely
1056
+ - **Category:** mass_assignment (privileged_field_writable) — CWE-915
1057
+ - **Endpoint:** - -
1058
+ - **Location:** `java-legacy/src/com/acme/web/ProfileServlet.java:12`
1059
+
1060
+ **Impact.** Any authenticated user can set the role field of an Account
1061
+
1062
+ **Evidence.**
1063
+
1064
+ - `java-legacy/src/com/acme/web/ProfileServlet.java:12` — BeanUtils.populate binds all request parameters including role
1065
+ - `java-legacy/src/com/acme/web/ProfileServlet.java:10` — no field filtering or role check
1066
+
1067
+ **Recommendation.** Bind only allowed fields or set role server‑side
1068
+
1069
+ *Verifier:* likely — checked: ProfileServlet.doPost method (lines 9-16), BeanUtils.populate usage. The code shows direct population of all request parameters into the Account object with no filtering or role enforcement.
1070
+
1071
+ ### BOLA-R-0001 — BOLA in ANY /user/edit.do: missing owner verification
1072
+
1073
+ - **Severity / confidence:** high / high
1074
+ - **Status:** confirmed
1075
+ - **Category:** bola (missing_ownership_check) — CWE-284, CWE-639
1076
+ - **Endpoint:** ANY /user/edit.do
1077
+ - **Location:** `java-legacy/src/com/acme/struts/EditUserAction.java:10`
1078
+
1079
+ **Evidence.**
1080
+
1081
+ - `java-legacy/src/com/acme/struts/EditUserAction.java:10` — ID from request
1082
+ `String userId = request.getParameter("user_id");`
1083
+ - `java-legacy/src/com/acme/struts/EditUserAction.java:13` — Query does not bind to user_id
1084
+ `PreparedStatement ps = conn.prepareStatement("UPDATE users SET email = '" + email + "' WHERE id = " + userId);`
1085
+
1086
+ **Recommendation.** Verify user ownership before update
1087
+
1088
+ *Verifier:* confirmed — checked: java-legacy/src/com/acme/struts/EditUserAction.java. The UPDATE statement uses the user_id from the request without any ownership verification or parameter binding.
1089
+
1090
+ ### BOLA-R-0002 — BOLA in ANY /classic-asp/shop/member.asp?mode=edit: missing owner verification
1091
+
1092
+ - **Severity / confidence:** high / high
1093
+ - **Status:** confirmed
1094
+ - **Category:** bola (missing_ownership_check) — CWE-284, CWE-639
1095
+ - **Endpoint:** ANY /classic-asp/shop/member.asp?mode=edit
1096
+ - **Location:** `classic-asp/shop/member.asp:6`
1097
+
1098
+ **Evidence.**
1099
+
1100
+ - `classic-asp/shop/member.asp:6` — ID from request, no ownership check
1101
+ `sql = "UPDATE members SET name = '" & Replace(Request.Form("name"), "'", "''") & "'"`
1102
+ - `classic-asp/shop/member.asp:7` — ID from request, no ownership check
1103
+ `sql = sql & " WHERE member_id = " & Request.Form("member_id")`
1104
+ - `classic-asp/shop/member.asp:8` — Executes query without owner check
1105
+ `conn.Execute sql`
1106
+
1107
+ **Recommendation.** Bind query to current session user
1108
+
1109
+ *Verifier:* confirmed — checked: classic-asp/shop/member.asp lines 6-8, classic-asp/shop/inc/auth.asp line 2. The code updates a member record using the member_id from the request without any ownership verification. The only visible check is authentication in inc/auth.asp, which does not enforce ownership.
1110
+
1111
+ ### BOLA-R-0003 — BOLA in ANY /classic-asp/shop/member.asp?mode=delete: missing owner verification
1112
+
1113
+ - **Severity / confidence:** high / high
1114
+ - **Status:** confirmed
1115
+ - **Category:** bola (missing_ownership_check) — CWE-284, CWE-639
1116
+ - **Endpoint:** ANY /classic-asp/shop/member.asp?mode=delete
1117
+ - **Location:** `classic-asp/shop/member.asp:9`
1118
+
1119
+ **Evidence.**
1120
+
1121
+ - `classic-asp/shop/member.asp:9` — ID from request, no ownership check
1122
+ `conn.Execute "DELETE FROM members WHERE member_id = " & Request.QueryString("member_id")`
1123
+
1124
+ **Recommendation.** Bind delete to current session user
1125
+
1126
+ *Verifier:* confirmed — checked: classic-asp/shop/member.asp line 9, classic-asp/shop/inc/auth.asp line 2. The delete statement uses the member_id from the query string directly. No ownership check is present in the visible code.
1127
+
1128
+ ### BOLA-R-0004 — BOLA in ANY /classic-asp/shop/order.asp: missing owner verification on first query
1129
+
1130
+ - **Severity / confidence:** high / high
1131
+ - **Status:** confirmed
1132
+ - **Category:** bola (missing_ownership_check) — CWE-284, CWE-639
1133
+ - **Endpoint:** ANY /classic-asp/shop/order.asp
1134
+ - **Location:** `classic-asp/shop/order.asp:5`
1135
+
1136
+ **Evidence.**
1137
+
1138
+ - `classic-asp/shop/order.asp:5` — ID from request, no ownership check
1139
+ `id = Request("id")`
1140
+ - `classic-asp/shop/order.asp:6` — Query does not bind to user_id
1141
+ `Set rs = conn.Execute("SELECT * FROM orders WHERE id = " & id)`
1142
+
1143
+ **Recommendation.** Bind order query to current session user
1144
+
1145
+ *Verifier:* confirmed — checked: classic-asp/shop/order.asp lines 5-6, classic-asp/shop/inc/auth.asp line 2. The first query selects an order by id from the request without binding to the current user. The later query includes a user_id check, but the initial query remains vulnerable.
1146
+
1147
+ ### BOLA-R-0005 — BOLA in ANY /coldfusion/app/OrderService.cfc?method=getOrder: missing owner verification
1148
+
1149
+ - **Severity / confidence:** high / high
1150
+ - **Status:** confirmed
1151
+ - **Category:** bola (missing_ownership_check) — CWE-284, CWE-639
1152
+ - **Endpoint:** ANY /coldfusion/app/OrderService.cfc?method=getOrder
1153
+ - **Location:** `coldfusion/app/OrderService.cfc:4`
1154
+
1155
+ **Evidence.**
1156
+
1157
+ - `coldfusion/app/OrderService.cfc:4` — Query starts here
1158
+ `<cfquery name="q" datasource="shop">`
1159
+ - `coldfusion/app/OrderService.cfc:5` — ID from request, no ownership check
1160
+ `SELECT * FROM orders WHERE id = #arguments.orderId#`
1161
+
1162
+ **Recommendation.** Bind order query to current session user
1163
+
1164
+ *Verifier:* confirmed — checked: coldfusion/app/OrderService.cfc lines 4-5. The cfquery directly interpolates the orderId argument into the SQL without any ownership verification or parameter binding.
1165
+
1166
+ ### BOLA-R-0006 — BOLA in ANY /coldfusion/app/order.cfm: missing owner verification on first query
1167
+
1168
+ - **Severity / confidence:** high / high
1169
+ - **Status:** confirmed
1170
+ - **Category:** bola (missing_ownership_check) — CWE-284, CWE-639
1171
+ - **Endpoint:** ANY /coldfusion/app/order.cfm
1172
+ - **Location:** `coldfusion/app/order.cfm:2`
1173
+
1174
+ **Evidence.**
1175
+
1176
+ - `coldfusion/app/order.cfm:2` — Query starts here
1177
+ `<cfquery name="qOrder" datasource="shop">`
1178
+ - `coldfusion/app/order.cfm:3` — ID from request, no ownership check
1179
+ `SELECT * FROM orders WHERE id = #url.id#`
1180
+
1181
+ **Recommendation.** Bind order query to current session user
1182
+
1183
+ *Verifier:* confirmed — checked: coldfusion/app/order.cfm lines 2-3, coldfusion/app/order.cfm lines 5-8. The first query qOrder selects an order by id from the URL without checking the current user. The subsequent qMine query includes a user_id check, but the initial query is still exposed.
1184
+
1185
+ ### BOLA-R-0007 — BOLA in POST /Admin/DeleteUser: missing owner verification
1186
+
1187
+ - **Severity / confidence:** high / high
1188
+ - **Status:** confirmed
1189
+ - **Category:** bola (missing_ownership_check) — CWE-284, CWE-639
1190
+ - **Endpoint:** POST /Admin/DeleteUser
1191
+ - **Location:** `dotnet-legacy/Web/Controllers/AdminController.cs:12`
1192
+
1193
+ **Evidence.**
1194
+
1195
+ - `dotnet-legacy/Web/Controllers/AdminController.cs:11` — Method signature
1196
+ `public ActionResult DeleteUser(int id)`
1197
+ - `dotnet-legacy/Web/Controllers/AdminController.cs:12` — Finds user by id from request
1198
+ `var u = db.Users.Find(id);`
1199
+ - `dotnet-legacy/Web/Controllers/AdminController.cs:13` — Deletes user without ownership check
1200
+ `db.Users.Remove(u);`
1201
+
1202
+ **Recommendation.** Restrict to admin role and verify ownership
1203
+
1204
+ *Verifier:* confirmed — checked: dotnet-legacy/Web/Controllers/AdminController.cs lines 6-13. The DeleteUser action lacks any ownership or role check; the controller is only marked with [Authorize], allowing any authenticated user to delete any user.
1205
+
1206
+ ### BOLA-R-0009 — BOLA in POST /Admin/Export: missing role check allows data exposure
1207
+
1208
+ - **Severity / confidence:** high / high
1209
+ - **Status:** confirmed
1210
+ - **Category:** bola (missing_role_check) — CWE-284, CWE-285
1211
+ - **Endpoint:** POST /Admin/Export
1212
+ - **Location:** `dotnet-legacy/Web/Controllers/AdminController.cs:30`
1213
+
1214
+ **Evidence.**
1215
+
1216
+ - `dotnet-legacy/Web/Controllers/AdminController.cs:30` — Method signature
1217
+ `public ActionResult Export()`
1218
+ - `dotnet-legacy/Web/Controllers/AdminController.cs:32` — Checks query string, not role
1219
+ `if (Request.QueryString["isAdmin"] == "true")`
1220
+ - `dotnet-legacy/Web/Controllers/AdminController.cs:33` — Returns all users
1221
+ `return Json(db.Users.ToList(), JsonRequestBehavior.AllowGet);`
1222
+
1223
+ **Recommendation.** Add role-based authorization
1224
+
1225
+ *Verifier:* confirmed — checked: dotnet-legacy/Web/Controllers/AdminController.cs lines 30-35. Export is protected only by class-level [Authorize] and a query‑string flag; no role or ownership verification is performed.
1226
+
1227
+ ### BOLA-R-0010 — BOLA in POST /Customer/Edit: missing owner verification
1228
+
1229
+ - **Severity / confidence:** high / medium
1230
+ - **Status:** likely
1231
+ - **Category:** bola (missing_ownership_check) — CWE-284, CWE-639
1232
+ - **Endpoint:** POST /Customer/Edit
1233
+ - **Location:** `dotnet-legacy/Web/Controllers/CustomerController.cs:12`
1234
+
1235
+ **Evidence.**
1236
+
1237
+ - `dotnet-legacy/Web/Controllers/CustomerController.cs:14` — Marks the supplied customer entity as modified without checking that the current user owns it
1238
+ `db.Entry(customer).State = System.Data.Entity.EntityState.Modified;`
1239
+ - `dotnet-legacy/Web/Controllers/CustomerController.cs:15` — Persists the changes, allowing any authenticated user to modify any customer record
1240
+ `db.SaveChanges();`
1241
+
1242
+ **Recommendation.** Load the customer by ID and verify ownership before applying changes
1243
+
1244
+ *Verifier:* likely — checked: dotnet-legacy/Web/Controllers/CustomerController.cs lines 11-15. The Edit action marks the supplied Customer entity as Modified and saves it without checking ownership. The controller is decorated with [Authorize], which only ensures authentication, not ownership.
1245
+
1246
+ ### BOLA-R-0011 — BOLA in POST /Customer/EditName: missing owner verification
1247
+
1248
+ - **Severity / confidence:** high / medium
1249
+ - **Status:** likely
1250
+ - **Category:** bola (missing_ownership_check) — CWE-284, CWE-639
1251
+ - **Endpoint:** POST /Customer/EditName
1252
+ - **Location:** `dotnet-legacy/Web/Controllers/CustomerController.cs:20`
1253
+
1254
+ **Evidence.**
1255
+
1256
+ - `dotnet-legacy/Web/Controllers/CustomerController.cs:22` — Saves changes to the customer entity without verifying that the current user owns it
1257
+ `db.SaveChanges();`
1258
+
1259
+ **Recommendation.** Verify ownership before saving changes
1260
+
1261
+ *Verifier:* likely — checked: dotnet-legacy/Web/Controllers/CustomerController.cs lines 20-23. EditName receives a Customer with only Id and Name bound, then calls SaveChanges without verifying that the current user owns the customer.
1262
+
1263
+ ### BOLA-R-0012 — BOLA in POST /Customer/Refresh: missing owner verification
1264
+
1265
+ - **Severity / confidence:** high / medium
1266
+ - **Status:** likely
1267
+ - **Category:** bola (missing_ownership_check) — CWE-284, CWE-639
1268
+ - **Endpoint:** POST /Customer/Refresh
1269
+ - **Location:** `dotnet-legacy/Web/Controllers/CustomerController.cs:27`
1270
+
1271
+ **Evidence.**
1272
+
1273
+ - `dotnet-legacy/Web/Controllers/CustomerController.cs:29` — Loads customer by ID supplied in the request without checking ownership
1274
+ `var customer = db.Customers.Find(id);`
1275
+ - `dotnet-legacy/Web/Controllers/CustomerController.cs:30` — Updates the customer entity without verifying that the current user owns it
1276
+ `TryUpdateModel(customer);`
1277
+ - `dotnet-legacy/Web/Controllers/CustomerController.cs:31` — Persists the changes, allowing any authenticated user to modify any customer record
1278
+ `db.SaveChanges();`
1279
+
1280
+ **Recommendation.** Load the customer and verify ownership before updating
1281
+
1282
+ *Verifier:* likely — checked: dotnet-legacy/Web/Controllers/CustomerController.cs lines 27-32. Refresh loads a Customer by id and applies TryUpdateModel before saving, with no ownership check. The [Authorize] attribute only guarantees authentication.
1283
+
1284
+ ### BOLA-R-0013 — BOLA in GET /Invoice/Details: missing owner verification
1285
+
1286
+ - **Severity / confidence:** high / high
1287
+ - **Status:** confirmed
1288
+ - **Category:** bola (missing_ownership_check) — CWE-284, CWE-639
1289
+ - **Endpoint:** ANY /Invoice/Details
1290
+ - **Location:** `dotnet-legacy/Web/Controllers/InvoiceController.cs:11`
1291
+
1292
+ **Evidence.**
1293
+
1294
+ - `dotnet-legacy/Web/Controllers/InvoiceController.cs:11` — Method signature
1295
+ `public ActionResult Details(int id)`
1296
+ - `dotnet-legacy/Web/Controllers/InvoiceController.cs:13` — Finds invoice by id from request
1297
+ `var inv = db.Invoices.Find(id);`
1298
+ - `dotnet-legacy/Web/Controllers/InvoiceController.cs:14` — Returns invoice without ownership check
1299
+ `return View(inv);`
1300
+
1301
+ **Recommendation.** Verify invoice ownership
1302
+
1303
+ *Verifier:* confirmed — checked: dotnet-legacy/Web/Controllers/InvoiceController.cs lines 6-14. Details retrieves an invoice by id without checking that the invoice belongs to the current user.
1304
+
1305
+ ### BOLA-R-0015 — BOLA in POST /Invoice/Search: missing owner verification
1306
+
1307
+ - **Severity / confidence:** high / high
1308
+ - **Status:** confirmed
1309
+ - **Category:** bola (missing_ownership_check) — CWE-284, CWE-639
1310
+ - **Endpoint:** POST /Invoice/Search
1311
+ - **Location:** `dotnet-legacy/Web/Controllers/InvoiceController.cs:26`
1312
+
1313
+ **Evidence.**
1314
+
1315
+ - `dotnet-legacy/Web/Controllers/InvoiceController.cs:26` — Method signature
1316
+ `public ActionResult Search(string customer)`
1317
+ - `dotnet-legacy/Web/Controllers/InvoiceController.cs:28` — Raw query uses customer from request, no ownership check
1318
+ `var list = db.Database.SqlQuery<Invoice>("SELECT * FROM Invoices WHERE Customer = '" + customer + "'").ToList();`
1319
+
1320
+ **Recommendation.** Add ownership filter to query
1321
+
1322
+ *Verifier:* confirmed — checked: dotnet-legacy/Web/Controllers/InvoiceController.cs lines 25-29. Search builds a raw SQL query from user input and returns all matching invoices, with no ownership filter.
1323
+
1324
+ ### BOLA-R-0016 — BOLA in ANY /dotnet-legacy/Web/Handlers/GetFile.ashx: missing owner verification
1325
+
1326
+ - **Severity / confidence:** high / high
1327
+ - **Status:** confirmed
1328
+ - **Category:** bola (missing_ownership_check) — CWE-284, CWE-639
1329
+ - **Endpoint:** ANY /dotnet-legacy/Web/Handlers/GetFile.ashx
1330
+ - **Location:** `dotnet-legacy/Web/Handlers/GetFile.ashx:8`
1331
+
1332
+ **Evidence.**
1333
+
1334
+ - `dotnet-legacy/Web/Handlers/GetFile.ashx:8` — Takes file identifier directly from the request
1335
+ `string fileId = context.Request.QueryString["file_id"];`
1336
+ - `dotnet-legacy/Web/Handlers/GetFile.ashx:9` — Builds file path without checking that the current user owns the file
1337
+ `string path = DocStore.PathFor(fileId);`
1338
+ - `dotnet-legacy/Web/Handlers/GetFile.ashx:10` — Serves the file to the requester, enabling download of any file
1339
+ `context.Response.TransmitFile(path);`
1340
+
1341
+ **Recommendation.** Verify that the current user owns the requested file before transmitting
1342
+
1343
+ *Verifier:* confirmed — checked: dotnet-legacy/Web/Handlers/GetFile.ashx:8-10. The handler reads the file identifier directly from the query string, builds a path without any ownership verification, and transmits the file. No ownership or tenant check is present in the visible code.
1344
+
1345
+ ### BOLA-R-0017 — BOLA in ANY /dotnet-legacy/Web/Orders/EditOrder.aspx.vb: missing owner verification
1346
+
1347
+ - **Severity / confidence:** high / high
1348
+ - **Status:** confirmed
1349
+ - **Category:** bola (missing_ownership_check) — CWE-284, CWE-639
1350
+ - **Endpoint:** ANY /dotnet-legacy/Web/Orders/EditOrder.aspx
1351
+ - **Location:** `dotnet-legacy/Web/Orders/EditOrder.aspx.vb:7`
1352
+
1353
+ **Evidence.**
1354
+
1355
+ - `dotnet-legacy/Web/Orders/EditOrder.aspx.vb:7` — SQL built from request data
1356
+ `Dim sql As String = "UPDATE Orders SET Note = '" & txtNote.Text & "'"`
1357
+ - `dotnet-legacy/Web/Orders/EditOrder.aspx.vb:8` — OrderId from hidden field, no ownership check
1358
+ `sql &= " WHERE OrderId = " & hfOrderId.Value`
1359
+
1360
+ **Recommendation.** Verify order ownership before update
1361
+
1362
+ *Verifier:* confirmed — checked: dotnet-legacy/Web/Orders/EditOrder.aspx.vb lines 6-13. The update statement uses the OrderId from a hidden field without verifying that the current user owns the order.
1363
+
1364
+ ### BOLA-R-0018 — BOLA in ANY /dotnet-legacy/Web/Orders/OrderDetail.aspx.cs: missing owner verification
1365
+
1366
+ - **Severity / confidence:** high / high
1367
+ - **Status:** confirmed
1368
+ - **Category:** bola (missing_ownership_check) — CWE-284, CWE-639
1369
+ - **Endpoint:** ANY /dotnet-legacy/Web/Orders/OrderDetail.aspx
1370
+ - **Location:** `dotnet-legacy/Web/Orders/OrderDetail.aspx.cs:10`
1371
+
1372
+ **Evidence.**
1373
+
1374
+ - `dotnet-legacy/Web/Orders/OrderDetail.aspx.cs:10` — ID from request
1375
+ `string id = Request.QueryString["id"];`
1376
+ - `dotnet-legacy/Web/Orders/OrderDetail.aspx.cs:13` — Query does not bind to user_id
1377
+ `var cmd = new SqlCommand("SELECT * FROM Orders WHERE OrderId = " + id, conn);`
1378
+
1379
+ **Recommendation.** Bind order query to current session user
1380
+
1381
+ *Verifier:* confirmed — checked: dotnet-legacy/Web/Orders/OrderDetail.aspx.cs. The unsafe query at line 13 is executed before any ownership check or parameter binding. No role or ownership guard is visible in the provided code.
1382
+
1383
+ ### BOLA-R-0019 — BOLA in ANY /java-legacy/WebContent/order/detail.jsp: missing owner verification
1384
+
1385
+ - **Severity / confidence:** high / high
1386
+ - **Status:** confirmed
1387
+ - **Category:** bola (missing_ownership_check) — CWE-284, CWE-639
1388
+ - **Endpoint:** ANY /java-legacy/WebContent/order/detail.jsp
1389
+ - **Location:** `java-legacy/WebContent/order/detail.jsp:3`
1390
+
1391
+ **Evidence.**
1392
+
1393
+ - `java-legacy/WebContent/order/detail.jsp:3` — ID from request
1394
+ `String no = request.getParameter("no");`
1395
+ - `java-legacy/WebContent/order/detail.jsp:5` — Query does not bind to user_id
1396
+ `ResultSet rs = c.createStatement().executeQuery("SELECT * FROM orders WHERE order_no = '" + no + "'");`
1397
+
1398
+ **Recommendation.** Bind order query to current session user
1399
+
1400
+ *Verifier:* confirmed — checked: java-legacy/WebContent/order/detail.jsp. The query concatenates the request parameter directly into the SQL string with no ownership check or parameter binding.
1401
+
1402
+ ### BOLA-R-0020 — BOLA in POST /account/save: missing owner verification
1403
+
1404
+ - **Severity / confidence:** high / high
1405
+ - **Status:** confirmed
1406
+ - **Category:** bola (missing_ownership_check) — CWE-284, CWE-639
1407
+ - **Endpoint:** POST /account/save
1408
+ - **Location:** `java-legacy/src/com/acme/web/AccountController.java:14`
1409
+
1410
+ **Evidence.**
1411
+
1412
+ - `java-legacy/src/com/acme/web/AccountController.java:14` — Account object is bound directly from the request; attacker can set any id
1413
+ `public String save(@ModelAttribute Account account) {`
1414
+ - `java-legacy/src/com/acme/web/AccountController.java:15` — No check that the account belongs to the current user
1415
+ ` accountDao.save(account);`
1416
+
1417
+ **Recommendation.** Bind the save operation to the authenticated user
1418
+
1419
+ *Verifier:* confirmed — checked: java-legacy/src/com/acme/web/AccountController.java. The Account object is bound directly from the request and passed to the DAO without any ownership check.
1420
+
1421
+ ### BOLA-R-0021 — BOLA in POST /account/rename: missing owner verification
1422
+
1423
+ - **Severity / confidence:** high / high
1424
+ - **Status:** confirmed
1425
+ - **Category:** bola (missing_ownership_check) — CWE-284, CWE-639
1426
+ - **Endpoint:** POST /account/rename
1427
+ - **Location:** `java-legacy/src/com/acme/web/AccountController.java:20`
1428
+
1429
+ **Evidence.**
1430
+
1431
+ - `java-legacy/src/com/acme/web/AccountController.java:20` — Form contains an id that can be set by the attacker
1432
+ `public String rename(@ModelAttribute RenameForm form) {`
1433
+ - `java-legacy/src/com/acme/web/AccountController.java:21` — No check that the id belongs to the current user
1434
+ ` accountDao.rename(form.getId(), form.getName());`
1435
+
1436
+ **Recommendation.** Verify ownership before renaming
1437
+
1438
+ *Verifier:* confirmed — checked: java-legacy/src/com/acme/web/AccountController.java. The RenameForm contains an id that is used directly in the DAO call with no ownership verification.
1439
+
1440
+ ### BOLA-R-0022 — BOLA in PUT /account/api: missing owner verification
1441
+
1442
+ - **Severity / confidence:** high / medium
1443
+ - **Status:** likely
1444
+ - **Category:** bola (missing_ownership_check) — CWE-284, CWE-639
1445
+ - **Endpoint:** PUT /account/api
1446
+ - **Location:** `java-legacy/src/com/acme/web/AccountController.java:27`
1447
+
1448
+ **Evidence.**
1449
+
1450
+ - `java-legacy/src/com/acme/web/AccountController.java:27` — Account object is deserialized from the request; attacker can set any id
1451
+ `public Account update(@RequestBody Account account) {`
1452
+ - `java-legacy/src/com/acme/web/AccountController.java:28` — No ownership check before saving
1453
+ ` return accountDao.save(account);`
1454
+
1455
+ **Recommendation.** Bind update to the authenticated user
1456
+
1457
+ *Verifier:* likely — checked: java-legacy/src/com/acme/web/AccountController.java:25-28. The update method deserializes an Account object and directly passes it to accountDao.save without any ownership or role check visible in the provided code. No global filter or cast is shown.
1458
+
1459
+ ### BOLA-R-0023 — BOLA in POST /admin/users/{id}/delete: missing owner verification
1460
+
1461
+ - **Severity / confidence:** high / medium
1462
+ - **Status:** likely
1463
+ - **Category:** bola (missing_ownership_check) — CWE-284, CWE-639
1464
+ - **Endpoint:** POST /admin/users/{id}/delete
1465
+ - **Location:** `java-legacy/src/com/acme/web/AdminUserController.java:13`
1466
+
1467
+ **Evidence.**
1468
+
1469
+ - `java-legacy/src/com/acme/web/AdminUserController.java:13` — Endpoint accepts any user id
1470
+ `@RequestMapping(value = "/{id}/delete", method = RequestMethod.POST)`
1471
+ - `java-legacy/src/com/acme/web/AdminUserController.java:15` — No authentication or role check; any logged‑in user can delete any account
1472
+ ` userDao.deleteById(id);`
1473
+
1474
+ **Recommendation.** Require admin role before deleting a user
1475
+
1476
+ *Verifier:* likely — checked: java-legacy/src/com/acme/web/AdminUserController.java:13-15. The delete method accepts any user id and calls userDao.deleteById without a role or ownership guard. The @PreAuthorize annotation is present only on a different method.
1477
+
1478
+ ### BOLA-R-0025 — BOLA in GET /invoices/{id}: missing owner verification
1479
+
1480
+ - **Severity / confidence:** high / medium
1481
+ - **Status:** likely
1482
+ - **Category:** bola (missing_ownership_check) — CWE-284, CWE-639
1483
+ - **Endpoint:** GET /invoices/{id}
1484
+ - **Location:** `java-legacy/src/com/acme/web/InvoiceController.java:15`
1485
+
1486
+ **Evidence.**
1487
+
1488
+ - `java-legacy/src/com/acme/web/InvoiceController.java:15` — Endpoint accepts any invoice id
1489
+ `@RequestMapping(value = "/{id}", method = RequestMethod.GET)`
1490
+ - `java-legacy/src/com/acme/web/InvoiceController.java:17` — No check that the invoice belongs to the current user
1491
+ ` model.addAttribute("invoice", invoiceDao.findById(id));`
1492
+
1493
+ **Recommendation.** Bind invoice lookup to the authenticated user
1494
+
1495
+ *Verifier:* likely — checked: java-legacy/src/com/acme/web/InvoiceController.java:15-17. The show method retrieves an invoice by id without verifying that the invoice belongs to the current user. No ownership check or role guard is visible.
1496
+
1497
+ ### BOLA-R-0027 — BOLA in GET /invoices/search: missing owner verification
1498
+
1499
+ - **Severity / confidence:** high / medium
1500
+ - **Status:** likely
1501
+ - **Category:** bola (missing_ownership_check) — CWE-284, CWE-639
1502
+ - **Endpoint:** GET /invoices/search
1503
+ - **Location:** `java-legacy/src/com/acme/web/InvoiceController.java:27`
1504
+
1505
+ **Evidence.**
1506
+
1507
+ - `java-legacy/src/com/acme/web/InvoiceController.java:27` — Endpoint accepts any customer string
1508
+ `@RequestMapping(value = "/search", method = RequestMethod.GET)`
1509
+ - `java-legacy/src/com/acme/web/InvoiceController.java:29` — Query is built from user input without binding to current user
1510
+ ` model.addAttribute("list", session.createQuery("from Invoice i where i.customer = '" + customer + "'").list());`
1511
+
1512
+ **Recommendation.** Restrict search to invoices owned by the current user
1513
+
1514
+ *Verifier:* likely — checked: java-legacy/src/com/acme/web/InvoiceController.java:27-29. The search method builds a query from a customer string without binding to the current user or applying an allow‑list. No ownership or role check is shown.
1515
+
1516
+ ### BOLA-R-0028 — BOLA in GET /order/view: missing owner verification
1517
+
1518
+ - **Severity / confidence:** high / medium
1519
+ - **Status:** likely
1520
+ - **Category:** bola (missing_ownership_check) — CWE-284, CWE-639
1521
+ - **Endpoint:** GET /order/view
1522
+ - **Location:** `java-legacy/src/com/acme/web/OrderServlet.java:11`
1523
+
1524
+ **Evidence.**
1525
+
1526
+ - `java-legacy/src/com/acme/web/OrderServlet.java:11` — Order id comes directly from the request
1527
+ `String id = request.getParameter("orderId");`
1528
+ - `java-legacy/src/com/acme/web/OrderServlet.java:15` — No check that the order belongs to the current user
1529
+ `ResultSet rs = stmt.executeQuery("SELECT * FROM orders WHERE id = '" + id + "'");`
1530
+
1531
+ **Recommendation.** Bind order lookup to the authenticated user
1532
+
1533
+ *Verifier:* likely — checked: java-legacy/src/com/acme/web/OrderServlet.java:11-15. The servlet retrieves an order by id directly from the request and queries the database without verifying ownership. No role or ownership guard is visible in the provided snippet.
1534
+
1535
+ ### BOLA-R-0029 — BOLA in POST /ProfileServlet: missing owner verification
1536
+
1537
+ - **Severity / confidence:** high / high
1538
+ - **Status:** confirmed
1539
+ - **Category:** bola (missing_ownership_check) — CWE-284, CWE-639
1540
+ - **Endpoint:** POST <see web.xml servlet-mapping>
1541
+ - **Location:** `java-legacy/src/com/acme/web/ProfileServlet.java:9`
1542
+
1543
+ **Evidence.**
1544
+
1545
+ - `java-legacy/src/com/acme/web/ProfileServlet.java:12` — Populates an Account object with all request parameters without checking ownership
1546
+ `BeanUtils.populate(account, request.getParameterMap());`
1547
+ - `java-legacy/src/com/acme/web/ProfileServlet.java:13` — No authentication or ownership check is performed before persisting the account
1548
+ `/* no further processing shown */`
1549
+
1550
+ **Recommendation.** Load the account by ID and verify that the current user owns it before updating
1551
+
1552
+ *Verifier:* confirmed — checked: java-legacy/src/com/acme/web/ProfileServlet.java:12-13. The servlet populates an Account object with all request parameters and does not perform any ownership check before persisting. No compensating control is visible.
1553
+
1554
+ ### BOLA-R-0030 — BOLA in POST /admin/users/:id/delete: missing owner verification
1555
+
1556
+ - **Severity / confidence:** high / high
1557
+ - **Status:** confirmed
1558
+ - **Category:** bola (missing_ownership_check) — CWE-284, CWE-639
1559
+ - **Endpoint:** POST /admin/users/:id/delete
1560
+ - **Location:** `node-express/routes/admin.js:8`
1561
+
1562
+ **Evidence.**
1563
+
1564
+ - `node-express/routes/admin.js:8` — Endpoint accepts any user id
1565
+ `router.post('/admin/users/:id/delete', ensureLoggedIn, function (req, res) {`
1566
+ - `node-express/routes/admin.js:9` — No role check; any logged‑in user can delete any account
1567
+ ` User.deleteOne({ _id: req.params.id }, function () { res.sendStatus(204); });`
1568
+
1569
+ **Recommendation.** Require admin role before deleting a user
1570
+
1571
+ *Verifier:* confirmed — checked: router.post('/admin/users/:id/delete', ensureLoggedIn, function (req, res) {, User.deleteOne({ _id: req.params.id }, function () { res.sendStatus(204); });. No admin role or ownership check is performed before deleting a user.
1572
+
1573
+ ### BOLA-R-0033 — BOLA in GET /orders/:id: missing owner verification
1574
+
1575
+ - **Severity / confidence:** high / high
1576
+ - **Status:** confirmed
1577
+ - **Category:** bola (missing_ownership_check) — CWE-284, CWE-639
1578
+ - **Endpoint:** GET /orders/:id
1579
+ - **Location:** `node-express/routes/orders.js:8`
1580
+
1581
+ **Evidence.**
1582
+
1583
+ - `node-express/routes/orders.js:8` — The order ID comes from the request and the query does not filter by the authenticated user.
1584
+ `router.get('/orders/:id', ensureLoggedIn, function (req, res) { Order.findById(req.params.id, function (err, order) { res.json(order); }); });`
1585
+
1586
+ **Recommendation.** Bind the query to the current session user.
1587
+
1588
+ *Verifier:* confirmed — checked: router.get('/orders/:id', ensureLoggedIn, function (req, res) {, Order.findById(req.params.id, function (err, order) { res.json(order); });. The order is retrieved by ID without filtering by the authenticated user.
1589
+
1590
+ ### BOLA-R-0038 — BOLA in GET /stats: missing owner verification
1591
+
1592
+ - **Severity / confidence:** high / high
1593
+ - **Status:** confirmed
1594
+ - **Category:** bola (missing_ownership_check) — CWE-284, CWE-639
1595
+ - **Endpoint:** GET /stats
1596
+ - **Location:** `node-express/routes/orders.js:28`
1597
+
1598
+ **Evidence.**
1599
+
1600
+ - `node-express/routes/orders.js:28` — The shop_id is taken from the request and the query is not filtered by the authenticated user.
1601
+ `router.get('/stats', function (req, res) { db.query('SELECT COUNT(*) AS n FROM orders WHERE shop_id = ${req.query.shop}', function (e, r) { res.json(r); }); });`
1602
+
1603
+ **Recommendation.** Add authentication guard and filter by the current user’s shop.
1604
+
1605
+ *Verifier:* confirmed — checked: router.get('/stats', function (req, res) {, db.query(`SELECT COUNT(*) AS n FROM orders WHERE shop_id = ${req.query.shop}`, function (e, r) { res.json(r); });. The shop_id is taken directly from the request and no authentication guard is present.
1606
+
1607
+ ### BOLA-R-0043 — BOLA in ANY /perl-cgi/cgi-bin/order.cgi: missing owner verification
1608
+
1609
+ - **Severity / confidence:** high / high
1610
+ - **Status:** confirmed
1611
+ - **Category:** bola (missing_ownership_check) — CWE-284, CWE-639
1612
+ - **Endpoint:** ANY /perl-cgi/cgi-bin/order.cgi
1613
+ - **Location:** `perl-cgi/cgi-bin/order.cgi:13`
1614
+
1615
+ **Evidence.**
1616
+
1617
+ - `perl-cgi/cgi-bin/order.cgi:13` — The order ID comes from the request and the query does not filter by the authenticated user.
1618
+ `my $sth = $dbh->prepare("SELECT * FROM orders WHERE id = $id");`
1619
+
1620
+ **Recommendation.** Use a parameterized query that includes the user_id.
1621
+
1622
+ *Verifier:* confirmed — checked: my $sth = $dbh->prepare("SELECT * FROM orders WHERE id = $id");, $sth->execute();. An insecure query is executed before the safe query that includes user_id.
1623
+
1624
+ ### BOLA-R-0044 — BOLA in ANY /invoice/view/{id}: missing owner verification
1625
+
1626
+ - **Severity / confidence:** high / high
1627
+ - **Status:** confirmed
1628
+ - **Category:** bola (missing_ownership_check) — CWE-284, CWE-639
1629
+ - **Endpoint:** ANY /invoice/view/{id}
1630
+ - **Location:** `php-codeigniter/application/controllers/Invoice.php:10`
1631
+
1632
+ **Evidence.**
1633
+
1634
+ - `php-codeigniter/application/controllers/Invoice.php:10` — The invoice ID comes from the request and the query does not filter by the authenticated user.
1635
+ `$q = $this->db->query("SELECT * FROM invoices WHERE id = $id");`
1636
+
1637
+ **Recommendation.** Add an owner check to the query.
1638
+
1639
+ *Verifier:* confirmed — checked: $q = $this->db->query("SELECT * FROM invoices WHERE id = $id");, $this->load->view('invoice', array('inv' => $q->row()));. The invoice is fetched by ID without filtering by the authenticated user.
1640
+
1641
+ ### BOLA-R-0046 — BOLA in ANY /invoice/update: missing owner verification
1642
+
1643
+ - **Severity / confidence:** high / medium
1644
+ - **Status:** likely
1645
+ - **Category:** bola (missing_ownership_check) — CWE-284, CWE-639
1646
+ - **Endpoint:** ANY /invoice/update
1647
+ - **Location:** `php-codeigniter/application/controllers/Invoice.php:23`
1648
+
1649
+ **Evidence.**
1650
+
1651
+ - `php-codeigniter/application/controllers/Invoice.php:23` — The invoice ID comes from the request and the update does not filter by the authenticated user.
1652
+ `$this->db->query("UPDATE invoices SET note = ? WHERE id = ?", array($note, $id));`
1653
+
1654
+ **Recommendation.** Add an owner check to the update query.
1655
+
1656
+ *Verifier:* likely — checked: php-codeigniter/application/controllers/Invoice.php lines 20-24. No ownership or role check, integer cast, or allow‑list is visible in the update method. The controller does not include any auth guard in the provided context.
1657
+
1658
+ ### BOLA-R-0057-1 — BOLA in GET /php-plain/admin.php?action=view: missing admin authorization
1659
+
1660
+ - **Severity / confidence:** high / medium
1661
+ - **Status:** likely
1662
+ - **Category:** bola (missing_role_check) — CWE-285
1663
+ - **Endpoint:** GET /php-plain/admin.php?action=view
1664
+ - **Location:** `php-plain/admin.php:8`
1665
+
1666
+ **Evidence.**
1667
+
1668
+ - `php-plain/admin.php:8` — No admin check; any logged-in user can view any user record by supplying uid
1669
+ `$r = mysql_query("SELECT * FROM users WHERE id = " . $uid);`
1670
+
1671
+ **Recommendation.** Restrict admin actions to users with admin role
1672
+
1673
+ *Verifier:* likely — checked: php-plain/admin.php lines 5-9, php-plain/inc/auth.php lines 1-7. The included auth file only verifies a logged‑in session; there is no admin role check before the SELECT query.
1674
+
1675
+ ### BOLA-R-0057-2 — BOLA in POST /php-plain/admin.php?action=delete: missing admin authorization
1676
+
1677
+ - **Severity / confidence:** high / medium
1678
+ - **Status:** likely
1679
+ - **Category:** bola (missing_role_check) — CWE-285
1680
+ - **Endpoint:** POST /php-plain/admin.php?action=delete
1681
+ - **Location:** `php-plain/admin.php:6`
1682
+
1683
+ **Evidence.**
1684
+
1685
+ - `php-plain/admin.php:12` — No admin check; any logged-in user can delete any user record by supplying id
1686
+ `mysql_query("DELETE FROM users WHERE id = $id");`
1687
+
1688
+ **Recommendation.** Restrict admin actions to users with admin role
1689
+
1690
+ *Verifier:* likely — checked: php-plain/admin.php lines 10-13, php-plain/inc/auth.php lines 1-7. No admin role check is present before the DELETE statement; the auth file does not enforce role.
1691
+
1692
+ ### BOLA-R-0058-1 — BOLA in GET /php-plain/admin.php?action=view: missing admin authorization
1693
+
1694
+ - **Severity / confidence:** high / medium
1695
+ - **Status:** likely
1696
+ - **Category:** bola (missing_role_check) — CWE-285
1697
+ - **Endpoint:** GET /php-plain/admin.php?action=view
1698
+ - **Location:** `php-plain/admin.php:10`
1699
+
1700
+ **Evidence.**
1701
+
1702
+ - `php-plain/admin.php:8` — No admin check; any logged-in user can view any user record by supplying uid
1703
+ `$r = mysql_query("SELECT * FROM users WHERE id = " . $uid);`
1704
+
1705
+ **Recommendation.** Restrict admin actions to users with admin role
1706
+
1707
+ *Verifier:* likely — checked: php-plain/admin.php lines 5-9, php-plain/inc/auth.php lines 1-7. Same as BOLA-R-0057-1: only a login check is performed, no admin guard before the SELECT.
1708
+
1709
+ ### BOLA-R-0058-2 — BOLA in POST /php-plain/admin.php?action=delete: missing admin authorization
1710
+
1711
+ - **Severity / confidence:** high / medium
1712
+ - **Status:** likely
1713
+ - **Category:** bola (missing_role_check) — CWE-285
1714
+ - **Endpoint:** POST /php-plain/admin.php?action=delete
1715
+ - **Location:** `php-plain/admin.php:12`
1716
+
1717
+ **Evidence.**
1718
+
1719
+ - `php-plain/admin.php:12` — No admin check; any logged-in user can delete any user record by supplying id
1720
+ `mysql_query("DELETE FROM users WHERE id = $id");`
1721
+
1722
+ **Recommendation.** Restrict admin actions to users with admin role
1723
+
1724
+ *Verifier:* likely — checked: php-plain/admin.php lines 10-13, php-plain/inc/auth.php lines 1-7. Same as BOLA-R-0057-2: no admin role check before the DELETE.
1725
+
1726
+ ### BOLA-R-0059-1 — BOLA in POST /php-plain/manage_users.php: missing admin authorization
1727
+
1728
+ - **Severity / confidence:** high / high
1729
+ - **Status:** confirmed
1730
+ - **Category:** bola (missing_role_check) — CWE-285
1731
+ - **Endpoint:** POST /php-plain/manage_users.php
1732
+ - **Location:** `php-plain/manage_users.php:6`
1733
+
1734
+ **Evidence.**
1735
+
1736
+ - `php-plain/manage_users.php:6` — No admin check; any logged-in user can delete any user record by supplying id
1737
+ `$stmt = $db->prepare("DELETE FROM users WHERE id = ?");`
1738
+ - `php-plain/manage_users.php:7` — No admin check; any logged-in user can delete any user record by supplying id
1739
+ `$stmt->execute(array((int)$_POST['id']));`
1740
+
1741
+ **Recommendation.** Restrict admin actions to users with admin role
1742
+
1743
+ *Verifier:* confirmed — checked: Checked lines 1-12 of php-plain/manage_users.php. The script performs a delete operation after a POST request but contains only a login check. No admin role check is present; the integer cast on $_POST['id'] is insufficient.
1744
+
1745
+ ### BOLA-R-0061-1 — BOLA in GET /php-plain/order_detail.php: missing ownership verification
1746
+
1747
+ - **Severity / confidence:** high / medium
1748
+ - **Status:** likely
1749
+ - **Category:** bola (missing_ownership_check) — CWE-284, CWE-639
1750
+ - **Endpoint:** GET /php-plain/order_detail.php
1751
+ - **Location:** `php-plain/order_detail.php:6`
1752
+
1753
+ **Evidence.**
1754
+
1755
+ - `php-plain/order_detail.php:6` — No ownership check; any logged-in user can view any order by supplying id
1756
+ `$res = mysql_query("SELECT * FROM orders WHERE id = " . $id);`
1757
+
1758
+ **Recommendation.** Bind query to current session user
1759
+
1760
+ *Verifier:* likely — checked: Checked lines 1-8 of php-plain/order_detail.php. The visible code performs a direct query on the order id without any ownership verification. The auth model indicates a check exists elsewhere, but it is not shown in the provided context.
1761
+
1762
+ ### BOLA-R-0066-1 — BOLA in POST /php-plain/admin/delete_user.php: missing admin authorization
1763
+
1764
+ - **Severity / confidence:** high / high
1765
+ - **Status:** confirmed
1766
+ - **Category:** bola (missing_role_check) — CWE-285
1767
+ - **Endpoint:** POST /php-plain/admin/delete_user.php
1768
+ - **Location:** `php-plain/admin/delete_user.php:6`
1769
+
1770
+ **Evidence.**
1771
+
1772
+ - `php-plain/admin/delete_user.php:6` — No admin check; any logged-in user can delete any user record by supplying id
1773
+ `$stmt = $db->prepare("DELETE FROM users WHERE id = ?");`
1774
+ - `php-plain/admin/delete_user.php:7` — No admin check; any logged-in user can delete any user record by supplying id
1775
+ `$stmt->execute(array($id));`
1776
+
1777
+ **Recommendation.** Restrict admin actions to users with admin role
1778
+
1779
+ *Verifier:* confirmed — checked: Checked lines 1-8 of php-plain/admin/delete_user.php. The file includes only a login check via inc/auth.php; no admin role check is present. The integer cast on $_POST['id'] does not provide authorization.
1780
+
1781
+ ### BOLA-R-0067-1 — BOLA in POST /php-plain/admin/promote.php: missing admin authorization
1782
+
1783
+ - **Severity / confidence:** high / high
1784
+ - **Status:** confirmed
1785
+ - **Category:** bola (missing_role_check) — CWE-285
1786
+ - **Endpoint:** POST /php-plain/admin/promote.php
1787
+ - **Location:** `php-plain/admin/promote.php:6`
1788
+
1789
+ **Evidence.**
1790
+
1791
+ - `php-plain/admin/promote.php:6` — No admin check; any logged-in user can promote any user to admin
1792
+ `$stmt = $db->prepare("UPDATE users SET role = 'admin' WHERE id = ?");`
1793
+ - `php-plain/admin/promote.php:7` — No admin check; any logged-in user can promote any user to admin
1794
+ `$stmt->execute(array((int)$_POST['uid']));`
1795
+
1796
+ **Recommendation.** Restrict admin actions to users with admin role
1797
+
1798
+ *Verifier:* confirmed — checked: Checked lines 1-8 of php-plain/admin/promote.php. Only a login check is performed; there is no admin role verification. The cast to int on $_POST['uid'] does not mitigate the missing authorization.
1799
+
1800
+ ### BOLA-R-0069-1 — BOLA in GET /orders/<int:order_id>: missing ownership verification
1801
+
1802
+ - **Severity / confidence:** high / high
1803
+ - **Status:** confirmed
1804
+ - **Category:** bola (missing_ownership_check) — CWE-284, CWE-639
1805
+ - **Endpoint:** GET /orders/<int:order_id>
1806
+ - **Location:** `python-flask/app.py:12`
1807
+
1808
+ **Evidence.**
1809
+
1810
+ - `python-flask/app.py:12` — No ownership check; any logged-in user can view any order by supplying order_id
1811
+ `cur.execute("SELECT * FROM orders WHERE id = %s" % order_id);`
1812
+
1813
+ **Recommendation.** Bind query to current user
1814
+
1815
+ *Verifier:* confirmed — checked: Checked lines 8-13 of python-flask/app.py. The /orders/<int:order_id> route executes a query based solely on the order id with no user‑ownership filter. Only the login_required decorator is present.
1816
+
1817
+ ### BOLA-R-0073 — BOLA in POST /users/<uid>/name: missing owner verification
1818
+
1819
+ - **Severity / confidence:** high / medium
1820
+ - **Status:** likely
1821
+ - **Category:** bola (missing_ownership_check) — CWE-284, CWE-639
1822
+ - **Endpoint:** POST /users/<int:uid>/name
1823
+ - **Location:** `python-flask/profile.py:16`
1824
+
1825
+ **Evidence.**
1826
+
1827
+ - `python-flask/profile.py:18` — Loads user by ID supplied in the URL without checking ownership
1828
+ `user = User.query.get(uid)`
1829
+ - `python-flask/profile.py:19` — Updates the user record without verifying that the current session user owns it
1830
+ `user.name = request.json["name"]`
1831
+
1832
+ **Recommendation.** Bind the update to the current session user
1833
+
1834
+ *Verifier:* likely — checked: python-flask/profile.py lines 16-20. The rename endpoint loads a User by the supplied uid and updates the name without any ownership or role check. No cast or allow‑list is present in the visible code.
1835
+
1836
+ ### BOLA-R-0074 — BOLA in PATCH /users/<uid>: missing owner verification
1837
+
1838
+ - **Severity / confidence:** high / medium
1839
+ - **Status:** likely
1840
+ - **Category:** bola (missing_ownership_check) — CWE-284, CWE-639
1841
+ - **Endpoint:** PATCH /users/<int:uid>
1842
+ - **Location:** `python-flask/profile.py:24`
1843
+
1844
+ **Evidence.**
1845
+
1846
+ - `python-flask/profile.py:26` — Loads user by ID supplied in the URL without ownership check
1847
+ `user = User.query.get(uid)`
1848
+ - `python-flask/profile.py:27` — Updates arbitrary fields of the user record without verifying ownership
1849
+ `for key, value in request.json.items():
1850
+ setattr(user, key, value)`
1851
+
1852
+ **Recommendation.** Verify that the current session user owns the target user before updating
1853
+
1854
+ *Verifier:* likely — checked: python-flask/profile.py lines 24-29. The patch endpoint retrieves a User by uid and applies arbitrary updates without verifying that the current session user owns the record. No ownership guard is visible.
1855
+
1856
+ ### MASS-M-0009-1 — Team creation allows owner_id to be set by any user
1857
+
1858
+ - **Severity / confidence:** high / medium
1859
+ - **Status:** likely
1860
+ - **Category:** mass_assignment (privileged_field_writable) — CWE-915
1861
+ - **Endpoint:** - -
1862
+ - **Location:** `php-laravel/app/Http/Controllers/AccountController.php:23`
1863
+
1864
+ **Impact.** owner_id field writable by any authenticated user
1865
+
1866
+ **Evidence.**
1867
+
1868
+ - `php-laravel/app/Http/Controllers/AccountController.php:21` — Team::create($request->all()) binds all request fields, including owner_id which is writable
1869
+
1870
+ **Recommendation.** Restrict mass assignment to non-privileged fields or set guarded/fillable to exclude owner_id
1871
+
1872
+ *Verifier:* likely — checked: php-laravel/app/Http/Controllers/AccountController.php lines 21-23. The controller calls Team::create($request->all()) with no visible mass‑assignment guard. The Team model definition (fillable/guarded) is not shown, so a compensating control cannot be confirmed.
1873
+
1874
+ ### MASS-M-0006-1 — Profile update binds entire request body to User model
1875
+
1876
+ - **Severity / confidence:** medium / medium
1877
+ - **Status:** likely
1878
+ - **Category:** mass_assignment (whole_object_binding) — CWE-915
1879
+ - **Endpoint:** - -
1880
+ - **Location:** `node-express/routes/profile.js:8`
1881
+
1882
+ **Impact.** Unknown privileged fields may be writable
1883
+
1884
+ **Evidence.**
1885
+
1886
+ - `node-express/routes/profile.js:8` — Location taken from the Tier 1 inventory
1887
+
1888
+ **Recommendation.** Review model definition to ensure no privileged fields are mass assignable
1889
+
1890
+ *Verifier:* likely — checked: profile.js router.put('/profile') handler (lines 7-9), User.findByIdAndUpdate with req.body. The handler updates the user document with the entire request body without any field filtering or privilege checks.
1891
+
1892
+ ### MASS-M-0007-1 — Profile update binds entire request body to User model
1893
+
1894
+ - **Severity / confidence:** medium / medium
1895
+ - **Status:** likely
1896
+ - **Category:** mass_assignment (whole_object_binding) — CWE-915
1897
+ - **Endpoint:** - -
1898
+ - **Location:** `node-express/routes/profile.js:16`
1899
+
1900
+ **Impact.** Unknown privileged fields may be writable
1901
+
1902
+ **Evidence.**
1903
+
1904
+ - `node-express/routes/profile.js:16` — Location taken from the Tier 1 inventory
1905
+
1906
+ **Recommendation.** Review model definition to ensure no privileged fields are mass assignable
1907
+
1908
+ *Verifier:* likely — checked: profile.js router.post('/signup') handler (lines 15-17), new User(req.body) and user.save(). The signup route creates a new user from the full request body, exposing all fields to the client.
1909
+
1910
+ ### MASS-M-0008-1 — User registration binds entire request body to User model
1911
+
1912
+ - **Severity / confidence:** medium / medium
1913
+ - **Status:** likely
1914
+ - **Category:** mass_assignment (whole_object_binding) — CWE-915
1915
+ - **Endpoint:** - -
1916
+ - **Location:** `php-laravel/app/Http/Controllers/AccountController.php:13`
1917
+
1918
+ **Impact.** Unknown privileged fields may be writable
1919
+
1920
+ **Evidence.**
1921
+
1922
+ - `php-laravel/app/Http/Controllers/AccountController.php:13` — Location taken from the Tier 1 inventory
1923
+
1924
+ **Recommendation.** Review model definition to ensure no privileged fields are mass assignable
1925
+
1926
+ *Verifier:* likely — checked: AccountController.register method (lines 11-14), User::create($request->all()). The register action mass‑assigns all request fields to the User model without any explicit field filtering.
1927
+
1928
+ ### MASS-M-0010-1 — Team creation binds entire request body to Team model
1929
+
1930
+ - **Severity / confidence:** medium / medium
1931
+ - **Status:** likely
1932
+ - **Category:** mass_assignment (whole_object_binding) — CWE-915
1933
+ - **Endpoint:** - -
1934
+ - **Location:** `php-laravel/app/Http/Controllers/AccountController.php:36`
1935
+
1936
+ **Impact.** Unknown privileged fields may be writable
1937
+
1938
+ **Evidence.**
1939
+
1940
+ - `php-laravel/app/Http/Controllers/AccountController.php:36` — Location taken from the Tier 1 inventory
1941
+
1942
+ **Recommendation.** Review model definition to ensure no privileged fields are mass assignable
1943
+
1944
+ *Verifier:* likely — checked: php-laravel/app/Http/Controllers/AccountController.php lines 21-23. Same as finding 1: the entire request body is bound to the Team model with no visible guard. The model’s mass‑assignment configuration is not visible.
1945
+
1946
+ ### MASS-M-0014-1 — User creation binds entire request JSON to User model
1947
+
1948
+ - **Severity / confidence:** medium / medium
1949
+ - **Status:** likely
1950
+ - **Category:** mass_assignment (whole_object_binding) — CWE-915
1951
+ - **Endpoint:** - -
1952
+ - **Location:** `python-flask/profile.py:10`
1953
+
1954
+ **Impact.** Unknown privileged fields may be writable
1955
+
1956
+ **Evidence.**
1957
+
1958
+ - `python-flask/profile.py:10` — Location taken from the Tier 1 inventory
1959
+
1960
+ **Recommendation.** Review model definition to ensure no privileged fields are mass assignable
1961
+
1962
+ *Verifier:* likely — checked: python-flask/profile.py lines 8-12. User creation uses User(**request.json) to bind all fields. No visible guard is present in the shown code, and the model’s mass‑assignment configuration is not visible.
1963
+
1964
+ ### MASS-M-0015-1 — PATCH endpoint sets arbitrary attributes from request JSON
1965
+
1966
+ - **Severity / confidence:** medium / medium
1967
+ - **Status:** likely
1968
+ - **Category:** mass_assignment (whole_object_binding) — CWE-915
1969
+ - **Endpoint:** - -
1970
+ - **Location:** `python-flask/profile.py:27`
1971
+
1972
+ **Impact.** Unknown privileged fields may be writable
1973
+
1974
+ **Evidence.**
1975
+
1976
+ - `python-flask/profile.py:27` — Location taken from the Tier 1 inventory
1977
+
1978
+ **Recommendation.** Review model definition to ensure no privileged fields are mass assignable
1979
+
1980
+ *Verifier:* likely — checked: python-flask/profile.py lines 24-29. The PATCH endpoint iterates over request.json and sets attributes on the User object without any visible guard. The User model’s mass‑assignment restrictions are not shown.
1981
+
1982
+ ## 4. Systemic fixes
1983
+
1984
+ <!-- LLM: reporter agent writes max 5 systemic fixes here -->
1985
+
1986
+ ## 5. Coverage and limitations
1987
+
1988
+ - missing from inventory: 0
1989
+ - bola routes without verdict: 0
1990
+ - injection candidates without verdict: 0
1991
+ - bfla routes without verdict: 0
1992
+ - mass candidates without verdict: 0
1993
+ - findings without verification: 0
1994
+
1995
+ <!-- LLM: reporter agent lists limitations here -->
1996
+
1997
+ ## Appendix A — Findings rejected by the verifier
1998
+
1999
+ | ID | Location | Reason |
2000
+ |---|---|---|
2001
+ | INJ-I-0035-1 | `python-flask/app.py:12` | The Flask route converter `<int:order_id>` guarantees that `order_id` is an integer before it reaches the handler, preventing SQL injection via the string formatting used in the query. |
2002
+ | MASS-M-0013-1 | `php-plain/register.php:4` | The code extracts $_POST but only inserts the email and name columns into the users table. No mass assignment of privileged fields occurs, so the evidence does not support the finding. |
2003
+
2004
+ ## Appendix B — Method
2005
+
2006
+ 1. Deterministic pre-scan (stack detection, endpoint candidates, query-building candidates).
2007
+ 2. AI agents: auth-model extraction, route inventory, BOLA audit, injection audit.
2008
+ 3. Independent AI verifier tries to refute each finding.
2009
+ 4. Human review and sign-off (`review-log.md`).
2010
+
2011
+ This is not a penetration test. Absence of findings does not prove absence of vulnerabilities.