torusguard 1.3.5 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (194) hide show
  1. package/.torusguard/.manifest.json +37 -36
  2. package/.torusguard/runs/report-latest.html +5862 -315
  3. package/.torusguard/runs/results-latest.sarif +20 -0
  4. package/.torusguard/runs/run-20260918-104221-audit/findings.json +1 -0
  5. package/.torusguard/runs/run-20260918-104221-audit/findings.md +8 -0
  6. package/.torusguard/runs/run-20260918-104221-audit/manifest.json +12 -0
  7. package/.torusguard/runs/run-20260918-104221-audit/summary.md +5 -0
  8. package/.torusguard/runs/run-20260918-104236-audit/findings.json +2314 -0
  9. package/.torusguard/runs/run-20260918-104236-audit/findings.md +960 -0
  10. package/.torusguard/runs/run-20260918-104236-audit/manifest.json +12 -0
  11. package/.torusguard/runs/run-20260918-104236-audit/summary.md +5 -0
  12. package/.torusguard/runs/run-20260918-105723-audit/findings.json +2382 -0
  13. package/.torusguard/runs/run-20260918-105723-audit/findings.md +960 -0
  14. package/.torusguard/runs/run-20260918-105723-audit/manifest.json +12 -0
  15. package/.torusguard/runs/run-20260918-105723-audit/summary.md +5 -0
  16. package/.torusguard/runs/run-20260918-105731-audit/findings.json +1 -0
  17. package/.torusguard/runs/run-20260918-105731-audit/findings.md +8 -0
  18. package/.torusguard/runs/run-20260918-105731-audit/manifest.json +12 -0
  19. package/.torusguard/runs/run-20260918-105731-audit/summary.md +5 -0
  20. package/.torusguard/runs/run-20260918-105940-audit/findings.json +1 -0
  21. package/.torusguard/runs/run-20260918-105940-audit/findings.md +8 -0
  22. package/.torusguard/runs/run-20260918-105940-audit/manifest.json +13 -0
  23. package/.torusguard/runs/run-20260918-105940-audit/remediation.md +7 -0
  24. package/.torusguard/runs/run-20260918-105940-audit/summary.md +5 -0
  25. package/.torusguard/runs/run-20260919-145701-audit/findings.json +1 -0
  26. package/.torusguard/runs/run-20260919-145701-audit/findings.md +8 -0
  27. package/.torusguard/runs/run-20260919-145701-audit/manifest.json +12 -0
  28. package/.torusguard/runs/run-20260919-145701-audit/summary.md +5 -0
  29. package/.torusguard/runs/run-20260919-151729-audit/findings.json +1 -0
  30. package/.torusguard/runs/run-20260919-151729-audit/findings.md +8 -0
  31. package/.torusguard/runs/run-20260919-151729-audit/manifest.json +13 -0
  32. package/.torusguard/runs/run-20260919-151729-audit/remediation.md +7 -0
  33. package/.torusguard/runs/run-20260919-151729-audit/summary.md +5 -0
  34. package/.torusguard/runs/run-20260919-152340-audit/findings.json +1 -0
  35. package/.torusguard/runs/run-20260919-152340-audit/findings.md +8 -0
  36. package/.torusguard/runs/run-20260919-152340-audit/manifest.json +12 -0
  37. package/.torusguard/runs/run-20260919-152340-audit/summary.md +5 -0
  38. package/.torusguard/runs/run-20260919-152345-audit/findings.json +1 -0
  39. package/.torusguard/runs/run-20260919-152345-audit/findings.md +8 -0
  40. package/.torusguard/runs/run-20260919-152345-audit/manifest.json +12 -0
  41. package/.torusguard/runs/run-20260919-152345-audit/summary.md +5 -0
  42. package/.torusguard/runs/run-20260919-153500-audit/findings.json +1 -0
  43. package/.torusguard/runs/run-20260919-153500-audit/findings.md +8 -0
  44. package/.torusguard/runs/run-20260919-153500-audit/manifest.json +12 -0
  45. package/.torusguard/runs/run-20260919-153500-audit/summary.md +5 -0
  46. package/.torusguard/scripts/__pycache__/apply_runner.cpython-314.pyc +0 -0
  47. package/.torusguard/scripts/__pycache__/audit_runner.cpython-314.pyc +0 -0
  48. package/.torusguard/scripts/__pycache__/diff_guard.cpython-314.pyc +0 -0
  49. package/.torusguard/scripts/__pycache__/finding_scorer.cpython-314.pyc +0 -0
  50. package/.torusguard/scripts/__pycache__/harden_runner.cpython-314.pyc +0 -0
  51. package/.torusguard/scripts/__pycache__/html_reporter.cpython-314.pyc +0 -0
  52. package/.torusguard/scripts/__pycache__/manifest_builder.cpython-314.pyc +0 -0
  53. package/.torusguard/scripts/__pycache__/memory_engine.cpython-314.pyc +0 -0
  54. package/.torusguard/scripts/__pycache__/monorepo_detector.cpython-314.pyc +0 -0
  55. package/.torusguard/scripts/__pycache__/recheck_runner.cpython-314.pyc +0 -0
  56. package/.torusguard/scripts/__pycache__/recipes_runner.cpython-314.pyc +0 -0
  57. package/.torusguard/scripts/__pycache__/report_sync.cpython-314.pyc +0 -0
  58. package/.torusguard/scripts/__pycache__/run_manager.cpython-314.pyc +0 -0
  59. package/.torusguard/scripts/__pycache__/sarif_exporter.cpython-314.pyc +0 -0
  60. package/.torusguard/scripts/__pycache__/stack_detect.cpython-314.pyc +0 -0
  61. package/.torusguard/scripts/__pycache__/term_ui.cpython-314.pyc +0 -0
  62. package/.torusguard/scripts/apply_runner.py +108 -9
  63. package/.torusguard/scripts/audit_runner.py +336 -24
  64. package/.torusguard/scripts/harden_runner.py +124 -70
  65. package/.torusguard/scripts/html_reporter.py +3585 -648
  66. package/.torusguard/scripts/manifest_builder.py +2 -0
  67. package/.torusguard/scripts/recheck_runner.py +5 -4
  68. package/.torusguard/scripts/recipes_runner.py +91 -8
  69. package/.torusguard/scripts/report_sync.py +496 -73
  70. package/.torusguard/scripts/sarif_exporter.py +48 -8
  71. package/.torusguard/scripts/stack_detect.py +44 -2
  72. package/.torusguard/scripts/status_runner.py +267 -0
  73. package/.torusguard/scripts/term_ui.py +1 -1
  74. package/.torusguard/skills/torusguard/SKILL.md +75 -72
  75. package/.torusguard/skills/torusguard-apply/SKILL.md +84 -80
  76. package/.torusguard/skills/torusguard-audit/SKILL.md +87 -83
  77. package/.torusguard/skills/torusguard-authorize/SKILL.md +7 -2
  78. package/.torusguard/skills/torusguard-exploit-check/SKILL.md +7 -2
  79. package/.torusguard/skills/torusguard-full/SKILL.md +7 -2
  80. package/.torusguard/skills/torusguard-harden/SKILL.md +98 -94
  81. package/.torusguard/skills/torusguard-init/SKILL.md +68 -64
  82. package/.torusguard/skills/torusguard-recheck/SKILL.md +81 -77
  83. package/.torusguard/skills/torusguard-report/SKILL.md +93 -72
  84. package/.torusguard/skills/torusguard-status/SKILL.md +62 -58
  85. package/.torusguard/skills/torusguard-verify/SKILL.md +7 -2
  86. package/.torusguard/skills/torusguard-web-validate/SKILL.md +7 -2
  87. package/.torusguard/workflows/apply.md +1 -1
  88. package/.torusguard/workflows/audit.md +1 -1
  89. package/.torusguard/workflows/authorize.md +1 -1
  90. package/.torusguard/workflows/exploit-check.md +1 -1
  91. package/.torusguard/workflows/harden.md +1 -1
  92. package/.torusguard/workflows/init.md +1 -1
  93. package/.torusguard/workflows/memory.md +1 -1
  94. package/.torusguard/workflows/recheck.md +1 -1
  95. package/.torusguard/workflows/report.md +1 -1
  96. package/.torusguard/workflows/status.md +1 -1
  97. package/.torusguard/workflows/verify.md +1 -1
  98. package/.torusguard/workflows/web-validate.md +1 -1
  99. package/README.md +115 -81
  100. package/bin/torusguard.js +244 -38
  101. package/package.json +6 -2
  102. package/skills/torusguard/SKILL.md +1 -1
  103. package/skills/torusguard/__pycache__/bootstrap.cpython-314.pyc +0 -0
  104. package/skills/torusguard/bootstrap.py +52 -8
  105. package/skills/torusguard/payload/.manifest.json +51 -36
  106. package/skills/torusguard/payload/scripts/__pycache__/apply_runner.cpython-314.pyc +0 -0
  107. package/skills/torusguard/payload/scripts/__pycache__/audit_runner.cpython-311.pyc +0 -0
  108. package/skills/torusguard/payload/scripts/__pycache__/audit_runner.cpython-314.pyc +0 -0
  109. package/skills/torusguard/payload/scripts/__pycache__/diff_guard.cpython-311.pyc +0 -0
  110. package/skills/torusguard/payload/scripts/__pycache__/diff_guard.cpython-314.pyc +0 -0
  111. package/skills/torusguard/payload/scripts/__pycache__/finding_scorer.cpython-311.pyc +0 -0
  112. package/skills/torusguard/payload/scripts/__pycache__/finding_scorer.cpython-314.pyc +0 -0
  113. package/skills/torusguard/payload/scripts/__pycache__/harden_runner.cpython-314.pyc +0 -0
  114. package/skills/torusguard/payload/scripts/__pycache__/html_reporter.cpython-311.pyc +0 -0
  115. package/skills/torusguard/payload/scripts/__pycache__/html_reporter.cpython-314.pyc +0 -0
  116. package/skills/torusguard/payload/scripts/__pycache__/manifest_builder.cpython-314.pyc +0 -0
  117. package/skills/torusguard/payload/scripts/__pycache__/memory_engine.cpython-311.pyc +0 -0
  118. package/skills/torusguard/payload/scripts/__pycache__/memory_engine.cpython-314.pyc +0 -0
  119. package/skills/torusguard/payload/scripts/__pycache__/monorepo_detector.cpython-311.pyc +0 -0
  120. package/skills/torusguard/payload/scripts/__pycache__/monorepo_detector.cpython-314.pyc +0 -0
  121. package/skills/torusguard/payload/scripts/__pycache__/recheck_runner.cpython-314.pyc +0 -0
  122. package/skills/torusguard/payload/scripts/__pycache__/report_sync.cpython-311.pyc +0 -0
  123. package/skills/torusguard/payload/scripts/__pycache__/report_sync.cpython-314.pyc +0 -0
  124. package/skills/torusguard/payload/scripts/__pycache__/rules_sync.cpython-311.pyc +0 -0
  125. package/skills/torusguard/payload/scripts/__pycache__/run_manager.cpython-311.pyc +0 -0
  126. package/skills/torusguard/payload/scripts/__pycache__/run_manager.cpython-314.pyc +0 -0
  127. package/skills/torusguard/payload/scripts/__pycache__/sarif_exporter.cpython-314.pyc +0 -0
  128. package/skills/torusguard/payload/scripts/__pycache__/stack_detect.cpython-311.pyc +0 -0
  129. package/skills/torusguard/payload/scripts/__pycache__/stack_detect.cpython-314.pyc +0 -0
  130. package/skills/torusguard/payload/scripts/__pycache__/term_ui.cpython-311.pyc +0 -0
  131. package/skills/torusguard/payload/scripts/__pycache__/term_ui.cpython-314.pyc +0 -0
  132. package/skills/torusguard/payload/scripts/apply_runner.py +108 -9
  133. package/skills/torusguard/payload/scripts/audit_runner.py +336 -24
  134. package/skills/torusguard/payload/scripts/harden_runner.py +124 -70
  135. package/skills/torusguard/payload/scripts/html_reporter.py +3585 -648
  136. package/skills/torusguard/payload/scripts/manifest_builder.py +2 -0
  137. package/skills/torusguard/payload/scripts/recheck_runner.py +5 -4
  138. package/skills/torusguard/payload/scripts/recipes_runner.py +91 -8
  139. package/skills/torusguard/payload/scripts/report_sync.py +496 -73
  140. package/skills/torusguard/payload/scripts/sarif_exporter.py +48 -8
  141. package/skills/torusguard/payload/scripts/stack_detect.py +44 -2
  142. package/skills/torusguard/payload/scripts/status_runner.py +267 -0
  143. package/skills/torusguard/payload/scripts/term_ui.py +1 -1
  144. package/skills/torusguard/payload/skills/torusguard/SKILL.md +1 -1
  145. package/skills/torusguard/payload/skills/torusguard-apply/SKILL.md +1 -1
  146. package/skills/torusguard/payload/skills/torusguard-audit/SKILL.md +1 -1
  147. package/skills/torusguard/payload/skills/torusguard-authorize/SKILL.md +1 -1
  148. package/skills/torusguard/payload/skills/torusguard-exploit-check/SKILL.md +1 -1
  149. package/skills/torusguard/payload/skills/torusguard-full/SKILL.md +1 -1
  150. package/skills/torusguard/payload/skills/torusguard-harden/SKILL.md +1 -1
  151. package/skills/torusguard/payload/skills/torusguard-init/SKILL.md +1 -1
  152. package/skills/torusguard/payload/skills/torusguard-recheck/SKILL.md +1 -1
  153. package/skills/torusguard/payload/skills/torusguard-report/SKILL.md +40 -23
  154. package/skills/torusguard/payload/skills/torusguard-status/SKILL.md +1 -1
  155. package/skills/torusguard/payload/skills/torusguard-verify/SKILL.md +1 -1
  156. package/skills/torusguard/payload/skills/torusguard-web-validate/SKILL.md +1 -1
  157. package/skills/torusguard/payload/workflows/apply.md +9 -1
  158. package/skills/torusguard/payload/workflows/audit.md +8 -2
  159. package/skills/torusguard/payload/workflows/authorize.md +1 -1
  160. package/skills/torusguard/payload/workflows/exploit-check.md +1 -1
  161. package/skills/torusguard/payload/workflows/harden.md +6 -1
  162. package/skills/torusguard/payload/workflows/init.md +7 -1
  163. package/skills/torusguard/payload/workflows/memory.md +1 -1
  164. package/skills/torusguard/payload/workflows/recheck.md +1 -1
  165. package/skills/torusguard/payload/workflows/recipes.md +55 -0
  166. package/skills/torusguard/payload/workflows/report.md +59 -55
  167. package/skills/torusguard/payload/workflows/status.md +4 -1
  168. package/skills/torusguard/payload/workflows/torusguard-apply.md +110 -0
  169. package/skills/torusguard/payload/workflows/torusguard-audit.md +105 -0
  170. package/skills/torusguard/payload/workflows/torusguard-authorize.md +96 -0
  171. package/skills/torusguard/payload/workflows/torusguard-exploit-check.md +98 -0
  172. package/skills/torusguard/payload/workflows/torusguard-harden.md +104 -0
  173. package/skills/torusguard/payload/workflows/torusguard-init.md +106 -0
  174. package/skills/torusguard/payload/workflows/torusguard-recheck.md +101 -0
  175. package/skills/torusguard/payload/workflows/torusguard-recipes.md +55 -0
  176. package/skills/torusguard/payload/workflows/torusguard-report.md +105 -0
  177. package/skills/torusguard/payload/workflows/torusguard-status.md +103 -0
  178. package/skills/torusguard/payload/workflows/torusguard-verify.md +100 -0
  179. package/skills/torusguard/payload/workflows/torusguard-web-validate.md +96 -0
  180. package/skills/torusguard/payload/workflows/torusguard.md +19 -0
  181. package/skills/torusguard/payload/workflows/verify.md +1 -1
  182. package/skills/torusguard/payload/workflows/web-validate.md +1 -1
  183. package/skills/torusguard-apply/SKILL.md +1 -1
  184. package/skills/torusguard-audit/SKILL.md +1 -1
  185. package/skills/torusguard-authorize/SKILL.md +1 -1
  186. package/skills/torusguard-exploit-check/SKILL.md +1 -1
  187. package/skills/torusguard-full/SKILL.md +1 -1
  188. package/skills/torusguard-harden/SKILL.md +1 -1
  189. package/skills/torusguard-init/SKILL.md +1 -1
  190. package/skills/torusguard-recheck/SKILL.md +1 -1
  191. package/skills/torusguard-report/SKILL.md +40 -23
  192. package/skills/torusguard-status/SKILL.md +1 -1
  193. package/skills/torusguard-verify/SKILL.md +1 -1
  194. package/skills/torusguard-web-validate/SKILL.md +1 -1
@@ -0,0 +1,960 @@
1
+ # TorusGuard Security Audit Findings: run-20260918-104236-audit
2
+ - Target Root: `C:\Users\Admin\Desktop\TorusGuard`
3
+ - Total Scored Findings: `68`
4
+ - Identified Clusters: `9`
5
+ - Generated At: `2026-09-18 10:42:36 IST`
6
+
7
+ ---
8
+ ## Summary of Findings
9
+
10
+ ### [Critical] TG-INPUT-002 - Raw SQL Concatenation
11
+ - **Finding ID:** `TG-INPUT-002-f8cd11b9`
12
+ - **Location:** `harness/runner.py:258`
13
+ - **Confidence Score:** `84/100` (High Confidence)
14
+ - **Cluster:** `cluster-injection`
15
+ - **Description:** Python f-string interpolation in raw SQL query
16
+ ```
17
+ framework_pattern=FrameworkPattern(
18
+ framework="Django",
19
+ unsafe_snippet="User.objects.raw(f'SELECT * FROM users WHERE name = {name}')",
20
+ safe_snippet="User.objects.raw('SELECT * FROM users WHERE name = %s', [name])",
21
+ ),
22
+ ```
23
+
24
+ ### [Critical] TG-SEC-001 - Hardcoded Secret or API Key in Tracked Source
25
+ - **Finding ID:** `TG-SEC-001-593d6437`
26
+ - **Location:** `harness/runner.py:211`
27
+ - **Confidence Score:** `81/100` (High Confidence)
28
+ - **Cluster:** `cluster-credentials-exposure`
29
+ - **Description:** Hardcoded credential or API secret string
30
+ ```
31
+ type=EvidenceType.SOURCE,
32
+ location="server/auth.py:42",
33
+ raw_snippet="SECRET_KEY = 'super_secret_jwt_key'",
34
+ rationale="Hardcoded secret credential.",
35
+ confidence_level=ConfidenceBand.CONFIRMED,
36
+ ```
37
+
38
+ ### [Critical] TG-SEC-001 - Hardcoded Secret or API Key in Tracked Source
39
+ - **Finding ID:** `TG-SEC-001-e0a84cf3`
40
+ - **Location:** `harness/runner.py:221`
41
+ - **Confidence Score:** `81/100` (High Confidence)
42
+ - **Cluster:** `cluster-credentials-exposure`
43
+ - **Description:** Hardcoded credential or API secret string
44
+ ```
45
+ def test_sensitive_data_masking(self):
46
+ print("\n6. Testing Sensitive Secret & Token Masking...")
47
+ sample_secret = "API_KEY = 'sk_live_998877665544332211'"
48
+ masked = mask_sensitive_data(sample_secret)
49
+ self.log_test("Stripe Secret Key Redaction", "sk_live_***REDACTED***" in masked and "998877665544332211" not in masked)
50
+ ```
51
+
52
+ ### [Critical] TG-SEC-001 - Hardcoded Secret or API Key in Tracked Source
53
+ - **Finding ID:** `TG-SEC-001-88c9bb29`
54
+ - **Location:** `harness/runner.py:392`
55
+ - **Confidence Score:** `81/100` (High Confidence)
56
+ - **Cluster:** `cluster-credentials-exposure`
57
+ - **Description:** Hardcoded credential or API secret string
58
+ ```
59
+ type=EvidenceType.SOURCE,
60
+ location="settings.py:10",
61
+ raw_snippet="DEBUG = True\nSECRET_KEY = 'sk_live_secret_key_12345'",
62
+ rationale="Production debug mode exposure and hardcoded secret.",
63
+ confidence_level=ConfidenceBand.CONFIRMED,
64
+ ```
65
+
66
+ ### [Critical] TG-SEC-001 - Hardcoded Secret or API Key in Tracked Source
67
+ - **Finding ID:** `TG-SEC-001-c616aefd`
68
+ - **Location:** `harness/validate_qa_v0_6_0.py:64`
69
+ - **Confidence Score:** `77/100` (High Confidence)
70
+ - **Cluster:** `cluster-credentials-exposure`
71
+ - **Description:** Hardcoded credential or API secret string
72
+ ```
73
+ "tiny-repo": {
74
+ "vulnerable": {
75
+ "app.py": 'DEBUG = True\nSECRET_KEY = "sk_live_1234567890"\n\ndef index():\n return "Welcome"\n'
76
+ },
77
+ "hardened": {
78
+ ```
79
+
80
+ ### [Critical] TG-SEC-001 - Hardcoded Secret or API Key in Tracked Source
81
+ - **Finding ID:** `TG-SEC-001-d5b3684f`
82
+ - **Location:** `harness/validate_qa_v0_6_0.py:90`
83
+ - **Confidence Score:** `77/100` (High Confidence)
84
+ - **Cluster:** `cluster-credentials-exposure`
85
+ - **Description:** Hardcoded credential or API secret string
86
+ ```
87
+ "confidence_band": "Confirmed",
88
+ "target": {"file_path": "app.py", "line_start": 2, "line_end": 2},
89
+ "evidence": {"code_snippet": 'SECRET_KEY = "sk_live_1234567890"'},
90
+ "what_is_wrong": "Hardcoded secret exposed in source code.",
91
+ "what_should_change": "Load SECRET_KEY from environment variables.",
92
+ ```
93
+
94
+ ### [Critical] TG-SEC-001 - Hardcoded Secret or API Key in Tracked Source
95
+ - **Finding ID:** `TG-SEC-001-54f1a02a`
96
+ - **Location:** `harness/validate_v0_6_2_modern_stacks.py:341`
97
+ - **Confidence Score:** `77/100` (High Confidence)
98
+ - **Cluster:** `cluster-credentials-exposure`
99
+ - **Description:** Hardcoded credential or API secret string
100
+ ```
101
+ COPY . .
102
+ # Running as root user & hardcoding secrets
103
+ ENV DATABASE_PASSWORD="secret_in_docker"
104
+ CMD ["python", "main.py"]
105
+ """, encoding="utf-8")
106
+ ```
107
+
108
+ ### [Critical] TG-SEC-001 - Hardcoded Secret or API Key in Tracked Source
109
+ - **Finding ID:** `TG-SEC-001-676f776e`
110
+ - **Location:** `harness/validate_v0_6_2_modern_stacks.py:356`
111
+ - **Confidence Score:** `77/100` (High Confidence)
112
+ - **Cluster:** `cluster-credentials-exposure`
113
+ - **Description:** Hardcoded credential or API secret string
114
+ ```
115
+ "confidence_band": "Confirmed",
116
+ "target": {"file_path": "Dockerfile", "line_start": 5, "line_end": 5},
117
+ "evidence": {"code_snippet": 'ENV DATABASE_PASSWORD="secret_in_docker"'},
118
+ "what_is_wrong": "Secret baked into immutable container image layer.",
119
+ "what_should_change": "Inject secrets at runtime or use BuildKit --mount=type=secret.",
120
+ ```
121
+
122
+ ### [Critical] TG-SEC-001 - Hardcoded Secret or API Key in Tracked Source
123
+ - **Finding ID:** `TG-SEC-001-58f70e46`
124
+ - **Location:** `harness/validate_v0_6_2_modern_stacks.py:362`
125
+ - **Confidence Score:** `77/100` (High Confidence)
126
+ - **Cluster:** `cluster-credentials-exposure`
127
+ - **Description:** Hardcoded credential or API secret string
128
+ ```
129
+ +++ b/Dockerfile
130
+ @@ -5,1 +5,2 @@
131
+ -ENV DATABASE_PASSWORD="secret_in_docker"
132
+ +USER appuser
133
+ """,
134
+ ```
135
+
136
+ ### [Critical] TG-INPUT-002 - Raw SQL Concatenation
137
+ - **Finding ID:** `TG-INPUT-002-02f8e274`
138
+ - **Location:** `harness/engine/fixture_manager.py:128`
139
+ - **Confidence Score:** `74/100` (High Confidence)
140
+ - **Cluster:** `cluster-injection`
141
+ - **Description:** Python f-string interpolation in raw SQL query
142
+ ```
143
+ vulnerable_variant=FixtureVariant(
144
+ relative_path="examples/python/sqlalchemy-vuln",
145
+ code_pattern="session.execute(f'SELECT * FROM items WHERE name LIKE {q}')",
146
+ expected_findings_count=4,
147
+ ),
148
+ ```
149
+
150
+ ### [Critical] TG-SEC-001 - Hardcoded Secret or API Key in Tracked Source
151
+ - **Finding ID:** `TG-SEC-001-7c852ff3`
152
+ - **Location:** `harness/master_validation.py:257`
153
+ - **Confidence Score:** `74/100` (High Confidence)
154
+ - **Cluster:** `cluster-credentials-exposure`
155
+ - **Description:** Hardcoded credential or API secret string
156
+ ```
157
+ self.log("Redaction", "JWT Token Redaction", "Bearer ***REDACTED_JWT***" in masked_jwt and "doNotLeakSignature" not in masked_jwt)
158
+
159
+ masked_pwd = mask_sensitive_data("DB_PASSWORD = 'super_secret_database_password_123'")
160
+ self.log("Redaction", "Password Variable Redaction", "***REDACTED***" in masked_pwd and "super_secret_database_password_123" not in masked_pwd)
161
+
162
+ ```
163
+
164
+ ### [Critical] TG-SEC-001 - Hardcoded Secret or API Key in Tracked Source
165
+ - **Finding ID:** `TG-SEC-001-02761dbb`
166
+ - **Location:** `harness/master_validation.py:460`
167
+ - **Confidence Score:** `74/100` (High Confidence)
168
+ - **Cluster:** `cluster-credentials-exposure`
169
+ - **Description:** Hardcoded credential or API secret string
170
+ ```
171
+
172
+ def _create_sample_finding(self, rule_id: str, target_path: str, secret_test: bool = False) -> Finding:
173
+ raw_code = "STRIPE_API_KEY = 'sk_live_998877665544332211'\nAuthorization = 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.doNotLeakSignature'" if secret_test else f"# Logic for {rule_id}\nrole = request.headers.get('X-User-Role')"
174
+
175
+ ev = Evidence(
176
+ ```
177
+
178
+ ### [Critical] TG-DB-004 - Missing Tenant Query Isolation in Multi-Tenant Models
179
+ - **Finding ID:** `TG-DB-004-e8cc000a`
180
+ - **Location:** `harness/runner.py:505`
181
+ - **Confidence Score:** `74/100` (High Confidence)
182
+ - **Cluster:** `cluster-tenant-isolation`
183
+ - **Description:** Django ORM .get(id=...) query lacking explicit tenant scope filter
184
+ ```
185
+
186
+ # 2. Stable Finding Identity
187
+ code_a = "def view():\n return Item.objects.get(id=id)"
188
+ code_b = "# Shifted comment\ndef view():\n return Item.objects.get(id=id)"
189
+ fp1 = IdentityEngine.generate_identity("TG-DB-004", "views.py", code_a, sink_signature="Item.objects.get")
190
+ ```
191
+
192
+ ### [Critical] TG-DB-004 - Missing Tenant Query Isolation in Multi-Tenant Models
193
+ - **Finding ID:** `TG-DB-004-89b581f9`
194
+ - **Location:** `harness/runner.py:506`
195
+ - **Confidence Score:** `74/100` (High Confidence)
196
+ - **Cluster:** `cluster-tenant-isolation`
197
+ - **Description:** Django ORM .get(id=...) query lacking explicit tenant scope filter
198
+ ```
199
+ # 2. Stable Finding Identity
200
+ code_a = "def view():\n return Item.objects.get(id=id)"
201
+ code_b = "# Shifted comment\ndef view():\n return Item.objects.get(id=id)"
202
+ fp1 = IdentityEngine.generate_identity("TG-DB-004", "views.py", code_a, sink_signature="Item.objects.get")
203
+ fp2 = IdentityEngine.generate_identity("TG-DB-004", "views.py", code_b, sink_signature="Item.objects.get")
204
+ ```
205
+
206
+ ### [Critical] TG-SEC-001 - Hardcoded Secret or API Key in Tracked Source
207
+ - **Finding ID:** `TG-SEC-001-3a2b5eca`
208
+ - **Location:** `harness/validate_e2e.py:355`
209
+ - **Confidence Score:** `74/100` (High Confidence)
210
+ - **Cluster:** `cluster-credentials-exposure`
211
+ - **Description:** Hardcoded credential or API secret string
212
+ ```
213
+
214
+ def _create_sample_finding(self, rule_id: str, target_path: str, secret_test: bool = False) -> Finding:
215
+ raw_code = "API_KEY = 'sk_live_998877665544332211'\nAuthorization = 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.doNotLeakSignature'" if secret_test else f"# Unsafe logic for {rule_id}\nrole = request.headers.get('X-User-Role')"
216
+
217
+ ev = Evidence(
218
+ ```
219
+
220
+ ### [Critical] TG-DB-002 - Privileged Database Credential in Browser Context
221
+ - **Finding ID:** `TG-DB-002-08d11e50`
222
+ - **Location:** `harness/validate_v0_9_2_diff_and_monorepo.py:134`
223
+ - **Confidence Score:** `74/100` (High Confidence)
224
+ - **Cluster:** `cluster-client-leak`
225
+ - **Description:** Service role key or raw database connection string reference in frontend code
226
+ ```
227
+ assert nextjs_file.is_file(), "Missing actions.ts in vulnerable_nextjs"
228
+ nx_code = nextjs_file.read_text(encoding="utf-8")
229
+ assert "TG-CLIENT-001" in nx_code and "SUPABASE_SERVICE_ROLE_KEY" in nx_code
230
+ assert "TG-AUTH-003" in nx_code and "use server" in nx_code
231
+ print(" [PASS] vulnerable_nextjs fixture contains TG-CLIENT-001 and TG-AUTH-003 sinks")
232
+ ```
233
+
234
+ ### [Critical] TG-INPUT-002 - Raw SQL Concatenation
235
+ - **Finding ID:** `TG-INPUT-002-8f877a5f`
236
+ - **Location:** `harness/validate_v1_1_0_advanced_memory.py:107`
237
+ - **Confidence Score:** `74/100` (High Confidence)
238
+ - **Cluster:** `cluster-injection`
239
+ - **Description:** Python f-string interpolation in raw SQL query
240
+ ```
241
+ memory_engine.ensure_memory_structure(root_dir=test_root)
242
+
243
+ valid_before = "cursor.execute(f'SELECT * FROM users WHERE id = {uid}')"
244
+ valid_after = "cursor.execute('SELECT * FROM users WHERE id = %s', (uid,))"
245
+ valid_diff = "- cursor.execute(f'SELECT * FROM users WHERE id = {uid}')\n+ cursor.execute('SELECT * FROM users WHERE id = %s', (uid,))"
246
+ ```
247
+
248
+ ### [Critical] TG-INPUT-002 - Raw SQL Concatenation
249
+ - **Finding ID:** `TG-INPUT-002-266bcaa1`
250
+ - **Location:** `harness/validate_v1_1_0_advanced_memory.py:109`
251
+ - **Confidence Score:** `74/100` (High Confidence)
252
+ - **Cluster:** `cluster-injection`
253
+ - **Description:** Python f-string interpolation in raw SQL query
254
+ ```
255
+ valid_before = "cursor.execute(f'SELECT * FROM users WHERE id = {uid}')"
256
+ valid_after = "cursor.execute('SELECT * FROM users WHERE id = %s', (uid,))"
257
+ valid_diff = "- cursor.execute(f'SELECT * FROM users WHERE id = {uid}')\n+ cursor.execute('SELECT * FROM users WHERE id = %s', (uid,))"
258
+
259
+ recipe = memory_engine.record_golden_recipe(
260
+ ```
261
+
262
+ ### [Critical] TG-DB-002 - Privileged Database Credential in Browser Context
263
+ - **Finding ID:** `TG-DB-002-14cf4139`
264
+ - **Location:** `harness/validate_v0_7_0_runtime.py:129`
265
+ - **Confidence Score:** `71/100` (High Confidence)
266
+ - **Cluster:** `cluster-client-leak`
267
+ - **Description:** Service role key or raw database connection string reference in frontend code
268
+ ```
269
+ self.send_header("Content-Type", "application/json")
270
+ self.end_headers()
271
+ self.wfile.write(b'{"DEBUG": true, "DATABASE_URL": "sqlite:////app/db.sqlite3"}')
272
+
273
+ elif url_path == "/api/files/download":
274
+ ```
275
+
276
+ ### [Critical] TG-DB-002 - Privileged Database Credential in Browser Context
277
+ - **Finding ID:** `TG-DB-002-b53ad22c`
278
+ - **Location:** `harness/validate_v0_7_0_runtime.py:423`
279
+ - **Confidence Score:** `71/100` (High Confidence)
280
+ - **Cluster:** `cluster-client-leak`
281
+ - **Description:** Service role key or raw database connection string reference in frontend code
282
+ ```
283
+
284
+ # 6. Exposed debug config -> Runtime Confirmed
285
+ r6 = ExploitChecker.check_debug_exposure(val, "fnd-6", "c-4", f"{self.base_url}/debug/env", "DATABASE_URL")
286
+ self.log_test("Phase 3", "Exposed Debug Configuration Confirmed", r6.status == ExploitabilityStatus.RUNTIME_CONFIRMED.value)
287
+
288
+ ```
289
+
290
+ ### [Critical] TG-DIFF-001 - Accidental Security Check Bypass in Patch Additions
291
+ - **Finding ID:** `TG-DIFF-001-04571685`
292
+ - **Location:** `harness/evaluate_portfolio_polyglot.py:74`
293
+ - **Confidence Score:** `69/100` (Medium Confidence)
294
+ - **Cluster:** `cluster-transport-security`
295
+ - **Description:** Disabled TLS certificate verification (verify=False)
296
+ ```
297
+ "expected_orm": "SQLAlchemy",
298
+ "ecosystem": "Python",
299
+ "test_bypass": ("python", "verify=False", "auth_bypass"),
300
+ "test_tenant": ("python", "tenant_id"),
301
+ },
302
+ ```
303
+
304
+ ### [Critical] TG-DIFF-001 - Accidental Security Check Bypass in Patch Additions
305
+ - **Finding ID:** `TG-DIFF-001-8b55ac4b`
306
+ - **Location:** `harness/evaluate_portfolio_polyglot.py:151`
307
+ - **Confidence Score:** `69/100` (Medium Confidence)
308
+ - **Cluster:** `cluster-transport-security`
309
+ - **Description:** Disabled Go TLS certificate verification (InsecureSkipVerify: true)
310
+ ```
311
+ "expected_orm": "GORM",
312
+ "ecosystem": "Go",
313
+ "test_bypass": ("go", "InsecureSkipVerify: true", "tls_bypass"),
314
+ "test_tenant": ("go", '.Where("tenant_id = ?", tenantID)'),
315
+ },
316
+ ```
317
+
318
+ ### [Critical] TG-DIFF-001 - Accidental Security Check Bypass in Patch Additions
319
+ - **Finding ID:** `TG-DIFF-001-cf8d252d`
320
+ - **Location:** `harness/evaluate_portfolio_polyglot.py:162`
321
+ - **Confidence Score:** `69/100` (Medium Confidence)
322
+ - **Cluster:** `cluster-transport-security`
323
+ - **Description:** Disabled Go TLS certificate verification (InsecureSkipVerify: true)
324
+ ```
325
+ "expected_orm": "SQLx",
326
+ "ecosystem": "Go",
327
+ "test_bypass": ("go", "tls.Config{InsecureSkipVerify: true}", "tls_bypass"),
328
+ "test_tenant": ("go", '.Where("org_id = ?", orgID)'),
329
+ },
330
+ ```
331
+
332
+ ### [Critical] TG-DIFF-001 - Accidental Security Check Bypass in Patch Additions
333
+ - **Finding ID:** `TG-DIFF-001-3543946e`
334
+ - **Location:** `harness/evaluate_portfolio_polyglot.py:173`
335
+ - **Confidence Score:** `69/100` (Medium Confidence)
336
+ - **Cluster:** `cluster-transport-security`
337
+ - **Description:** Disabled Go TLS certificate verification (InsecureSkipVerify: true)
338
+ ```
339
+ "expected_orm": None,
340
+ "ecosystem": "Go",
341
+ "test_bypass": ("go", "InsecureSkipVerify: true", "tls_bypass"),
342
+ "test_tenant": ("go", '.Where("tenant_id = ?", tid)'),
343
+ },
344
+ ```
345
+
346
+ ### [Critical] TG-DIFF-001 - Accidental Security Check Bypass in Patch Additions
347
+ - **Finding ID:** `TG-DIFF-001-efffaad0`
348
+ - **Location:** `harness/evaluate_portfolio_polyglot.py:349`
349
+ - **Confidence Score:** `69/100` (Medium Confidence)
350
+ - **Cluster:** `cluster-transport-security`
351
+ - **Description:** Disabled Go TLS certificate verification (InsecureSkipVerify: true)
352
+ ```
353
+ "expected_orm": None,
354
+ "ecosystem": "Polyglot Fleet",
355
+ "test_bypass": ("go", "InsecureSkipVerify: true", "tls_bypass"),
356
+ "test_tenant": ("go", '.Where("tenant_id = ?", tid)'),
357
+ },
358
+ ```
359
+
360
+ ### [Critical] TG-DIFF-001 - Accidental Security Check Bypass in Patch Additions
361
+ - **Finding ID:** `TG-DIFF-001-91bd06b8`
362
+ - **Location:** `harness/evaluate_portfolio_polyglot.py:129`
363
+ - **Confidence Score:** `69/100` (Medium Confidence)
364
+ - **Cluster:** `cluster-transport-security`
365
+ - **Description:** Disabled Node.js TLS rejectUnauthorized
366
+ ```
367
+ "expected_orm": "Mongoose",
368
+ "ecosystem": "JavaScript",
369
+ "test_bypass": ("javascript", "rejectUnauthorized: false", "tls_bypass"),
370
+ "test_tenant": ("javascript", "author: req.user.id"),
371
+ },
372
+ ```
373
+
374
+ ### [Critical] TG-DIFF-001 - Accidental Security Check Bypass in Patch Additions
375
+ - **Finding ID:** `TG-DIFF-001-cb245735`
376
+ - **Location:** `harness/evaluate_portfolio_polyglot.py:261`
377
+ - **Confidence Score:** `69/100` (Medium Confidence)
378
+ - **Cluster:** `cluster-transport-security`
379
+ - **Description:** Disabled PHP curl SSL verification
380
+ ```
381
+ "expected_orm": "Eloquent",
382
+ "ecosystem": "PHP",
383
+ "test_bypass": ("php", "CURLOPT_SSL_VERIFYPEER => false", "tls_bypass"),
384
+ "test_tenant": ("php", 'where("tenant_id", $tenantId)'),
385
+ },
386
+ ```
387
+
388
+ ### [Critical] TG-DIFF-001 - Accidental Security Check Bypass in Patch Additions
389
+ - **Finding ID:** `TG-DIFF-001-6667680a`
390
+ - **Location:** `harness/validate_v0_9_2_diff_and_monorepo.py:60`
391
+ - **Confidence Score:** `69/100` (Medium Confidence)
392
+ - **Cluster:** `cluster-transport-security`
393
+ - **Description:** Disabled TLS certificate verification (verify=False)
394
+ ```
395
+ def authenticate_user(token):
396
+ + # TODO: bypass auth check for debugging
397
+ + verify = False
398
+ return True
399
+ """
400
+ ```
401
+
402
+ ### [Critical] TG-DIFF-001 - Accidental Security Check Bypass in Patch Additions
403
+ - **Finding ID:** `TG-DIFF-001-00b3b8ca`
404
+ - **Location:** `harness/validate_v0_9_2_diff_and_monorepo.py:67`
405
+ - **Confidence Score:** `69/100` (Medium Confidence)
406
+ - **Cluster:** `cluster-transport-security`
407
+ - **Description:** Disabled TLS certificate verification (verify=False)
408
+ ```
409
+ rule_ids = [v["rule_id"] for v in res_bypass["violations"]]
410
+ assert "TG-DIFF-001" in rule_ids, "TG-DIFF-001 bypass not caught"
411
+ print(f" [PASS] TG-DIFF-001: Caught bypass comments and verify=False ({res_bypass['total_violations']} violations)")
412
+
413
+ mock_key = "sk" + "_live_" + "99887766554433221100aabbccdd"
414
+ ```
415
+
416
+ ### [Critical] TG-DIFF-001 - Accidental Security Check Bypass in Patch Additions
417
+ - **Finding ID:** `TG-DIFF-001-f209dec6`
418
+ - **Location:** `harness/validate_v1_3_0_polyglot.py:16`
419
+ - **Confidence Score:** `69/100` (Medium Confidence)
420
+ - **Cluster:** `cluster-transport-security`
421
+ - **Description:** Disabled Go TLS certificate verification (InsecureSkipVerify: true)
422
+ ```
423
+ - File extension census fallback (no manifest)
424
+ 2. Polyglot Diff Guard bypass detection across:
425
+ - Go (InsecureSkipVerify: true)
426
+ - Java (csrf().disable())
427
+ - C# ([AllowAnonymous])
428
+ ```
429
+
430
+ ### [Critical] TG-DIFF-001 - Accidental Security Check Bypass in Patch Additions
431
+ - **Finding ID:** `TG-DIFF-001-d9adecdb`
432
+ - **Location:** `harness/validate_v1_3_0_polyglot.py:182`
433
+ - **Confidence Score:** `69/100` (Medium Confidence)
434
+ - **Cluster:** `cluster-transport-security`
435
+ - **Description:** Disabled Go TLS certificate verification (InsecureSkipVerify: true)
436
+ ```
437
+ +++ b/client.go
438
+ @@ -10,3 +10,4 @@
439
+ + tr := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}
440
+ """
441
+ viol_go = diff_guard.check_diff_content(diff_go, "client.go")
442
+ ```
443
+
444
+ ### [Critical] TG-DIFF-001 - Accidental Security Check Bypass in Patch Additions
445
+ - **Finding ID:** `TG-DIFF-001-ddbf5cf0`
446
+ - **Location:** `harness/validate_v1_3_0_polyglot.py:19`
447
+ - **Confidence Score:** `69/100` (Medium Confidence)
448
+ - **Cluster:** `cluster-transport-security`
449
+ - **Description:** Disabled PHP curl SSL verification
450
+ ```
451
+ - Java (csrf().disable())
452
+ - C# ([AllowAnonymous])
453
+ - PHP (CURLOPT_SSL_VERIFYPEER => false)
454
+ - Rust (unsafe { ... })
455
+ 3. Polyglot Tenant Scoping Patterns across GORM, LINQ, and Prisma
456
+ ```
457
+
458
+ ### [Critical] TG-DIFF-001 - Accidental Security Check Bypass in Patch Additions
459
+ - **Finding ID:** `TG-DIFF-001-2b3eb6b7`
460
+ - **Location:** `harness/validate_v1_3_0_polyglot.py:215`
461
+ - **Confidence Score:** `69/100` (Medium Confidence)
462
+ - **Cluster:** `cluster-transport-security`
463
+ - **Description:** Disabled PHP curl SSL verification
464
+ ```
465
+ +++ b/api.php
466
+ @@ -5,3 +5,4 @@
467
+ + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
468
+ """
469
+ viol_php = diff_guard.check_diff_content(diff_php, "api.php")
470
+ ```
471
+
472
+ ### [Critical] TG-DB-004 - Missing Tenant Query Isolation in Multi-Tenant Models
473
+ - **Finding ID:** `TG-DB-004-e33fd263`
474
+ - **Location:** `harness/validate_v0_6_3_hardening.py:119`
475
+ - **Confidence Score:** `67/100` (Medium Confidence)
476
+ - **Cluster:** `cluster-tenant-isolation`
477
+ - **Description:** Django ORM .get(id=...) query lacking explicit tenant scope filter
478
+ ```
479
+ snippet_v1 = """def process_invoice(req, inv_id):
480
+ # Retrieve invoice
481
+ inv = Invoice.objects.get(id=inv_id)
482
+ return inv
483
+ """
484
+ ```
485
+
486
+ ### [Critical] TG-DB-004 - Missing Tenant Query Isolation in Multi-Tenant Models
487
+ - **Finding ID:** `TG-DB-004-ff3f7499`
488
+ - **Location:** `harness/validate_v0_6_3_hardening.py:127`
489
+ - **Confidence Score:** `67/100` (Medium Confidence)
490
+ - **Cluster:** `cluster-tenant-isolation`
491
+ - **Description:** Django ORM .get(id=...) query lacking explicit tenant scope filter
492
+ ```
493
+ snippet_v2 = """def process_invoice(req, inv_id):
494
+ # Retrieve invoice
495
+ inv = Invoice.objects.get(id=inv_id)
496
+ return inv
497
+ """
498
+ ```
499
+
500
+ ### [Critical] TG-DB-004 - Missing Tenant Query Isolation in Multi-Tenant Models
501
+ - **Finding ID:** `TG-DB-004-a7c00c05`
502
+ - **Location:** `harness/validate_v0_6_3_hardening.py:135`
503
+ - **Confidence Score:** `67/100` (Medium Confidence)
504
+ - **Cluster:** `cluster-tenant-isolation`
505
+ - **Description:** Django ORM .get(id=...) query lacking explicit tenant scope filter
506
+ ```
507
+ snippet_v3 = """def process_invoice(req, inv_id):
508
+ # Different comment text here
509
+ inv = Invoice.objects.get(id=inv_id)
510
+ return inv
511
+ """
512
+ ```
513
+
514
+ ### [Critical] TG-DB-004 - Missing Tenant Query Isolation in Multi-Tenant Models
515
+ - **Finding ID:** `TG-DB-004-8b6c1463`
516
+ - **Location:** `harness/validate_v0_6_3_hardening.py:171`
517
+ - **Confidence Score:** `67/100` (Medium Confidence)
518
+ - **Cluster:** `cluster-tenant-isolation`
519
+ - **Description:** Django ORM .get(id=...) query lacking explicit tenant scope filter
520
+ ```
521
+ "confidence_band": "Confirmed",
522
+ "target": {"file_path": "apps/billing/views.py", "line_start": 12, "line_end": 14},
523
+ "evidence": {"code_snippet": "Invoice.objects.get(id=inv_id)"},
524
+ "cluster_id": "cluster-tenant-isolation",
525
+ "recheck_status": "Confirmed Fixed",
526
+ ```
527
+
528
+ ### [Critical] TG-DB-004 - Missing Tenant Query Isolation in Multi-Tenant Models
529
+ - **Finding ID:** `TG-DB-004-9a2f13c7`
530
+ - **Location:** `harness/validate_v0_6_1_scale.py:115`
531
+ - **Confidence Score:** `64/100` (Medium Confidence)
532
+ - **Cluster:** `cluster-tenant-isolation`
533
+ - **Description:** Django ORM .get(id=...) query lacking explicit tenant scope filter
534
+ ```
535
+ "severity": "High",
536
+ "target": {"file_path": "apps/django_core/billing/views.py", "line_start": 42, "line_end": 42},
537
+ "evidence": {"code_snippet": "Invoice.objects.get(id=inv_id)"},
538
+ },
539
+ # FastAPI Microservice
540
+ ```
541
+
542
+ ### [Critical] TG-DB-004 - Missing Tenant Query Isolation in Multi-Tenant Models
543
+ - **Finding ID:** `TG-DB-004-a932f5b8`
544
+ - **Location:** `harness/validate_v0_6_1_scale.py:193`
545
+ - **Confidence Score:** `64/100` (Medium Confidence)
546
+ - **Cluster:** `cluster-tenant-isolation`
547
+ - **Description:** Django ORM .get(id=...) query lacking explicit tenant scope filter
548
+ ```
549
+ "confidence_band": "Confirmed",
550
+ "target": {"file_path": f"services/api/module_{i % 15}/views.py", "line_start": 10 + i, "line_end": 12 + i},
551
+ "evidence": {"code_snippet": f"Model_{i}.objects.get(id=id)"},
552
+ })
553
+
554
+ ```
555
+
556
+ ### [Critical] TG-DB-004 - Missing Tenant Query Isolation in Multi-Tenant Models
557
+ - **Finding ID:** `TG-DB-004-14a2d74f`
558
+ - **Location:** `harness/validate_v1_0_0_memory.py:265`
559
+ - **Confidence Score:** `64/100` (Medium Confidence)
560
+ - **Cluster:** `cluster-tenant-isolation`
561
+ - **Description:** Django ORM .get(id=...) query lacking explicit tenant scope filter
562
+ ```
563
+ - return Bill.objects.filter(id=id, tenant=tenant)
564
+ +def get_bill(id):
565
+ + return Bill.objects.get(id=id)
566
+ """
567
+ res_reg = diff_guard.audit_diff(regression_diff, check_memory=True, root_dir=test_root)
568
+ ```
569
+
570
+ ### [Critical] TG-SUPPLY-004 - Unpinned CI Action
571
+ - **Finding ID:** `TG-SUPPLY-004-e52415c0`
572
+ - **Location:** `harness/validate_v0_6_2_modern_stacks.py:383`
573
+ - **Confidence Score:** `47/100` (Needs Review)
574
+ - **Cluster:** `cluster-supply-chain`
575
+ - **Description:** GitHub Action referenced by mutable tag instead of immutable commit SHA
576
+ ```
577
+ runs-on: ubuntu-latest
578
+ steps:
579
+ - uses: actions/checkout@v2
580
+ - run: make test
581
+ """, encoding="utf-8")
582
+ ```
583
+
584
+ ### [Critical] TG-SUPPLY-004 - Unpinned CI Action
585
+ - **Finding ID:** `TG-SUPPLY-004-b9d15743`
586
+ - **Location:** `harness/validate_v0_6_2_modern_stacks.py:404`
587
+ - **Confidence Score:** `47/100` (Needs Review)
588
+ - **Cluster:** `cluster-supply-chain`
589
+ - **Description:** GitHub Action referenced by mutable tag instead of immutable commit SHA
590
+ ```
591
+ +++ b/.github/workflows/ci.yml
592
+ @@ -6,1 +6,1 @@
593
+ - - uses: actions/checkout@v2
594
+ + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
595
+ """,
596
+ ```
597
+
598
+ ### [Critical] TG-SUPPLY-004 - Unpinned CI Action
599
+ - **Finding ID:** `TG-SUPPLY-004-9240a873`
600
+ - **Location:** `harness/validate_v0_6_3_hardening.py:251`
601
+ - **Confidence Score:** `44/100` (Needs Review)
602
+ - **Cluster:** `cluster-supply-chain`
603
+ - **Description:** GitHub Action referenced by mutable tag instead of immutable commit SHA
604
+ ```
605
+ +++ b/.github/workflows/deploy.yml
606
+ @@ -5,1 +5,2 @@
607
+ - - uses: actions/checkout@v2
608
+ + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29
609
+ + with: { persist-credentials: false }
610
+ ```
611
+
612
+ ### [High] TG-AUTH-004 - Insecure Session Cookie Configuration
613
+ - **Finding ID:** `TG-AUTH-004-33adb2d9`
614
+ - **Location:** `harness/evaluate_portfolio_polyglot.py:107`
615
+ - **Confidence Score:** `66/100` (Medium Confidence)
616
+ - **Cluster:** `cluster-auth-bypass`
617
+ - **Description:** Session cookie secure flag disabled in Django settings
618
+ ```
619
+ "expected_orm": "SQLAlchemy",
620
+ "ecosystem": "Python",
621
+ "test_bypass": ("python", "SESSION_COOKIE_SECURE = False", "auth_bypass"),
622
+ "test_tenant": ("python", "tenant_id"),
623
+ },
624
+ ```
625
+
626
+ ### [High] TG-AUTH-004 - Insecure Session Cookie Configuration
627
+ - **Finding ID:** `TG-AUTH-004-56b1c90f`
628
+ - **Location:** `harness/evaluate_portfolio_polyglot.py:96`
629
+ - **Confidence Score:** `66/100` (Medium Confidence)
630
+ - **Cluster:** `cluster-auth-bypass`
631
+ - **Description:** Decorator disabling route-level authentication or CSRF protection
632
+ ```
633
+ "expected_orm": "Django ORM",
634
+ "ecosystem": "Python",
635
+ "test_bypass": ("python", "@csrf_exempt", "auth_bypass"),
636
+ "test_tenant": ("python", "tenant"),
637
+ },
638
+ ```
639
+
640
+ ### [High] TG-AUTH-004 - Insecure Session Cookie Configuration
641
+ - **Finding ID:** `TG-AUTH-004-4a33f7e7`
642
+ - **Location:** `harness/evaluate_portfolio_polyglot.py:239`
643
+ - **Confidence Score:** `66/100` (Medium Confidence)
644
+ - **Cluster:** `cluster-auth-bypass`
645
+ - **Description:** Attribute disabling ASP.NET authentication
646
+ ```
647
+ "expected_orm": "Entity Framework Core",
648
+ "ecosystem": "C#",
649
+ "test_bypass": ("csharp", "[AllowAnonymous]", "auth_bypass"),
650
+ "test_tenant": ("csharp", ".Where(x => x.TenantId == tenantId)"),
651
+ },
652
+ ```
653
+
654
+ ### [High] TG-AUTH-004 - Insecure Session Cookie Configuration
655
+ - **Finding ID:** `TG-AUTH-004-95eb27cd`
656
+ - **Location:** `harness/evaluate_portfolio_polyglot.py:876`
657
+ - **Confidence Score:** `66/100` (Medium Confidence)
658
+ - **Cluster:** `cluster-auth-bypass`
659
+ - **Description:** Attribute disabling ASP.NET authentication
660
+ ```
661
+ | **4. 5-Factor Confidence Scorer** | 100% | Applied objective $0–100$ scoring with memory modifiers and false positive deductions. |
662
+ | **5. Adaptive Security Memory Engine** | 100% | Isolated memory workspace successfully recorded events and verified context cards $\le 2,000$ tokens. |
663
+ | **6. Polyglot Diff Guard** | 100% | Intercepted Go `InsecureSkipVerify`, Java `csrf().disable()`, C# `[AllowAnonymous]`, PHP `CURLOPT_SSL_VERIFYPEER`, Rust `unsafe {`, and tenant stripping. |
664
+ | **7. Governed Remediation (Ponytail)** | 100% | Enforced patch churn limits ($\le 35$ additions, $\le 25$ deletions) and pre-apply snapshot generation. |
665
+ | **8. Visual HTML Dashboard** | 100% | Generated self-contained, air-gapped dark-mode visual report with SVG circular gauge. |
666
+ ```
667
+
668
+ ### [High] TG-AUTH-004 - Insecure Session Cookie Configuration
669
+ - **Finding ID:** `TG-AUTH-004-e838c41c`
670
+ - **Location:** `harness/validate_v1_3_0_polyglot.py:18`
671
+ - **Confidence Score:** `66/100` (Medium Confidence)
672
+ - **Cluster:** `cluster-auth-bypass`
673
+ - **Description:** Attribute disabling ASP.NET authentication
674
+ ```
675
+ - Go (InsecureSkipVerify: true)
676
+ - Java (csrf().disable())
677
+ - C# ([AllowAnonymous])
678
+ - PHP (CURLOPT_SSL_VERIFYPEER => false)
679
+ - Rust (unsafe { ... })
680
+ ```
681
+
682
+ ### [High] TG-AUTH-004 - Insecure Session Cookie Configuration
683
+ - **Finding ID:** `TG-AUTH-004-5c78d750`
684
+ - **Location:** `harness/validate_v1_3_0_polyglot.py:204`
685
+ - **Confidence Score:** `66/100` (Medium Confidence)
686
+ - **Cluster:** `cluster-auth-bypass`
687
+ - **Description:** Attribute disabling ASP.NET authentication
688
+ ```
689
+ +++ b/UsersController.cs
690
+ @@ -15,3 +15,4 @@
691
+ + [AllowAnonymous]
692
+ + public IActionResult GetFinancialData() {
693
+ """
694
+ ```
695
+
696
+ ### [High] TG-AUTH-004 - Insecure Session Cookie Configuration
697
+ - **Finding ID:** `TG-AUTH-004-0d028be7`
698
+ - **Location:** `harness/validate_v1_3_0_polyglot.py:208`
699
+ - **Confidence Score:** `66/100` (Medium Confidence)
700
+ - **Cluster:** `cluster-auth-bypass`
701
+ - **Description:** Attribute disabling ASP.NET authentication
702
+ ```
703
+ """
704
+ viol_cs = diff_guard.check_diff_content(diff_cs, "UsersController.cs")
705
+ assert len(viol_cs) >= 1, "Failed to catch C# [AllowAnonymous]"
706
+ print(" [PASS] Caught C# ASP.NET [AllowAnonymous] bypass")
707
+
708
+ ```
709
+
710
+ ### [High] TG-AUTH-004 - Insecure Session Cookie Configuration
711
+ - **Finding ID:** `TG-AUTH-004-3ae1d9c1`
712
+ - **Location:** `harness/validate_v1_3_0_polyglot.py:209`
713
+ - **Confidence Score:** `66/100` (Medium Confidence)
714
+ - **Cluster:** `cluster-auth-bypass`
715
+ - **Description:** Attribute disabling ASP.NET authentication
716
+ ```
717
+ viol_cs = diff_guard.check_diff_content(diff_cs, "UsersController.cs")
718
+ assert len(viol_cs) >= 1, "Failed to catch C# [AllowAnonymous]"
719
+ print(" [PASS] Caught C# ASP.NET [AllowAnonymous] bypass")
720
+
721
+ # PHP CURLOPT_SSL_VERIFYPEER bypass
722
+ ```
723
+
724
+ ### [High] TG-AUTH-004 - Insecure Session Cookie Configuration
725
+ - **Finding ID:** `TG-AUTH-004-ea07db54`
726
+ - **Location:** `harness/validate_v1_3_0_polyglot.py:193`
727
+ - **Confidence Score:** `66/100` (Medium Confidence)
728
+ - **Cluster:** `cluster-auth-bypass`
729
+ - **Description:** Spring Security CSRF protection explicitly disabled
730
+ ```
731
+ +++ b/SecurityConfig.java
732
+ @@ -20,3 +20,4 @@
733
+ + http.csrf().disable();
734
+ """
735
+ viol_java = diff_guard.check_diff_content(diff_java, "SecurityConfig.java")
736
+ ```
737
+
738
+ ### [High] TG-RATE-001 - Unlimited Authentication Endpoint
739
+ - **Finding ID:** `TG-RATE-001-758a7750`
740
+ - **Location:** `harness/runner.py:575`
741
+ - **Confidence Score:** `65/100` (Medium Confidence)
742
+ - **Cluster:** `cluster-rate-limiting`
743
+ - **Description:** Authentication POST endpoint defined without rate-limiting middleware
744
+ ```
745
+ "line_number": 25,
746
+ "description": "Unprotected auth route lacking rate limiting.",
747
+ "snippet": "app.post('/login', async (req, res) => {})",
748
+ "confidence_score": 85,
749
+ "confidence_band": "High Confidence"
750
+ ```
751
+
752
+ ### [High] TG-DIFF-003 - Unintentional Removal of Tenant Filter in Patch Deletions
753
+ - **Finding ID:** `TG-DIFF-003-3d00a189`
754
+ - **Location:** `harness/validate_v0_6_2_modern_stacks.py:262`
755
+ - **Confidence Score:** `54/100` (Medium Confidence)
756
+ - **Cluster:** `cluster-tenant-isolation`
757
+ - **Description:** Removal of tenant isolation boundary in patch deletion
758
+ ```
759
+ +++ b/queries.py
760
+ @@ -7,1 +7,1 @@
761
+ - stmt = select(Account).where(Account.id == account_id)
762
+ + stmt = select(Account).where(Account.id == account_id, Account.tenant_id == tenant_id)
763
+ """,
764
+ ```
765
+
766
+ ### [High] TG-INPUT-005 - Unsafe Template Rendering & Disabled Autoescaping
767
+ - **Finding ID:** `TG-INPUT-005-7f81ea7f`
768
+ - **Location:** `harness/validate_qa_v0_6_0.py:177`
769
+ - **Confidence Score:** `52/100` (Medium Confidence)
770
+ - **Cluster:** `cluster-injection`
771
+ - **Description:** Flask render_template_string rendering untrusted input
772
+ ```
773
+ "flask-app": {
774
+ "vulnerable": {
775
+ "app.py": 'from flask import Flask, request, render_template_string\nimport os\n\napp = Flask(__name__)\n\n@app.route("/greet")\ndef greet():\n name = request.args.get("name", "Guest")\n # SSTI: Unescaped string formatting in template\n return render_template_string(f"Hello {name}")\n\n@app.route("/upload", methods=["POST"])\ndef upload():\n f = request.files["file"]\n # Path Traversal in filename\n f.save(os.path.join("/var/uploads", f.filename))\n return "Saved"\n'
776
+ },
777
+ "hardened": {
778
+ ```
779
+
780
+ ### [High] TG-INPUT-005 - Unsafe Template Rendering & Disabled Autoescaping
781
+ - **Finding ID:** `TG-INPUT-005-d5aaebe0`
782
+ - **Location:** `harness/validate_qa_v0_6_0.py:190`
783
+ - **Confidence Score:** `52/100` (Medium Confidence)
784
+ - **Cluster:** `cluster-injection`
785
+ - **Description:** Flask render_template_string rendering untrusted input
786
+ ```
787
+ "confidence_band": "Confirmed",
788
+ "target": {"file_path": "app.py", "line_start": 10, "line_end": 10},
789
+ "evidence": {"code_snippet": 'return render_template_string(f"Hello {name}")'},
790
+ "what_is_wrong": "User input formatted directly into template string.",
791
+ "what_should_change": "Render static template file with contextual autoescaping.",
792
+ ```
793
+
794
+ ### [High] TG-INPUT-005 - Unsafe Template Rendering & Disabled Autoescaping
795
+ - **Finding ID:** `TG-INPUT-005-e0ffb03b`
796
+ - **Location:** `harness/validate_qa_v0_6_0.py:193`
797
+ - **Confidence Score:** `52/100` (Medium Confidence)
798
+ - **Cluster:** `cluster-injection`
799
+ - **Description:** Flask render_template_string rendering untrusted input
800
+ ```
801
+ "what_is_wrong": "User input formatted directly into template string.",
802
+ "what_should_change": "Render static template file with contextual autoescaping.",
803
+ "proposed_diff": "--- a/app.py\n+++ b/app.py\n@@ -10,1 +10,1 @@\n-return render_template_string(f\"Hello {name}\")\n+return render_template(\"greet.html\", name=name)\n",
804
+ "verification_steps": "Send name={{7*7}} and verify output contains literal {{7*7}} instead of 49.",
805
+ },
806
+ ```
807
+
808
+ ### [High] TG-INPUT-005 - Unsafe Template Rendering & Disabled Autoescaping
809
+ - **Finding ID:** `TG-INPUT-005-0d595acd`
810
+ - **Location:** `harness/master_validation.py:314`
811
+ - **Confidence Score:** `49/100` (Needs Review)
812
+ - **Cluster:** `cluster-injection`
813
+ - **Description:** Flask render_template_string rendering untrusted input
814
+ ```
815
+ "severity": SeverityLevel.HIGH,
816
+ "path": "rules/TG-INPUT-005-unsafe-template-rendering-and-escaping.md",
817
+ "vuln_sample": "return render_template_string(f'<h1>Hello {name}</h1>')",
818
+ "hard_sample": "return render_template('hello.html', name=name)",
819
+ "remediation": "Pass inputs as context variables in autoescaped template files or use Django's format_html() to safely construct HTML wrappers.",
820
+ ```
821
+
822
+ ### [High] TG-INPUT-005 - Unsafe Template Rendering & Disabled Autoescaping
823
+ - **Finding ID:** `TG-INPUT-005-d7ef73f1`
824
+ - **Location:** `harness/validate_e2e.py:457`
825
+ - **Confidence Score:** `49/100` (Needs Review)
826
+ - **Cluster:** `cluster-injection`
827
+ - **Description:** Flask render_template_string rendering untrusted input
828
+ ```
829
+ "",
830
+ "- **`TG-AUTH-008` (Untrusted Role/Tenant Header Injection):** Verified detection on client headers (`X-User-Role`, `X-Tenant-ID`) and verified FastAPI/DRF JWT token extraction remediations.",
831
+ "- **`TG-INPUT-005` (Unsafe Template Rendering & Disabled Autoescaping):** Verified detection on `mark_safe()`, `| safe`, and `render_template_string()`; verified Jinja2 context variable autoescaping and `format_html()` remediations.",
832
+ "- **`TG-INPUT-006` (Path Traversal & Unsafe Upload Storage):** Verified detection on `os.path.join(UPLOAD_DIR, filename)`; verified `secure_filename()` + UUID storage remediations.",
833
+ "- **`TG-DB-004` (Missing Tenant Query Isolation):** Verified detection on unscoped primary key queries; verified SQLAlchemy composite tenant filters and DRF ViewSet `get_queryset()` tenant isolation.",
834
+ ```
835
+
836
+ ### [High] TG-INPUT-005 - Unsafe Template Rendering & Disabled Autoescaping
837
+ - **Finding ID:** `TG-INPUT-005-95cb57ba`
838
+ - **Location:** `harness/engine/fixture_manager.py:176`
839
+ - **Confidence Score:** `46/100` (Needs Review)
840
+ - **Cluster:** `cluster-injection`
841
+ - **Description:** Flask render_template_string rendering untrusted input
842
+ ```
843
+ vulnerable_variant=FixtureVariant(
844
+ relative_path="examples/python/flask-vuln",
845
+ code_pattern="render_template_string(f'<h1>Hello {name}</h1>')",
846
+ expected_findings_count=1,
847
+ ),
848
+ ```
849
+
850
+ ### [Medium] TG-PLATFORM-003 - Production Stack Trace Exposure
851
+ - **Finding ID:** `TG-PLATFORM-003-69f083d6`
852
+ - **Location:** `harness/runner.py:392`
853
+ - **Confidence Score:** `56/100` (Medium Confidence)
854
+ - **Cluster:** `cluster-platform`
855
+ - **Description:** Django DEBUG mode enabled in configuration
856
+ ```
857
+ type=EvidenceType.SOURCE,
858
+ location="settings.py:10",
859
+ raw_snippet="DEBUG = True\nSECRET_KEY = 'sk_live_secret_key_12345'",
860
+ rationale="Production debug mode exposure and hardcoded secret.",
861
+ confidence_level=ConfidenceBand.CONFIRMED,
862
+ ```
863
+
864
+ ### [Medium] TG-PLATFORM-003 - Production Stack Trace Exposure
865
+ - **Finding ID:** `TG-PLATFORM-003-6f253f06`
866
+ - **Location:** `harness/runner.py:405`
867
+ - **Confidence Score:** `56/100` (Medium Confidence)
868
+ - **Cluster:** `cluster-platform`
869
+ - **Description:** Django DEBUG mode enabled in configuration
870
+ ```
871
+ prov = ProvenanceChain(
872
+ discovery_module="rules/TG-PLATFORM-003-production-stack-trace-exposure.md",
873
+ triggering_input="DEBUG = True assignment in settings.py",
874
+ evidence_collected=["settings.py:10"],
875
+ decision_path=["Loaded Django settings", "Found DEBUG enabled"],
876
+ ```
877
+
878
+ ### [Medium] TG-PLATFORM-003 - Production Stack Trace Exposure
879
+ - **Finding ID:** `TG-PLATFORM-003-fbe8ec66`
880
+ - **Location:** `harness/runner.py:416`
881
+ - **Confidence Score:** `56/100` (Medium Confidence)
882
+ - **Cluster:** `cluster-platform`
883
+ - **Description:** Django DEBUG mode enabled in configuration
884
+ ```
885
+ framework_pattern=FrameworkPattern(
886
+ framework="Django",
887
+ unsafe_snippet="DEBUG = True",
888
+ safe_snippet="DEBUG = False",
889
+ ),
890
+ ```
891
+
892
+ ### [Medium] TG-PLATFORM-003 - Production Stack Trace Exposure
893
+ - **Finding ID:** `TG-PLATFORM-003-153d982f`
894
+ - **Location:** `harness/validate_qa_v0_6_0.py:64`
895
+ - **Confidence Score:** `52/100` (Medium Confidence)
896
+ - **Cluster:** `cluster-platform`
897
+ - **Description:** Django DEBUG mode enabled in configuration
898
+ ```
899
+ "tiny-repo": {
900
+ "vulnerable": {
901
+ "app.py": 'DEBUG = True\nSECRET_KEY = "sk_live_1234567890"\n\ndef index():\n return "Welcome"\n'
902
+ },
903
+ "hardened": {
904
+ ```
905
+
906
+ ### [Medium] TG-PLATFORM-003 - Production Stack Trace Exposure
907
+ - **Finding ID:** `TG-PLATFORM-003-21644311`
908
+ - **Location:** `harness/validate_qa_v0_6_0.py:77`
909
+ - **Confidence Score:** `52/100` (Medium Confidence)
910
+ - **Cluster:** `cluster-platform`
911
+ - **Description:** Django DEBUG mode enabled in configuration
912
+ ```
913
+ "confidence_band": "Confirmed",
914
+ "target": {"file_path": "app.py", "line_start": 1, "line_end": 1},
915
+ "evidence": {"code_snippet": "DEBUG = True"},
916
+ "what_is_wrong": "DEBUG is statically enabled.",
917
+ "what_should_change": "Load DEBUG from environment variables.",
918
+ ```
919
+
920
+ ### [Medium] TG-PLATFORM-003 - Production Stack Trace Exposure
921
+ - **Finding ID:** `TG-PLATFORM-003-21b8a588`
922
+ - **Location:** `harness/validate_qa_v0_6_0.py:80`
923
+ - **Confidence Score:** `52/100` (Medium Confidence)
924
+ - **Cluster:** `cluster-platform`
925
+ - **Description:** Django DEBUG mode enabled in configuration
926
+ ```
927
+ "what_is_wrong": "DEBUG is statically enabled.",
928
+ "what_should_change": "Load DEBUG from environment variables.",
929
+ "proposed_diff": "--- a/app.py\n+++ b/app.py\n@@ -1,1 +1,2 @@\n-DEBUG = True\n+import os\n+DEBUG = os.getenv('DEBUG', 'False').lower() == 'true'\n",
930
+ "verification_steps": "Check DEBUG setting resolution in production.",
931
+ },
932
+ ```
933
+
934
+ ### [Low] TG-DB-004 - Missing Tenant Query Isolation in Multi-Tenant Models
935
+ - **Finding ID:** `TG-DB-004-6a739666`
936
+ - **Location:** `tests/test_v0_6_0_governed_remediation.py:79`
937
+ - **Confidence Score:** `24/100` (Needs Review)
938
+ - **Cluster:** `cluster-tenant-isolation`
939
+ - **Description:** Django ORM .get(id=...) query lacking explicit tenant scope filter
940
+ ```
941
+ def get_invoice(request, invoice_id):
942
+ # Fetch invoice directly without tenant filter
943
+ invoice = Invoice.objects.get(id=invoice_id)
944
+ return JsonResponse({"id": invoice.id})
945
+ """
946
+ ```
947
+
948
+ ### [Low] TG-DB-004 - Missing Tenant Query Isolation in Multi-Tenant Models
949
+ - **Finding ID:** `TG-DB-004-fe2c60e3`
950
+ - **Location:** `tests/test_v0_6_0_governed_remediation.py:86`
951
+ - **Confidence Score:** `24/100` (Needs Review)
952
+ - **Cluster:** `cluster-tenant-isolation`
953
+ - **Description:** Django ORM .get(id=...) query lacking explicit tenant scope filter
954
+ ```
955
+ # Lines shifted down by 10 lines
956
+ def get_invoice(request, invoice_id):
957
+ invoice = Invoice.objects.get(id=invoice_id)
958
+ return JsonResponse({"id": invoice.id})
959
+ """
960
+ ```