@oculum/scanner 1.0.13 → 1.0.15

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 (1328) hide show
  1. package/dist/detect/ai-code/index.d.ts +6 -11
  2. package/dist/detect/ai-code/index.d.ts.map +1 -1
  3. package/dist/detect/ai-code/index.js +6 -24
  4. package/dist/detect/ai-code/index.js.map +1 -1
  5. package/dist/detect/ast-rules/agent-tools-ast.d.ts +14 -0
  6. package/dist/detect/ast-rules/agent-tools-ast.d.ts.map +1 -0
  7. package/dist/detect/ast-rules/agent-tools-ast.js +809 -0
  8. package/dist/detect/ast-rules/agent-tools-ast.js.map +1 -0
  9. package/dist/detect/ast-rules/ai-fingerprinting-ast.d.ts +14 -0
  10. package/dist/detect/ast-rules/ai-fingerprinting-ast.d.ts.map +1 -0
  11. package/dist/detect/ast-rules/ai-fingerprinting-ast.js +344 -0
  12. package/dist/detect/ast-rules/ai-fingerprinting-ast.js.map +1 -0
  13. package/dist/detect/ast-rules/auth-patterns-ast.d.ts +14 -0
  14. package/dist/detect/ast-rules/auth-patterns-ast.d.ts.map +1 -0
  15. package/dist/detect/ast-rules/auth-patterns-ast.js +280 -0
  16. package/dist/detect/ast-rules/auth-patterns-ast.js.map +1 -0
  17. package/dist/detect/ast-rules/byok-ast.d.ts +13 -0
  18. package/dist/detect/ast-rules/byok-ast.d.ts.map +1 -0
  19. package/dist/detect/ast-rules/byok-ast.js +180 -0
  20. package/dist/detect/ast-rules/byok-ast.js.map +1 -0
  21. package/dist/detect/ast-rules/child-process-ast.d.ts +13 -0
  22. package/dist/detect/ast-rules/child-process-ast.d.ts.map +1 -0
  23. package/dist/detect/ast-rules/child-process-ast.js +252 -0
  24. package/dist/detect/ast-rules/child-process-ast.js.map +1 -0
  25. package/dist/detect/ast-rules/dangerous-eval-ast.d.ts +13 -0
  26. package/dist/detect/ast-rules/dangerous-eval-ast.d.ts.map +1 -0
  27. package/dist/detect/ast-rules/dangerous-eval-ast.js +218 -0
  28. package/dist/detect/ast-rules/dangerous-eval-ast.js.map +1 -0
  29. package/dist/detect/ast-rules/data-exposure-ast.d.ts +13 -0
  30. package/dist/detect/ast-rules/data-exposure-ast.d.ts.map +1 -0
  31. package/dist/detect/ast-rules/data-exposure-ast.js +158 -0
  32. package/dist/detect/ast-rules/data-exposure-ast.js.map +1 -0
  33. package/dist/detect/ast-rules/dom-xss-ast.d.ts +14 -0
  34. package/dist/detect/ast-rules/dom-xss-ast.d.ts.map +1 -0
  35. package/dist/detect/ast-rules/dom-xss-ast.js +217 -0
  36. package/dist/detect/ast-rules/dom-xss-ast.js.map +1 -0
  37. package/dist/detect/ast-rules/endpoint-protection-ast.d.ts +13 -0
  38. package/dist/detect/ast-rules/endpoint-protection-ast.d.ts.map +1 -0
  39. package/dist/detect/ast-rules/endpoint-protection-ast.js +228 -0
  40. package/dist/detect/ast-rules/endpoint-protection-ast.js.map +1 -0
  41. package/dist/detect/ast-rules/entropy-ast.d.ts +17 -0
  42. package/dist/detect/ast-rules/entropy-ast.d.ts.map +1 -0
  43. package/dist/detect/ast-rules/entropy-ast.js +265 -0
  44. package/dist/detect/ast-rules/entropy-ast.js.map +1 -0
  45. package/dist/detect/ast-rules/flask-debug-ast.d.ts +10 -0
  46. package/dist/detect/ast-rules/flask-debug-ast.d.ts.map +1 -0
  47. package/dist/detect/ast-rules/flask-debug-ast.js +125 -0
  48. package/dist/detect/ast-rules/flask-debug-ast.js.map +1 -0
  49. package/dist/detect/ast-rules/framework-checks-ast.d.ts +13 -0
  50. package/dist/detect/ast-rules/framework-checks-ast.d.ts.map +1 -0
  51. package/dist/detect/ast-rules/framework-checks-ast.js +185 -0
  52. package/dist/detect/ast-rules/framework-checks-ast.js.map +1 -0
  53. package/dist/detect/ast-rules/helpers/call-analysis.d.ts +62 -0
  54. package/dist/detect/ast-rules/helpers/call-analysis.d.ts.map +1 -0
  55. package/dist/detect/ast-rules/helpers/call-analysis.js +217 -0
  56. package/dist/detect/ast-rules/helpers/call-analysis.js.map +1 -0
  57. package/dist/detect/ast-rules/helpers/context-detection.d.ts +33 -0
  58. package/dist/detect/ast-rules/helpers/context-detection.d.ts.map +1 -0
  59. package/dist/detect/ast-rules/helpers/context-detection.js +256 -0
  60. package/dist/detect/ast-rules/helpers/context-detection.js.map +1 -0
  61. package/dist/detect/ast-rules/helpers/control-flow.d.ts +40 -0
  62. package/dist/detect/ast-rules/helpers/control-flow.d.ts.map +1 -0
  63. package/dist/detect/ast-rules/helpers/control-flow.js +174 -0
  64. package/dist/detect/ast-rules/helpers/control-flow.js.map +1 -0
  65. package/dist/detect/ast-rules/helpers/import-analysis.d.ts +43 -0
  66. package/dist/detect/ast-rules/helpers/import-analysis.d.ts.map +1 -0
  67. package/dist/detect/ast-rules/helpers/import-analysis.js +149 -0
  68. package/dist/detect/ast-rules/helpers/import-analysis.js.map +1 -0
  69. package/dist/detect/ast-rules/helpers/index.d.ts +16 -0
  70. package/dist/detect/ast-rules/helpers/index.d.ts.map +1 -0
  71. package/dist/detect/ast-rules/helpers/index.js +112 -0
  72. package/dist/detect/ast-rules/helpers/index.js.map +1 -0
  73. package/dist/detect/ast-rules/helpers/python-helpers.d.ts +215 -0
  74. package/dist/detect/ast-rules/helpers/python-helpers.d.ts.map +1 -0
  75. package/dist/detect/ast-rules/helpers/python-helpers.js +935 -0
  76. package/dist/detect/ast-rules/helpers/python-helpers.js.map +1 -0
  77. package/dist/detect/ast-rules/helpers/scope-analysis.d.ts +50 -0
  78. package/dist/detect/ast-rules/helpers/scope-analysis.d.ts.map +1 -0
  79. package/dist/detect/ast-rules/helpers/scope-analysis.js +194 -0
  80. package/dist/detect/ast-rules/helpers/scope-analysis.js.map +1 -0
  81. package/dist/detect/ast-rules/helpers/string-analysis.d.ts +57 -0
  82. package/dist/detect/ast-rules/helpers/string-analysis.d.ts.map +1 -0
  83. package/dist/detect/ast-rules/helpers/string-analysis.js +184 -0
  84. package/dist/detect/ast-rules/helpers/string-analysis.js.map +1 -0
  85. package/dist/detect/ast-rules/helpers/type-extraction.d.ts +44 -0
  86. package/dist/detect/ast-rules/helpers/type-extraction.d.ts.map +1 -0
  87. package/dist/detect/ast-rules/helpers/type-extraction.js +125 -0
  88. package/dist/detect/ast-rules/helpers/type-extraction.js.map +1 -0
  89. package/dist/detect/ast-rules/helpers/user-input.d.ts +35 -0
  90. package/dist/detect/ast-rules/helpers/user-input.d.ts.map +1 -0
  91. package/dist/detect/ast-rules/helpers/user-input.js +243 -0
  92. package/dist/detect/ast-rules/helpers/user-input.js.map +1 -0
  93. package/dist/detect/ast-rules/index.d.ts +112 -0
  94. package/dist/detect/ast-rules/index.d.ts.map +1 -0
  95. package/dist/detect/ast-rules/index.js +232 -0
  96. package/dist/detect/ast-rules/index.js.map +1 -0
  97. package/dist/detect/ast-rules/json-parse-ast.d.ts +13 -0
  98. package/dist/detect/ast-rules/json-parse-ast.d.ts.map +1 -0
  99. package/dist/detect/ast-rules/json-parse-ast.js +143 -0
  100. package/dist/detect/ast-rules/json-parse-ast.js.map +1 -0
  101. package/dist/detect/ast-rules/log-injection-ast.d.ts +14 -0
  102. package/dist/detect/ast-rules/log-injection-ast.d.ts.map +1 -0
  103. package/dist/detect/ast-rules/log-injection-ast.js +235 -0
  104. package/dist/detect/ast-rules/log-injection-ast.js.map +1 -0
  105. package/dist/detect/ast-rules/logic-gates-ast.d.ts +14 -0
  106. package/dist/detect/ast-rules/logic-gates-ast.d.ts.map +1 -0
  107. package/dist/detect/ast-rules/logic-gates-ast.js +312 -0
  108. package/dist/detect/ast-rules/logic-gates-ast.js.map +1 -0
  109. package/dist/detect/ast-rules/mcp-security-ast.d.ts +14 -0
  110. package/dist/detect/ast-rules/mcp-security-ast.d.ts.map +1 -0
  111. package/dist/detect/ast-rules/mcp-security-ast.js +755 -0
  112. package/dist/detect/ast-rules/mcp-security-ast.js.map +1 -0
  113. package/dist/detect/ast-rules/model-supply-chain-ast.d.ts +13 -0
  114. package/dist/detect/ast-rules/model-supply-chain-ast.d.ts.map +1 -0
  115. package/dist/detect/ast-rules/model-supply-chain-ast.js +188 -0
  116. package/dist/detect/ast-rules/model-supply-chain-ast.js.map +1 -0
  117. package/dist/detect/ast-rules/package-hallucination-ast.d.ts +13 -0
  118. package/dist/detect/ast-rules/package-hallucination-ast.d.ts.map +1 -0
  119. package/dist/detect/ast-rules/package-hallucination-ast.js +607 -0
  120. package/dist/detect/ast-rules/package-hallucination-ast.js.map +1 -0
  121. package/dist/detect/ast-rules/prompt-hygiene-ast.d.ts +15 -0
  122. package/dist/detect/ast-rules/prompt-hygiene-ast.d.ts.map +1 -0
  123. package/dist/detect/ast-rules/prompt-hygiene-ast.js +332 -0
  124. package/dist/detect/ast-rules/prompt-hygiene-ast.js.map +1 -0
  125. package/dist/detect/ast-rules/rag-safety-ast.d.ts +18 -0
  126. package/dist/detect/ast-rules/rag-safety-ast.d.ts.map +1 -0
  127. package/dist/detect/ast-rules/rag-safety-ast.js +640 -0
  128. package/dist/detect/ast-rules/rag-safety-ast.js.map +1 -0
  129. package/dist/detect/ast-rules/request-validation-ast.d.ts +13 -0
  130. package/dist/detect/ast-rules/request-validation-ast.d.ts.map +1 -0
  131. package/dist/detect/ast-rules/request-validation-ast.js +116 -0
  132. package/dist/detect/ast-rules/request-validation-ast.js.map +1 -0
  133. package/dist/detect/ast-rules/risky-imports-ast.d.ts +14 -0
  134. package/dist/detect/ast-rules/risky-imports-ast.d.ts.map +1 -0
  135. package/dist/detect/ast-rules/risky-imports-ast.js +114 -0
  136. package/dist/detect/ast-rules/risky-imports-ast.js.map +1 -0
  137. package/dist/detect/ast-rules/schema-validation-ast.d.ts +14 -0
  138. package/dist/detect/ast-rules/schema-validation-ast.d.ts.map +1 -0
  139. package/dist/detect/ast-rules/schema-validation-ast.js +233 -0
  140. package/dist/detect/ast-rules/schema-validation-ast.js.map +1 -0
  141. package/dist/detect/ast-rules/secret-patterns-ast.d.ts +17 -0
  142. package/dist/detect/ast-rules/secret-patterns-ast.d.ts.map +1 -0
  143. package/dist/detect/ast-rules/secret-patterns-ast.js +199 -0
  144. package/dist/detect/ast-rules/secret-patterns-ast.js.map +1 -0
  145. package/dist/detect/ast-rules/security-headers-ast.d.ts +14 -0
  146. package/dist/detect/ast-rules/security-headers-ast.d.ts.map +1 -0
  147. package/dist/detect/ast-rules/security-headers-ast.js +187 -0
  148. package/dist/detect/ast-rules/security-headers-ast.js.map +1 -0
  149. package/dist/detect/ast-rules/sql-injection-ast.d.ts +17 -0
  150. package/dist/detect/ast-rules/sql-injection-ast.d.ts.map +1 -0
  151. package/dist/detect/ast-rules/sql-injection-ast.js +497 -0
  152. package/dist/detect/ast-rules/sql-injection-ast.js.map +1 -0
  153. package/dist/detect/ast-rules/ssrf-ast.d.ts +14 -0
  154. package/dist/detect/ast-rules/ssrf-ast.d.ts.map +1 -0
  155. package/dist/detect/ast-rules/ssrf-ast.js +573 -0
  156. package/dist/detect/ast-rules/ssrf-ast.js.map +1 -0
  157. package/dist/detect/ast-rules/taint-fix-templates.d.ts +18 -0
  158. package/dist/detect/ast-rules/taint-fix-templates.d.ts.map +1 -0
  159. package/dist/detect/ast-rules/taint-fix-templates.js +92 -0
  160. package/dist/detect/ast-rules/taint-fix-templates.js.map +1 -0
  161. package/dist/detect/ast-rules/taint-flow-ast.d.ts +24 -0
  162. package/dist/detect/ast-rules/taint-flow-ast.d.ts.map +1 -0
  163. package/dist/detect/ast-rules/taint-flow-ast.js +340 -0
  164. package/dist/detect/ast-rules/taint-flow-ast.js.map +1 -0
  165. package/dist/detect/ast-rules/variables-ast.d.ts +24 -0
  166. package/dist/detect/ast-rules/variables-ast.d.ts.map +1 -0
  167. package/dist/detect/ast-rules/variables-ast.js +362 -0
  168. package/dist/detect/ast-rules/variables-ast.js.map +1 -0
  169. package/dist/detect/ast-rules/weak-crypto-ast.d.ts +15 -0
  170. package/dist/detect/ast-rules/weak-crypto-ast.d.ts.map +1 -0
  171. package/dist/detect/ast-rules/weak-crypto-ast.js +406 -0
  172. package/dist/detect/ast-rules/weak-crypto-ast.js.map +1 -0
  173. package/dist/detect/ast-rules/xxe-ast.d.ts +13 -0
  174. package/dist/detect/ast-rules/xxe-ast.d.ts.map +1 -0
  175. package/dist/detect/ast-rules/xxe-ast.js +157 -0
  176. package/dist/detect/ast-rules/xxe-ast.js.map +1 -0
  177. package/dist/detect/config/agent-skill-injection.d.ts.map +1 -1
  178. package/dist/detect/config/agent-skill-injection.js +2 -24
  179. package/dist/detect/config/agent-skill-injection.js.map +1 -1
  180. package/dist/detect/config/index.d.ts +1 -0
  181. package/dist/detect/config/index.d.ts.map +1 -1
  182. package/dist/detect/config/index.js +3 -1
  183. package/dist/detect/config/index.js.map +1 -1
  184. package/dist/detect/config/osv-check.d.ts.map +1 -1
  185. package/dist/detect/config/osv-check.js +6 -1
  186. package/dist/detect/config/osv-check.js.map +1 -1
  187. package/dist/detect/config/package-check.d.ts.map +1 -1
  188. package/dist/detect/config/package-check.js +6 -1
  189. package/dist/detect/config/package-check.js.map +1 -1
  190. package/dist/detect/config/rules-file-backdoor.d.ts +36 -0
  191. package/dist/detect/config/rules-file-backdoor.d.ts.map +1 -0
  192. package/dist/detect/config/rules-file-backdoor.js +379 -0
  193. package/dist/detect/config/rules-file-backdoor.js.map +1 -0
  194. package/dist/detect/index.d.ts +43 -6
  195. package/dist/detect/index.d.ts.map +1 -1
  196. package/dist/detect/index.js +70 -7
  197. package/dist/detect/index.js.map +1 -1
  198. package/dist/detect/secrets/config-audit.d.ts +5 -0
  199. package/dist/detect/secrets/config-audit.d.ts.map +1 -1
  200. package/dist/detect/secrets/config-audit.js +131 -3
  201. package/dist/detect/secrets/config-audit.js.map +1 -1
  202. package/dist/detect/secrets/entropy.d.ts.map +1 -1
  203. package/dist/detect/secrets/entropy.js +180 -0
  204. package/dist/detect/secrets/entropy.js.map +1 -1
  205. package/dist/detect/secrets/index.d.ts +0 -2
  206. package/dist/detect/secrets/index.d.ts.map +1 -1
  207. package/dist/detect/secrets/index.js +7 -17
  208. package/dist/detect/secrets/index.js.map +1 -1
  209. package/dist/detect/structural/index.d.ts +15 -28
  210. package/dist/detect/structural/index.d.ts.map +1 -1
  211. package/dist/detect/structural/index.js +20 -497
  212. package/dist/detect/structural/index.js.map +1 -1
  213. package/dist/index.d.ts +3 -0
  214. package/dist/index.d.ts.map +1 -1
  215. package/dist/index.js +9 -1
  216. package/dist/index.js.map +1 -1
  217. package/dist/model/auth-helper-detector.d.ts.map +1 -1
  218. package/dist/model/auth-helper-detector.js +2 -7
  219. package/dist/model/auth-helper-detector.js.map +1 -1
  220. package/dist/model/import-resolver.d.ts.map +1 -1
  221. package/dist/model/import-resolver.js +94 -0
  222. package/dist/model/import-resolver.js.map +1 -1
  223. package/dist/model/imported-auth-detector.js +8 -8
  224. package/dist/model/imported-auth-detector.js.map +1 -1
  225. package/dist/model/index.d.ts +8 -0
  226. package/dist/model/index.d.ts.map +1 -1
  227. package/dist/model/index.js +198 -73
  228. package/dist/model/index.js.map +1 -1
  229. package/dist/model/module-graph.d.ts.map +1 -1
  230. package/dist/model/module-graph.js +22 -9
  231. package/dist/model/module-graph.js.map +1 -1
  232. package/dist/model/project-context.d.ts +1 -1
  233. package/dist/model/project-context.d.ts.map +1 -1
  234. package/dist/model/project-context.js +34 -0
  235. package/dist/model/project-context.js.map +1 -1
  236. package/dist/model/route-auth-resolver.d.ts.map +1 -1
  237. package/dist/model/route-auth-resolver.js +17 -2
  238. package/dist/model/route-auth-resolver.js.map +1 -1
  239. package/dist/model/route-discovery/index.js +1 -1
  240. package/dist/model/route-discovery/index.js.map +1 -1
  241. package/dist/model/route-discovery/nextjs.js +1 -1
  242. package/dist/model/route-discovery/nextjs.js.map +1 -1
  243. package/dist/model/route-discovery/python.d.ts +6 -3
  244. package/dist/model/route-discovery/python.d.ts.map +1 -1
  245. package/dist/model/route-discovery/python.js +132 -9
  246. package/dist/model/route-discovery/python.js.map +1 -1
  247. package/dist/model/route-discovery/types.d.ts +1 -1
  248. package/dist/model/route-discovery/types.d.ts.map +1 -1
  249. package/dist/model/route-discovery/utils.d.ts +8 -0
  250. package/dist/model/route-discovery/utils.d.ts.map +1 -1
  251. package/dist/model/route-discovery/utils.js +70 -0
  252. package/dist/model/route-discovery/utils.js.map +1 -1
  253. package/dist/model/taint-types.d.ts +0 -4
  254. package/dist/model/taint-types.d.ts.map +1 -1
  255. package/dist/parse/ast.d.ts +58 -0
  256. package/dist/parse/ast.d.ts.map +1 -0
  257. package/dist/parse/ast.js +230 -0
  258. package/dist/parse/ast.js.map +1 -0
  259. package/dist/parse/call-graph.d.ts +41 -0
  260. package/dist/parse/call-graph.d.ts.map +1 -0
  261. package/dist/parse/call-graph.js +386 -0
  262. package/dist/parse/call-graph.js.map +1 -0
  263. package/dist/parse/file-classifier.d.ts +11 -0
  264. package/dist/parse/file-classifier.d.ts.map +1 -1
  265. package/dist/parse/file-classifier.js +63 -15
  266. package/dist/parse/file-classifier.js.map +1 -1
  267. package/dist/parse/node-index.d.ts +32 -0
  268. package/dist/parse/node-index.d.ts.map +1 -0
  269. package/dist/parse/node-index.js +103 -0
  270. package/dist/parse/node-index.js.map +1 -0
  271. package/dist/parse/type-extractor.d.ts +50 -0
  272. package/dist/parse/type-extractor.d.ts.map +1 -0
  273. package/dist/parse/type-extractor.js +243 -0
  274. package/dist/parse/type-extractor.js.map +1 -0
  275. package/dist/pipeline/config.d.ts +10 -2
  276. package/dist/pipeline/config.d.ts.map +1 -1
  277. package/dist/pipeline/config.js.map +1 -1
  278. package/dist/pipeline/index.d.ts +3 -3
  279. package/dist/pipeline/index.d.ts.map +1 -1
  280. package/dist/pipeline/index.js +214 -65
  281. package/dist/pipeline/index.js.map +1 -1
  282. package/dist/pipeline/modes/incremental.d.ts.map +1 -1
  283. package/dist/pipeline/modes/incremental.js +2 -7
  284. package/dist/pipeline/modes/incremental.js.map +1 -1
  285. package/dist/postprocess/dedup.d.ts +5 -2
  286. package/dist/postprocess/dedup.d.ts.map +1 -1
  287. package/dist/postprocess/dedup.js +47 -16
  288. package/dist/postprocess/dedup.js.map +1 -1
  289. package/dist/report/build-result.d.ts +9 -4
  290. package/dist/report/build-result.d.ts.map +1 -1
  291. package/dist/report/build-result.js +15 -4
  292. package/dist/report/build-result.js.map +1 -1
  293. package/dist/report/formatters/cli-terminal.d.ts +1 -1
  294. package/dist/report/formatters/cli-terminal.d.ts.map +1 -1
  295. package/dist/report/formatters/cli-terminal.js +434 -231
  296. package/dist/report/formatters/cli-terminal.js.map +1 -1
  297. package/dist/report/sanitize.d.ts +10 -0
  298. package/dist/report/sanitize.d.ts.map +1 -0
  299. package/dist/report/sanitize.js +19 -0
  300. package/dist/report/sanitize.js.map +1 -0
  301. package/dist/score/adjustments.d.ts +20 -2
  302. package/dist/score/adjustments.d.ts.map +1 -1
  303. package/dist/score/adjustments.js +108 -37
  304. package/dist/score/adjustments.js.map +1 -1
  305. package/dist/score/confidence.d.ts +6 -0
  306. package/dist/score/confidence.d.ts.map +1 -1
  307. package/dist/score/confidence.js +10 -4
  308. package/dist/score/confidence.js.map +1 -1
  309. package/dist/score/evidence.d.ts +25 -0
  310. package/dist/score/evidence.d.ts.map +1 -0
  311. package/dist/score/evidence.js +51 -0
  312. package/dist/score/evidence.js.map +1 -0
  313. package/dist/score/index.d.ts +3 -1
  314. package/dist/score/index.d.ts.map +1 -1
  315. package/dist/score/index.js +25 -50
  316. package/dist/score/index.js.map +1 -1
  317. package/dist/score/types.d.ts +5 -1
  318. package/dist/score/types.d.ts.map +1 -1
  319. package/dist/shared/category-filter.d.ts.map +1 -1
  320. package/dist/shared/category-filter.js +12 -0
  321. package/dist/shared/category-filter.js.map +1 -1
  322. package/dist/shared/regex-utils.d.ts +3 -0
  323. package/dist/shared/regex-utils.d.ts.map +1 -0
  324. package/dist/shared/regex-utils.js +8 -0
  325. package/dist/shared/regex-utils.js.map +1 -0
  326. package/dist/shared/registry-clients.d.ts +7 -0
  327. package/dist/shared/registry-clients.d.ts.map +1 -1
  328. package/dist/shared/registry-clients.js +94 -17
  329. package/dist/shared/registry-clients.js.map +1 -1
  330. package/dist/shared/rules/metadata.d.ts.map +1 -1
  331. package/dist/shared/rules/metadata.js +17 -0
  332. package/dist/shared/rules/metadata.js.map +1 -1
  333. package/dist/shared/types.d.ts +60 -16
  334. package/dist/shared/types.d.ts.map +1 -1
  335. package/dist/shared/types.js +38 -21
  336. package/dist/shared/types.js.map +1 -1
  337. package/dist/taint/async-flow.d.ts +44 -0
  338. package/dist/taint/async-flow.d.ts.map +1 -0
  339. package/dist/taint/async-flow.js +271 -0
  340. package/dist/taint/async-flow.js.map +1 -0
  341. package/dist/taint/cfg-builder.d.ts +35 -0
  342. package/dist/taint/cfg-builder.d.ts.map +1 -0
  343. package/dist/taint/cfg-builder.js +980 -0
  344. package/dist/taint/cfg-builder.js.map +1 -0
  345. package/dist/taint/cfg-types.d.ts +76 -0
  346. package/dist/taint/cfg-types.d.ts.map +1 -0
  347. package/dist/taint/cfg-types.js +13 -0
  348. package/dist/taint/cfg-types.js.map +1 -0
  349. package/dist/taint/constant-propagation.d.ts +34 -0
  350. package/dist/taint/constant-propagation.d.ts.map +1 -0
  351. package/dist/taint/constant-propagation.js +164 -0
  352. package/dist/taint/constant-propagation.js.map +1 -0
  353. package/dist/taint/cross-file-analyzer.d.ts +27 -0
  354. package/dist/taint/cross-file-analyzer.d.ts.map +1 -0
  355. package/dist/taint/cross-file-analyzer.js +99 -0
  356. package/dist/taint/cross-file-analyzer.js.map +1 -0
  357. package/dist/taint/cross-file-index.d.ts +59 -0
  358. package/dist/taint/cross-file-index.d.ts.map +1 -0
  359. package/dist/taint/cross-file-index.js +183 -0
  360. package/dist/taint/cross-file-index.js.map +1 -0
  361. package/dist/taint/def-use.d.ts +27 -0
  362. package/dist/taint/def-use.d.ts.map +1 -0
  363. package/dist/taint/def-use.js +519 -0
  364. package/dist/taint/def-use.js.map +1 -0
  365. package/dist/taint/file-analysis-cache.d.ts +47 -0
  366. package/dist/taint/file-analysis-cache.d.ts.map +1 -0
  367. package/dist/taint/file-analysis-cache.js +107 -0
  368. package/dist/taint/file-analysis-cache.js.map +1 -0
  369. package/dist/taint/framework-models.d.ts +77 -0
  370. package/dist/taint/framework-models.d.ts.map +1 -0
  371. package/dist/taint/framework-models.js +258 -0
  372. package/dist/taint/framework-models.js.map +1 -0
  373. package/dist/taint/helpers.d.ts +31 -0
  374. package/dist/taint/helpers.d.ts.map +1 -0
  375. package/dist/taint/helpers.js +130 -0
  376. package/dist/taint/helpers.js.map +1 -0
  377. package/dist/taint/index.d.ts +28 -0
  378. package/dist/taint/index.d.ts.map +1 -0
  379. package/dist/taint/index.js +77 -0
  380. package/dist/taint/index.js.map +1 -0
  381. package/dist/taint/llm-registry.d.ts +47 -0
  382. package/dist/taint/llm-registry.d.ts.map +1 -0
  383. package/dist/taint/llm-registry.js +152 -0
  384. package/dist/taint/llm-registry.js.map +1 -0
  385. package/dist/taint/llm-risk-scoring.d.ts +54 -0
  386. package/dist/taint/llm-risk-scoring.d.ts.map +1 -0
  387. package/dist/taint/llm-risk-scoring.js +376 -0
  388. package/dist/taint/llm-risk-scoring.js.map +1 -0
  389. package/dist/taint/propagation-types.d.ts +104 -0
  390. package/dist/taint/propagation-types.d.ts.map +1 -0
  391. package/dist/taint/propagation-types.js +98 -0
  392. package/dist/taint/propagation-types.js.map +1 -0
  393. package/dist/taint/propagation.d.ts +111 -0
  394. package/dist/taint/propagation.d.ts.map +1 -0
  395. package/dist/taint/propagation.js +1576 -0
  396. package/dist/taint/propagation.js.map +1 -0
  397. package/dist/taint/sanitizer-registry.d.ts +26 -0
  398. package/dist/taint/sanitizer-registry.d.ts.map +1 -0
  399. package/dist/taint/sanitizer-registry.js +422 -0
  400. package/dist/taint/sanitizer-registry.js.map +1 -0
  401. package/dist/taint/sink-classifier.d.ts +27 -0
  402. package/dist/taint/sink-classifier.d.ts.map +1 -0
  403. package/dist/taint/sink-classifier.js +1166 -0
  404. package/dist/taint/sink-classifier.js.map +1 -0
  405. package/dist/taint/source-classifier.d.ts +29 -0
  406. package/dist/taint/source-classifier.d.ts.map +1 -0
  407. package/dist/taint/source-classifier.js +814 -0
  408. package/dist/taint/source-classifier.js.map +1 -0
  409. package/dist/taint/taint-analyzer.d.ts +33 -0
  410. package/dist/taint/taint-analyzer.d.ts.map +1 -0
  411. package/dist/taint/taint-analyzer.js +88 -0
  412. package/dist/taint/taint-analyzer.js.map +1 -0
  413. package/dist/taint/taint-summary.d.ts +37 -0
  414. package/dist/taint/taint-summary.d.ts.map +1 -0
  415. package/dist/taint/taint-summary.js +293 -0
  416. package/dist/taint/taint-summary.js.map +1 -0
  417. package/dist/taint/types.d.ts +47 -0
  418. package/dist/taint/types.d.ts.map +1 -0
  419. package/dist/taint/types.js +19 -0
  420. package/dist/taint/types.js.map +1 -0
  421. package/dist/tiers.d.ts +2 -2
  422. package/dist/tiers.js +1 -1
  423. package/dist/validate/clients.d.ts +2 -1
  424. package/dist/validate/clients.d.ts.map +1 -1
  425. package/dist/validate/clients.js +3 -2
  426. package/dist/validate/clients.js.map +1 -1
  427. package/dist/validate/index.d.ts +5 -6
  428. package/dist/validate/index.d.ts.map +1 -1
  429. package/dist/validate/index.js +22 -21
  430. package/dist/validate/index.js.map +1 -1
  431. package/dist/validate/prompts/modules/ai-patterns.d.ts +1 -1
  432. package/dist/validate/prompts/modules/ai-patterns.d.ts.map +1 -1
  433. package/dist/validate/prompts/modules/ai-patterns.js +16 -0
  434. package/dist/validate/prompts/modules/ai-patterns.js.map +1 -1
  435. package/dist/validate/prompts/modules/common.d.ts +1 -1
  436. package/dist/validate/prompts/modules/common.d.ts.map +1 -1
  437. package/dist/validate/prompts/modules/common.js +12 -3
  438. package/dist/validate/prompts/modules/common.js.map +1 -1
  439. package/dist/validate/providers/anthropic.d.ts +4 -4
  440. package/dist/validate/providers/anthropic.d.ts.map +1 -1
  441. package/dist/validate/providers/anthropic.js +85 -58
  442. package/dist/validate/providers/anthropic.js.map +1 -1
  443. package/dist/validate/providers/openai.d.ts +4 -4
  444. package/dist/validate/providers/openai.d.ts.map +1 -1
  445. package/dist/validate/providers/openai.js +149 -99
  446. package/dist/validate/providers/openai.js.map +1 -1
  447. package/dist/validate/request-builder.d.ts +2 -8
  448. package/dist/validate/request-builder.d.ts.map +1 -1
  449. package/dist/validate/request-builder.js +4 -34
  450. package/dist/validate/request-builder.js.map +1 -1
  451. package/dist/validate/types.d.ts +9 -0
  452. package/dist/validate/types.d.ts.map +1 -1
  453. package/dist/validate/types.js.map +1 -1
  454. package/dist/validate/utils/path-helpers.js +2 -2
  455. package/dist/validate/utils/path-helpers.js.map +1 -1
  456. package/dist/validate/utils/response-parser.d.ts +10 -0
  457. package/dist/validate/utils/response-parser.d.ts.map +1 -1
  458. package/dist/validate/utils/response-parser.js +21 -2
  459. package/dist/validate/utils/response-parser.js.map +1 -1
  460. package/dist/validate/utils/retry.d.ts.map +1 -1
  461. package/dist/validate/utils/retry.js +19 -4
  462. package/dist/validate/utils/retry.js.map +1 -1
  463. package/package.json +7 -4
  464. package/src/__tests__/benchmark/fixtures/layer2/ai-execution-sinks.ts +1 -1
  465. package/src/__tests__/benchmark/planted-benchmark.test.ts +337 -0
  466. package/src/__tests__/benchmark/utils/test-runner.ts +38 -4
  467. package/src/__tests__/category-filter.test.ts +5 -1
  468. package/src/__tests__/context-engine/route-discovery/python.test.ts +726 -0
  469. package/src/__tests__/detect/ast-rules.test.ts +1043 -0
  470. package/src/__tests__/detect/offline-mode.test.ts +147 -0
  471. package/src/__tests__/detect/postinstall-enrichment.test.ts +300 -0
  472. package/src/__tests__/detect/python-ast-rules.test.ts +569 -0
  473. package/src/__tests__/detect/python-helpers.test.ts +536 -0
  474. package/src/__tests__/detect/python-sast-rules.test.ts +453 -0
  475. package/src/__tests__/detect/rules-file-backdoor-decoders.test.ts +151 -0
  476. package/src/__tests__/detect/rules-file-backdoor.test.ts +284 -0
  477. package/src/__tests__/detect/taint-fix-templates.test.ts +150 -0
  478. package/src/__tests__/detect/taint-path-serialization.test.ts +170 -0
  479. package/src/__tests__/parse/call-graph.test.ts +300 -0
  480. package/src/__tests__/parse/python-parser.test.ts +274 -0
  481. package/src/__tests__/regression/known-false-positives.test.ts +491 -9
  482. package/src/__tests__/regression/rules-file-backdoor.test.ts +137 -0
  483. package/src/__tests__/score/adjustments.test.ts +34 -16
  484. package/src/__tests__/score/confidence.test.ts +84 -57
  485. package/src/__tests__/score/evidence-scoring.test.ts +249 -0
  486. package/src/__tests__/score/evidence.test.ts +144 -0
  487. package/src/__tests__/score/scoring-integration.test.ts +56 -34
  488. package/src/__tests__/score/taint-adjustments.test.ts +14 -228
  489. package/src/__tests__/snapshots/__snapshots__/scan-depth.test.ts.snap +65 -59
  490. package/src/__tests__/snapshots/scan-depth.test.ts +39 -7
  491. package/src/__tests__/taint/async-flow.test.ts +247 -0
  492. package/src/__tests__/taint/cfg-builder.test.ts +835 -0
  493. package/src/__tests__/taint/constant-propagation.test.ts +302 -0
  494. package/src/__tests__/taint/cross-file-index.test.ts +683 -0
  495. package/src/__tests__/taint/cross-file-integration.test.ts +275 -0
  496. package/src/__tests__/taint/cross-file-propagation.test.ts +910 -0
  497. package/src/__tests__/taint/def-use.test.ts +132 -0
  498. package/src/__tests__/taint/field-sensitive-sinks.test.ts +179 -0
  499. package/src/__tests__/taint/field-sensitivity.test.ts +342 -0
  500. package/src/__tests__/taint/file-analysis-cache.test.ts +290 -0
  501. package/src/__tests__/taint/framework-models.test.ts +227 -0
  502. package/src/__tests__/taint/llm-flow-graph.test.ts +850 -0
  503. package/src/__tests__/taint/llm-risk-scoring.test.ts +439 -0
  504. package/src/__tests__/taint/performance-parity.test.ts +315 -0
  505. package/src/__tests__/taint/propagation.test.ts +621 -0
  506. package/src/__tests__/taint/python-cross-file.test.ts +494 -0
  507. package/src/__tests__/taint/python-taint.test.ts +1344 -0
  508. package/src/__tests__/taint/sanitizer-registry.test.ts +304 -0
  509. package/src/__tests__/taint/sanitizer-regression.test.ts +111 -0
  510. package/src/__tests__/taint/sink-classifier.test.ts +537 -0
  511. package/src/__tests__/taint/source-classifier.test.ts +367 -0
  512. package/src/__tests__/taint/taint-pipeline.test.ts +418 -0
  513. package/src/__tests__/taint/taint-smoke.test.ts +400 -0
  514. package/src/__tests__/taint/taint-summary.test.ts +472 -0
  515. package/src/detect/ai-code/index.ts +6 -11
  516. package/src/detect/ast-rules/agent-tools-ast.ts +861 -0
  517. package/src/detect/ast-rules/ai-fingerprinting-ast.ts +451 -0
  518. package/src/detect/ast-rules/auth-patterns-ast.ts +304 -0
  519. package/src/detect/ast-rules/byok-ast.ts +195 -0
  520. package/src/detect/ast-rules/child-process-ast.ts +276 -0
  521. package/src/detect/ast-rules/dangerous-eval-ast.ts +227 -0
  522. package/src/detect/ast-rules/data-exposure-ast.ts +162 -0
  523. package/src/detect/ast-rules/dom-xss-ast.ts +260 -0
  524. package/src/detect/ast-rules/endpoint-protection-ast.ts +231 -0
  525. package/src/detect/ast-rules/entropy-ast.ts +268 -0
  526. package/src/detect/ast-rules/flask-debug-ast.ts +148 -0
  527. package/src/detect/ast-rules/framework-checks-ast.ts +200 -0
  528. package/src/detect/ast-rules/helpers/call-analysis.ts +256 -0
  529. package/src/detect/ast-rules/helpers/context-detection.ts +277 -0
  530. package/src/detect/ast-rules/helpers/control-flow.ts +179 -0
  531. package/src/detect/ast-rules/helpers/import-analysis.ts +185 -0
  532. package/src/detect/ast-rules/helpers/index.ts +133 -0
  533. package/src/detect/ast-rules/helpers/python-helpers.ts +1054 -0
  534. package/src/detect/ast-rules/helpers/scope-analysis.ts +224 -0
  535. package/src/detect/ast-rules/helpers/string-analysis.ts +215 -0
  536. package/src/detect/ast-rules/helpers/type-extraction.ts +138 -0
  537. package/src/detect/ast-rules/helpers/user-input.ts +256 -0
  538. package/src/detect/ast-rules/index.ts +311 -0
  539. package/src/detect/ast-rules/json-parse-ast.ts +162 -0
  540. package/src/detect/ast-rules/log-injection-ast.ts +243 -0
  541. package/src/detect/ast-rules/logic-gates-ast.ts +343 -0
  542. package/src/detect/ast-rules/mcp-security-ast.ts +808 -0
  543. package/src/detect/ast-rules/model-supply-chain-ast.ts +202 -0
  544. package/src/detect/ast-rules/package-hallucination-ast.ts +664 -0
  545. package/src/detect/ast-rules/prompt-hygiene-ast.ts +329 -0
  546. package/src/detect/ast-rules/rag-safety-ast.ts +689 -0
  547. package/src/detect/ast-rules/request-validation-ast.ts +122 -0
  548. package/src/detect/ast-rules/risky-imports-ast.ts +133 -0
  549. package/src/detect/ast-rules/schema-validation-ast.ts +244 -0
  550. package/src/detect/ast-rules/secret-patterns-ast.ts +223 -0
  551. package/src/detect/ast-rules/security-headers-ast.ts +206 -0
  552. package/src/detect/ast-rules/sql-injection-ast.ts +614 -0
  553. package/src/detect/ast-rules/ssrf-ast.ts +601 -0
  554. package/src/detect/ast-rules/taint-fix-templates.ts +108 -0
  555. package/src/detect/ast-rules/taint-flow-ast.ts +416 -0
  556. package/src/detect/ast-rules/variables-ast.ts +446 -0
  557. package/src/detect/ast-rules/weak-crypto-ast.ts +441 -0
  558. package/src/detect/ast-rules/xxe-ast.ts +184 -0
  559. package/src/detect/config/agent-skill-injection.ts +2 -24
  560. package/src/detect/config/index.ts +1 -0
  561. package/src/detect/config/osv-check.ts +6 -1
  562. package/src/detect/config/package-check.ts +6 -1
  563. package/src/detect/config/rules-file-backdoor.ts +438 -0
  564. package/src/detect/index.ts +146 -52
  565. package/src/detect/secrets/config-audit.ts +148 -3
  566. package/src/detect/secrets/entropy.ts +195 -0
  567. package/src/detect/secrets/index.ts +7 -16
  568. package/src/detect/structural/index.ts +23 -566
  569. package/src/index.ts +7 -0
  570. package/src/model/auth-helper-detector.ts +1 -7
  571. package/src/model/import-resolver.ts +104 -0
  572. package/src/model/imported-auth-detector.ts +1 -1
  573. package/src/model/index.ts +240 -80
  574. package/src/model/module-graph.ts +17 -5
  575. package/src/model/project-context.ts +28 -1
  576. package/src/model/route-auth-resolver.ts +18 -3
  577. package/src/model/route-discovery/index.ts +1 -1
  578. package/src/model/route-discovery/nextjs.ts +1 -1
  579. package/src/model/route-discovery/python.ts +156 -9
  580. package/src/model/route-discovery/types.ts +1 -1
  581. package/src/model/route-discovery/utils.ts +73 -0
  582. package/src/model/taint-types.ts +1 -6
  583. package/src/parse/ast.ts +271 -0
  584. package/src/parse/call-graph.ts +419 -0
  585. package/src/parse/file-classifier.ts +69 -15
  586. package/src/parse/node-index.ts +118 -0
  587. package/src/parse/type-extractor.ts +293 -0
  588. package/src/pipeline/config.ts +10 -1
  589. package/src/pipeline/index.ts +475 -187
  590. package/src/pipeline/modes/incremental.ts +1 -7
  591. package/src/postprocess/dedup.ts +48 -17
  592. package/src/report/build-result.ts +57 -29
  593. package/src/report/formatters/cli-terminal.ts +731 -415
  594. package/src/report/sanitize.ts +27 -0
  595. package/src/score/adjustments.ts +113 -40
  596. package/src/score/confidence.ts +10 -5
  597. package/src/score/evidence.ts +55 -0
  598. package/src/score/index.ts +27 -55
  599. package/src/score/types.ts +4 -0
  600. package/src/shared/category-filter.ts +12 -0
  601. package/src/shared/regex-utils.ts +4 -0
  602. package/src/shared/registry-clients.ts +106 -18
  603. package/src/shared/rules/__tests__/metadata.test.ts +5 -1
  604. package/src/shared/rules/metadata.ts +19 -0
  605. package/src/shared/types.ts +373 -254
  606. package/src/taint/async-flow.ts +301 -0
  607. package/src/taint/cfg-builder.ts +1127 -0
  608. package/src/taint/cfg-types.ts +110 -0
  609. package/src/taint/constant-propagation.ts +170 -0
  610. package/src/taint/cross-file-analyzer.ts +118 -0
  611. package/src/taint/cross-file-index.ts +275 -0
  612. package/src/taint/def-use.ts +556 -0
  613. package/src/taint/file-analysis-cache.ts +145 -0
  614. package/src/taint/framework-models.ts +313 -0
  615. package/src/taint/helpers.ts +138 -0
  616. package/src/taint/index.ts +71 -0
  617. package/src/taint/llm-registry.ts +174 -0
  618. package/src/taint/llm-risk-scoring.ts +412 -0
  619. package/src/taint/propagation-types.ts +188 -0
  620. package/src/taint/propagation.ts +1750 -0
  621. package/src/taint/sanitizer-registry.ts +490 -0
  622. package/src/taint/sink-classifier.ts +1402 -0
  623. package/src/taint/source-classifier.ts +859 -0
  624. package/src/taint/taint-analyzer.ts +112 -0
  625. package/src/taint/taint-summary.ts +341 -0
  626. package/src/taint/types.ts +86 -0
  627. package/src/tiers.ts +2 -2
  628. package/src/validate/clients.ts +3 -2
  629. package/src/validate/index.ts +89 -53
  630. package/src/validate/prompts/modules/ai-patterns.ts +16 -0
  631. package/src/validate/prompts/modules/common.ts +12 -3
  632. package/src/validate/providers/anthropic.ts +254 -148
  633. package/src/validate/providers/openai.ts +363 -218
  634. package/src/validate/request-builder.ts +2 -45
  635. package/src/validate/types.ts +9 -0
  636. package/src/validate/utils/path-helpers.ts +2 -2
  637. package/src/validate/utils/response-parser.ts +32 -3
  638. package/src/validate/utils/retry.ts +19 -4
  639. package/dist/ai-context/index.d.ts +0 -6
  640. package/dist/ai-context/index.d.ts.map +0 -1
  641. package/dist/ai-context/index.js +0 -13
  642. package/dist/ai-context/index.js.map +0 -1
  643. package/dist/ai-context/manager.d.ts +0 -67
  644. package/dist/ai-context/manager.d.ts.map +0 -1
  645. package/dist/ai-context/manager.js +0 -104
  646. package/dist/ai-context/manager.js.map +0 -1
  647. package/dist/baseline/diff.d.ts +0 -32
  648. package/dist/baseline/diff.d.ts.map +0 -1
  649. package/dist/baseline/diff.js +0 -119
  650. package/dist/baseline/diff.js.map +0 -1
  651. package/dist/baseline/index.d.ts +0 -9
  652. package/dist/baseline/index.d.ts.map +0 -1
  653. package/dist/baseline/index.js +0 -19
  654. package/dist/baseline/index.js.map +0 -1
  655. package/dist/baseline/manager.d.ts +0 -67
  656. package/dist/baseline/manager.d.ts.map +0 -1
  657. package/dist/baseline/manager.js +0 -180
  658. package/dist/baseline/manager.js.map +0 -1
  659. package/dist/baseline/types.d.ts +0 -91
  660. package/dist/baseline/types.d.ts.map +0 -1
  661. package/dist/baseline/types.js +0 -12
  662. package/dist/baseline/types.js.map +0 -1
  663. package/dist/category-filter.d.ts +0 -125
  664. package/dist/category-filter.d.ts.map +0 -1
  665. package/dist/category-filter.js +0 -360
  666. package/dist/category-filter.js.map +0 -1
  667. package/dist/detect/ai-code/agent-tools.d.ts +0 -22
  668. package/dist/detect/ai-code/agent-tools.d.ts.map +0 -1
  669. package/dist/detect/ai-code/agent-tools.js +0 -1509
  670. package/dist/detect/ai-code/agent-tools.js.map +0 -1
  671. package/dist/detect/ai-code/byok-patterns.d.ts +0 -15
  672. package/dist/detect/ai-code/byok-patterns.d.ts.map +0 -1
  673. package/dist/detect/ai-code/byok-patterns.js +0 -313
  674. package/dist/detect/ai-code/byok-patterns.js.map +0 -1
  675. package/dist/detect/ai-code/endpoint-protection.d.ts +0 -38
  676. package/dist/detect/ai-code/endpoint-protection.d.ts.map +0 -1
  677. package/dist/detect/ai-code/endpoint-protection.js +0 -349
  678. package/dist/detect/ai-code/endpoint-protection.js.map +0 -1
  679. package/dist/detect/ai-code/execution-sinks.d.ts +0 -21
  680. package/dist/detect/ai-code/execution-sinks.d.ts.map +0 -1
  681. package/dist/detect/ai-code/execution-sinks.js +0 -1158
  682. package/dist/detect/ai-code/execution-sinks.js.map +0 -1
  683. package/dist/detect/ai-code/fingerprinting.d.ts +0 -10
  684. package/dist/detect/ai-code/fingerprinting.d.ts.map +0 -1
  685. package/dist/detect/ai-code/fingerprinting.js +0 -665
  686. package/dist/detect/ai-code/fingerprinting.js.map +0 -1
  687. package/dist/detect/ai-code/mcp-security.d.ts +0 -20
  688. package/dist/detect/ai-code/mcp-security.d.ts.map +0 -1
  689. package/dist/detect/ai-code/mcp-security.js +0 -880
  690. package/dist/detect/ai-code/mcp-security.js.map +0 -1
  691. package/dist/detect/ai-code/model-supply-chain.d.ts +0 -23
  692. package/dist/detect/ai-code/model-supply-chain.d.ts.map +0 -1
  693. package/dist/detect/ai-code/model-supply-chain.js +0 -447
  694. package/dist/detect/ai-code/model-supply-chain.js.map +0 -1
  695. package/dist/detect/ai-code/package-hallucination.d.ts +0 -22
  696. package/dist/detect/ai-code/package-hallucination.d.ts.map +0 -1
  697. package/dist/detect/ai-code/package-hallucination.js +0 -841
  698. package/dist/detect/ai-code/package-hallucination.js.map +0 -1
  699. package/dist/detect/ai-code/prompt-hygiene.d.ts +0 -22
  700. package/dist/detect/ai-code/prompt-hygiene.d.ts.map +0 -1
  701. package/dist/detect/ai-code/prompt-hygiene.js +0 -1177
  702. package/dist/detect/ai-code/prompt-hygiene.js.map +0 -1
  703. package/dist/detect/ai-code/rag-safety.d.ts +0 -24
  704. package/dist/detect/ai-code/rag-safety.d.ts.map +0 -1
  705. package/dist/detect/ai-code/rag-safety.js +0 -913
  706. package/dist/detect/ai-code/rag-safety.js.map +0 -1
  707. package/dist/detect/ai-code/schema-validation.d.ts +0 -28
  708. package/dist/detect/ai-code/schema-validation.d.ts.map +0 -1
  709. package/dist/detect/ai-code/schema-validation.js +0 -378
  710. package/dist/detect/ai-code/schema-validation.js.map +0 -1
  711. package/dist/detect/secrets/patterns.d.ts +0 -11
  712. package/dist/detect/secrets/patterns.d.ts.map +0 -1
  713. package/dist/detect/secrets/patterns.js +0 -518
  714. package/dist/detect/secrets/patterns.js.map +0 -1
  715. package/dist/detect/secrets/weak-crypto.d.ts +0 -10
  716. package/dist/detect/secrets/weak-crypto.d.ts.map +0 -1
  717. package/dist/detect/secrets/weak-crypto.js +0 -432
  718. package/dist/detect/secrets/weak-crypto.js.map +0 -1
  719. package/dist/detect/structural/auth-patterns.d.ts +0 -22
  720. package/dist/detect/structural/auth-patterns.d.ts.map +0 -1
  721. package/dist/detect/structural/auth-patterns.js +0 -533
  722. package/dist/detect/structural/auth-patterns.js.map +0 -1
  723. package/dist/detect/structural/dangerous-functions/child-process.d.ts +0 -16
  724. package/dist/detect/structural/dangerous-functions/child-process.d.ts.map +0 -1
  725. package/dist/detect/structural/dangerous-functions/child-process.js +0 -74
  726. package/dist/detect/structural/dangerous-functions/child-process.js.map +0 -1
  727. package/dist/detect/structural/dangerous-functions/dom-xss.d.ts +0 -34
  728. package/dist/detect/structural/dangerous-functions/dom-xss.d.ts.map +0 -1
  729. package/dist/detect/structural/dangerous-functions/dom-xss.js +0 -230
  730. package/dist/detect/structural/dangerous-functions/dom-xss.js.map +0 -1
  731. package/dist/detect/structural/dangerous-functions/index.d.ts +0 -16
  732. package/dist/detect/structural/dangerous-functions/index.d.ts.map +0 -1
  733. package/dist/detect/structural/dangerous-functions/index.js +0 -1193
  734. package/dist/detect/structural/dangerous-functions/index.js.map +0 -1
  735. package/dist/detect/structural/dangerous-functions/json-parse.d.ts +0 -31
  736. package/dist/detect/structural/dangerous-functions/json-parse.d.ts.map +0 -1
  737. package/dist/detect/structural/dangerous-functions/json-parse.js +0 -326
  738. package/dist/detect/structural/dangerous-functions/json-parse.js.map +0 -1
  739. package/dist/detect/structural/dangerous-functions/math-random.d.ts +0 -111
  740. package/dist/detect/structural/dangerous-functions/math-random.d.ts.map +0 -1
  741. package/dist/detect/structural/dangerous-functions/math-random.js +0 -684
  742. package/dist/detect/structural/dangerous-functions/math-random.js.map +0 -1
  743. package/dist/detect/structural/dangerous-functions/patterns.d.ts +0 -21
  744. package/dist/detect/structural/dangerous-functions/patterns.d.ts.map +0 -1
  745. package/dist/detect/structural/dangerous-functions/patterns.js +0 -163
  746. package/dist/detect/structural/dangerous-functions/patterns.js.map +0 -1
  747. package/dist/detect/structural/dangerous-functions/request-validation.d.ts +0 -13
  748. package/dist/detect/structural/dangerous-functions/request-validation.d.ts.map +0 -1
  749. package/dist/detect/structural/dangerous-functions/request-validation.js +0 -126
  750. package/dist/detect/structural/dangerous-functions/request-validation.js.map +0 -1
  751. package/dist/detect/structural/dangerous-functions/utils/control-flow.d.ts +0 -24
  752. package/dist/detect/structural/dangerous-functions/utils/control-flow.d.ts.map +0 -1
  753. package/dist/detect/structural/dangerous-functions/utils/control-flow.js +0 -70
  754. package/dist/detect/structural/dangerous-functions/utils/control-flow.js.map +0 -1
  755. package/dist/detect/structural/dangerous-functions/utils/helpers.d.ts +0 -31
  756. package/dist/detect/structural/dangerous-functions/utils/helpers.d.ts.map +0 -1
  757. package/dist/detect/structural/dangerous-functions/utils/helpers.js +0 -147
  758. package/dist/detect/structural/dangerous-functions/utils/helpers.js.map +0 -1
  759. package/dist/detect/structural/dangerous-functions/utils/index.d.ts +0 -9
  760. package/dist/detect/structural/dangerous-functions/utils/index.d.ts.map +0 -1
  761. package/dist/detect/structural/dangerous-functions/utils/index.js +0 -23
  762. package/dist/detect/structural/dangerous-functions/utils/index.js.map +0 -1
  763. package/dist/detect/structural/dangerous-functions/utils/schema-validation.d.ts +0 -22
  764. package/dist/detect/structural/dangerous-functions/utils/schema-validation.d.ts.map +0 -1
  765. package/dist/detect/structural/dangerous-functions/utils/schema-validation.js +0 -102
  766. package/dist/detect/structural/dangerous-functions/utils/schema-validation.js.map +0 -1
  767. package/dist/detect/structural/data-exposure.d.ts +0 -19
  768. package/dist/detect/structural/data-exposure.d.ts.map +0 -1
  769. package/dist/detect/structural/data-exposure.js +0 -262
  770. package/dist/detect/structural/data-exposure.js.map +0 -1
  771. package/dist/detect/structural/framework-checks.d.ts +0 -10
  772. package/dist/detect/structural/framework-checks.d.ts.map +0 -1
  773. package/dist/detect/structural/framework-checks.js +0 -389
  774. package/dist/detect/structural/framework-checks.js.map +0 -1
  775. package/dist/detect/structural/log-injection.d.ts +0 -18
  776. package/dist/detect/structural/log-injection.d.ts.map +0 -1
  777. package/dist/detect/structural/log-injection.js +0 -217
  778. package/dist/detect/structural/log-injection.js.map +0 -1
  779. package/dist/detect/structural/logic-gates.d.ts +0 -10
  780. package/dist/detect/structural/logic-gates.d.ts.map +0 -1
  781. package/dist/detect/structural/logic-gates.js +0 -227
  782. package/dist/detect/structural/logic-gates.js.map +0 -1
  783. package/dist/detect/structural/risky-imports.d.ts +0 -10
  784. package/dist/detect/structural/risky-imports.d.ts.map +0 -1
  785. package/dist/detect/structural/risky-imports.js +0 -168
  786. package/dist/detect/structural/risky-imports.js.map +0 -1
  787. package/dist/detect/structural/security-headers.d.ts +0 -18
  788. package/dist/detect/structural/security-headers.d.ts.map +0 -1
  789. package/dist/detect/structural/security-headers.js +0 -196
  790. package/dist/detect/structural/security-headers.js.map +0 -1
  791. package/dist/detect/structural/ssrf-detection.d.ts +0 -18
  792. package/dist/detect/structural/ssrf-detection.d.ts.map +0 -1
  793. package/dist/detect/structural/ssrf-detection.js +0 -263
  794. package/dist/detect/structural/ssrf-detection.js.map +0 -1
  795. package/dist/detect/structural/variables.d.ts +0 -11
  796. package/dist/detect/structural/variables.d.ts.map +0 -1
  797. package/dist/detect/structural/variables.js +0 -159
  798. package/dist/detect/structural/variables.js.map +0 -1
  799. package/dist/detect/structural/xxe-detection.d.ts +0 -18
  800. package/dist/detect/structural/xxe-detection.d.ts.map +0 -1
  801. package/dist/detect/structural/xxe-detection.js +0 -245
  802. package/dist/detect/structural/xxe-detection.js.map +0 -1
  803. package/dist/filtering/context-adjustments.d.ts +0 -23
  804. package/dist/filtering/context-adjustments.d.ts.map +0 -1
  805. package/dist/filtering/context-adjustments.js +0 -100
  806. package/dist/filtering/context-adjustments.js.map +0 -1
  807. package/dist/filtering/index.d.ts +0 -3
  808. package/dist/filtering/index.d.ts.map +0 -1
  809. package/dist/filtering/index.js +0 -8
  810. package/dist/filtering/index.js.map +0 -1
  811. package/dist/filtering/pipeline.d.ts +0 -48
  812. package/dist/filtering/pipeline.d.ts.map +0 -1
  813. package/dist/filtering/pipeline.js +0 -76
  814. package/dist/filtering/pipeline.js.map +0 -1
  815. package/dist/formatters/ai-context.d.ts +0 -23
  816. package/dist/formatters/ai-context.d.ts.map +0 -1
  817. package/dist/formatters/ai-context.js +0 -238
  818. package/dist/formatters/ai-context.js.map +0 -1
  819. package/dist/formatters/cli-terminal.d.ts +0 -65
  820. package/dist/formatters/cli-terminal.d.ts.map +0 -1
  821. package/dist/formatters/cli-terminal.js +0 -735
  822. package/dist/formatters/cli-terminal.js.map +0 -1
  823. package/dist/formatters/github-comment.d.ts +0 -41
  824. package/dist/formatters/github-comment.d.ts.map +0 -1
  825. package/dist/formatters/github-comment.js +0 -370
  826. package/dist/formatters/github-comment.js.map +0 -1
  827. package/dist/formatters/grouping.d.ts +0 -52
  828. package/dist/formatters/grouping.d.ts.map +0 -1
  829. package/dist/formatters/grouping.js +0 -152
  830. package/dist/formatters/grouping.js.map +0 -1
  831. package/dist/formatters/ide/claude-code.d.ts +0 -17
  832. package/dist/formatters/ide/claude-code.d.ts.map +0 -1
  833. package/dist/formatters/ide/claude-code.js +0 -94
  834. package/dist/formatters/ide/claude-code.js.map +0 -1
  835. package/dist/formatters/ide/cursor.d.ts +0 -13
  836. package/dist/formatters/ide/cursor.d.ts.map +0 -1
  837. package/dist/formatters/ide/cursor.js +0 -125
  838. package/dist/formatters/ide/cursor.js.map +0 -1
  839. package/dist/formatters/ide/index.d.ts +0 -62
  840. package/dist/formatters/ide/index.d.ts.map +0 -1
  841. package/dist/formatters/ide/index.js +0 -184
  842. package/dist/formatters/ide/index.js.map +0 -1
  843. package/dist/formatters/ide/windsurf.d.ts +0 -13
  844. package/dist/formatters/ide/windsurf.d.ts.map +0 -1
  845. package/dist/formatters/ide/windsurf.js +0 -117
  846. package/dist/formatters/ide/windsurf.js.map +0 -1
  847. package/dist/formatters/index.d.ts +0 -11
  848. package/dist/formatters/index.d.ts.map +0 -1
  849. package/dist/formatters/index.js +0 -54
  850. package/dist/formatters/index.js.map +0 -1
  851. package/dist/formatters/vscode-diagnostic.d.ts +0 -103
  852. package/dist/formatters/vscode-diagnostic.d.ts.map +0 -1
  853. package/dist/formatters/vscode-diagnostic.js +0 -151
  854. package/dist/formatters/vscode-diagnostic.js.map +0 -1
  855. package/dist/layer1/comments.d.ts +0 -11
  856. package/dist/layer1/comments.d.ts.map +0 -1
  857. package/dist/layer1/comments.js +0 -203
  858. package/dist/layer1/comments.js.map +0 -1
  859. package/dist/layer1/config-audit.d.ts +0 -11
  860. package/dist/layer1/config-audit.d.ts.map +0 -1
  861. package/dist/layer1/config-audit.js +0 -311
  862. package/dist/layer1/config-audit.js.map +0 -1
  863. package/dist/layer1/config-mcp-audit.d.ts +0 -23
  864. package/dist/layer1/config-mcp-audit.d.ts.map +0 -1
  865. package/dist/layer1/config-mcp-audit.js +0 -239
  866. package/dist/layer1/config-mcp-audit.js.map +0 -1
  867. package/dist/layer1/entropy.d.ts +0 -11
  868. package/dist/layer1/entropy.d.ts.map +0 -1
  869. package/dist/layer1/entropy.js +0 -741
  870. package/dist/layer1/entropy.js.map +0 -1
  871. package/dist/layer1/file-flags.d.ts +0 -10
  872. package/dist/layer1/file-flags.d.ts.map +0 -1
  873. package/dist/layer1/file-flags.js +0 -119
  874. package/dist/layer1/file-flags.js.map +0 -1
  875. package/dist/layer1/index.d.ts +0 -38
  876. package/dist/layer1/index.d.ts.map +0 -1
  877. package/dist/layer1/index.js +0 -170
  878. package/dist/layer1/index.js.map +0 -1
  879. package/dist/layer1/patterns.d.ts +0 -11
  880. package/dist/layer1/patterns.d.ts.map +0 -1
  881. package/dist/layer1/patterns.js +0 -512
  882. package/dist/layer1/patterns.js.map +0 -1
  883. package/dist/layer1/urls.d.ts +0 -11
  884. package/dist/layer1/urls.d.ts.map +0 -1
  885. package/dist/layer1/urls.js +0 -444
  886. package/dist/layer1/urls.js.map +0 -1
  887. package/dist/layer1/weak-crypto.d.ts +0 -10
  888. package/dist/layer1/weak-crypto.d.ts.map +0 -1
  889. package/dist/layer1/weak-crypto.js +0 -428
  890. package/dist/layer1/weak-crypto.js.map +0 -1
  891. package/dist/layer2/ai-agent-tools.d.ts +0 -22
  892. package/dist/layer2/ai-agent-tools.d.ts.map +0 -1
  893. package/dist/layer2/ai-agent-tools.js +0 -1490
  894. package/dist/layer2/ai-agent-tools.js.map +0 -1
  895. package/dist/layer2/ai-endpoint-protection.d.ts +0 -38
  896. package/dist/layer2/ai-endpoint-protection.d.ts.map +0 -1
  897. package/dist/layer2/ai-endpoint-protection.js +0 -346
  898. package/dist/layer2/ai-endpoint-protection.js.map +0 -1
  899. package/dist/layer2/ai-execution-sinks.d.ts +0 -21
  900. package/dist/layer2/ai-execution-sinks.d.ts.map +0 -1
  901. package/dist/layer2/ai-execution-sinks.js +0 -1155
  902. package/dist/layer2/ai-execution-sinks.js.map +0 -1
  903. package/dist/layer2/ai-fingerprinting.d.ts +0 -10
  904. package/dist/layer2/ai-fingerprinting.d.ts.map +0 -1
  905. package/dist/layer2/ai-fingerprinting.js +0 -650
  906. package/dist/layer2/ai-fingerprinting.js.map +0 -1
  907. package/dist/layer2/ai-mcp-security.d.ts +0 -20
  908. package/dist/layer2/ai-mcp-security.d.ts.map +0 -1
  909. package/dist/layer2/ai-mcp-security.js +0 -877
  910. package/dist/layer2/ai-mcp-security.js.map +0 -1
  911. package/dist/layer2/ai-package-hallucination.d.ts +0 -22
  912. package/dist/layer2/ai-package-hallucination.d.ts.map +0 -1
  913. package/dist/layer2/ai-package-hallucination.js +0 -828
  914. package/dist/layer2/ai-package-hallucination.js.map +0 -1
  915. package/dist/layer2/ai-prompt-hygiene.d.ts +0 -22
  916. package/dist/layer2/ai-prompt-hygiene.d.ts.map +0 -1
  917. package/dist/layer2/ai-prompt-hygiene.js +0 -1156
  918. package/dist/layer2/ai-prompt-hygiene.js.map +0 -1
  919. package/dist/layer2/ai-rag-safety.d.ts +0 -24
  920. package/dist/layer2/ai-rag-safety.d.ts.map +0 -1
  921. package/dist/layer2/ai-rag-safety.js +0 -910
  922. package/dist/layer2/ai-rag-safety.js.map +0 -1
  923. package/dist/layer2/ai-schema-validation.d.ts +0 -28
  924. package/dist/layer2/ai-schema-validation.d.ts.map +0 -1
  925. package/dist/layer2/ai-schema-validation.js +0 -375
  926. package/dist/layer2/ai-schema-validation.js.map +0 -1
  927. package/dist/layer2/auth-antipatterns.d.ts +0 -22
  928. package/dist/layer2/auth-antipatterns.d.ts.map +0 -1
  929. package/dist/layer2/auth-antipatterns.js +0 -522
  930. package/dist/layer2/auth-antipatterns.js.map +0 -1
  931. package/dist/layer2/byok-patterns.d.ts +0 -15
  932. package/dist/layer2/byok-patterns.d.ts.map +0 -1
  933. package/dist/layer2/byok-patterns.js +0 -302
  934. package/dist/layer2/byok-patterns.js.map +0 -1
  935. package/dist/layer2/dangerous-functions/child-process.d.ts +0 -16
  936. package/dist/layer2/dangerous-functions/child-process.d.ts.map +0 -1
  937. package/dist/layer2/dangerous-functions/child-process.js +0 -74
  938. package/dist/layer2/dangerous-functions/child-process.js.map +0 -1
  939. package/dist/layer2/dangerous-functions/dom-xss.d.ts +0 -34
  940. package/dist/layer2/dangerous-functions/dom-xss.d.ts.map +0 -1
  941. package/dist/layer2/dangerous-functions/dom-xss.js +0 -230
  942. package/dist/layer2/dangerous-functions/dom-xss.js.map +0 -1
  943. package/dist/layer2/dangerous-functions/index.d.ts +0 -16
  944. package/dist/layer2/dangerous-functions/index.d.ts.map +0 -1
  945. package/dist/layer2/dangerous-functions/index.js +0 -1152
  946. package/dist/layer2/dangerous-functions/index.js.map +0 -1
  947. package/dist/layer2/dangerous-functions/json-parse.d.ts +0 -31
  948. package/dist/layer2/dangerous-functions/json-parse.d.ts.map +0 -1
  949. package/dist/layer2/dangerous-functions/json-parse.js +0 -319
  950. package/dist/layer2/dangerous-functions/json-parse.js.map +0 -1
  951. package/dist/layer2/dangerous-functions/math-random.d.ts +0 -111
  952. package/dist/layer2/dangerous-functions/math-random.d.ts.map +0 -1
  953. package/dist/layer2/dangerous-functions/math-random.js +0 -684
  954. package/dist/layer2/dangerous-functions/math-random.js.map +0 -1
  955. package/dist/layer2/dangerous-functions/patterns.d.ts +0 -21
  956. package/dist/layer2/dangerous-functions/patterns.d.ts.map +0 -1
  957. package/dist/layer2/dangerous-functions/patterns.js +0 -163
  958. package/dist/layer2/dangerous-functions/patterns.js.map +0 -1
  959. package/dist/layer2/dangerous-functions/request-validation.d.ts +0 -13
  960. package/dist/layer2/dangerous-functions/request-validation.d.ts.map +0 -1
  961. package/dist/layer2/dangerous-functions/request-validation.js +0 -119
  962. package/dist/layer2/dangerous-functions/request-validation.js.map +0 -1
  963. package/dist/layer2/dangerous-functions/utils/control-flow.d.ts +0 -24
  964. package/dist/layer2/dangerous-functions/utils/control-flow.d.ts.map +0 -1
  965. package/dist/layer2/dangerous-functions/utils/control-flow.js +0 -70
  966. package/dist/layer2/dangerous-functions/utils/control-flow.js.map +0 -1
  967. package/dist/layer2/dangerous-functions/utils/helpers.d.ts +0 -31
  968. package/dist/layer2/dangerous-functions/utils/helpers.d.ts.map +0 -1
  969. package/dist/layer2/dangerous-functions/utils/helpers.js +0 -147
  970. package/dist/layer2/dangerous-functions/utils/helpers.js.map +0 -1
  971. package/dist/layer2/dangerous-functions/utils/index.d.ts +0 -9
  972. package/dist/layer2/dangerous-functions/utils/index.d.ts.map +0 -1
  973. package/dist/layer2/dangerous-functions/utils/index.js +0 -23
  974. package/dist/layer2/dangerous-functions/utils/index.js.map +0 -1
  975. package/dist/layer2/dangerous-functions/utils/schema-validation.d.ts +0 -22
  976. package/dist/layer2/dangerous-functions/utils/schema-validation.d.ts.map +0 -1
  977. package/dist/layer2/dangerous-functions/utils/schema-validation.js +0 -102
  978. package/dist/layer2/dangerous-functions/utils/schema-validation.js.map +0 -1
  979. package/dist/layer2/data-exposure.d.ts +0 -19
  980. package/dist/layer2/data-exposure.d.ts.map +0 -1
  981. package/dist/layer2/data-exposure.js +0 -255
  982. package/dist/layer2/data-exposure.js.map +0 -1
  983. package/dist/layer2/framework-checks.d.ts +0 -10
  984. package/dist/layer2/framework-checks.d.ts.map +0 -1
  985. package/dist/layer2/framework-checks.js +0 -384
  986. package/dist/layer2/framework-checks.js.map +0 -1
  987. package/dist/layer2/index.d.ts +0 -74
  988. package/dist/layer2/index.d.ts.map +0 -1
  989. package/dist/layer2/index.js +0 -544
  990. package/dist/layer2/index.js.map +0 -1
  991. package/dist/layer2/log-injection.d.ts +0 -18
  992. package/dist/layer2/log-injection.d.ts.map +0 -1
  993. package/dist/layer2/log-injection.js +0 -214
  994. package/dist/layer2/log-injection.js.map +0 -1
  995. package/dist/layer2/logic-gates.d.ts +0 -10
  996. package/dist/layer2/logic-gates.d.ts.map +0 -1
  997. package/dist/layer2/logic-gates.js +0 -220
  998. package/dist/layer2/logic-gates.js.map +0 -1
  999. package/dist/layer2/model-supply-chain.d.ts +0 -23
  1000. package/dist/layer2/model-supply-chain.d.ts.map +0 -1
  1001. package/dist/layer2/model-supply-chain.js +0 -444
  1002. package/dist/layer2/model-supply-chain.js.map +0 -1
  1003. package/dist/layer2/risky-imports.d.ts +0 -10
  1004. package/dist/layer2/risky-imports.d.ts.map +0 -1
  1005. package/dist/layer2/risky-imports.js +0 -165
  1006. package/dist/layer2/risky-imports.js.map +0 -1
  1007. package/dist/layer2/security-headers.d.ts +0 -18
  1008. package/dist/layer2/security-headers.d.ts.map +0 -1
  1009. package/dist/layer2/security-headers.js +0 -187
  1010. package/dist/layer2/security-headers.js.map +0 -1
  1011. package/dist/layer2/ssrf-detection.d.ts +0 -18
  1012. package/dist/layer2/ssrf-detection.d.ts.map +0 -1
  1013. package/dist/layer2/ssrf-detection.js +0 -252
  1014. package/dist/layer2/ssrf-detection.js.map +0 -1
  1015. package/dist/layer2/variables.d.ts +0 -11
  1016. package/dist/layer2/variables.d.ts.map +0 -1
  1017. package/dist/layer2/variables.js +0 -156
  1018. package/dist/layer2/variables.js.map +0 -1
  1019. package/dist/layer2/xxe-detection.d.ts +0 -18
  1020. package/dist/layer2/xxe-detection.d.ts.map +0 -1
  1021. package/dist/layer2/xxe-detection.js +0 -242
  1022. package/dist/layer2/xxe-detection.js.map +0 -1
  1023. package/dist/layer3/anthropic/auto-dismiss.d.ts +0 -24
  1024. package/dist/layer3/anthropic/auto-dismiss.d.ts.map +0 -1
  1025. package/dist/layer3/anthropic/auto-dismiss.js +0 -199
  1026. package/dist/layer3/anthropic/auto-dismiss.js.map +0 -1
  1027. package/dist/layer3/anthropic/clients.d.ts +0 -44
  1028. package/dist/layer3/anthropic/clients.d.ts.map +0 -1
  1029. package/dist/layer3/anthropic/clients.js +0 -81
  1030. package/dist/layer3/anthropic/clients.js.map +0 -1
  1031. package/dist/layer3/anthropic/index.d.ts +0 -41
  1032. package/dist/layer3/anthropic/index.d.ts.map +0 -1
  1033. package/dist/layer3/anthropic/index.js +0 -141
  1034. package/dist/layer3/anthropic/index.js.map +0 -1
  1035. package/dist/layer3/anthropic/prompts/index.d.ts +0 -8
  1036. package/dist/layer3/anthropic/prompts/index.d.ts.map +0 -1
  1037. package/dist/layer3/anthropic/prompts/index.js +0 -16
  1038. package/dist/layer3/anthropic/prompts/index.js.map +0 -1
  1039. package/dist/layer3/anthropic/prompts/modules/ai-patterns.d.ts +0 -19
  1040. package/dist/layer3/anthropic/prompts/modules/ai-patterns.d.ts.map +0 -1
  1041. package/dist/layer3/anthropic/prompts/modules/ai-patterns.js +0 -156
  1042. package/dist/layer3/anthropic/prompts/modules/ai-patterns.js.map +0 -1
  1043. package/dist/layer3/anthropic/prompts/modules/auth-access.d.ts +0 -9
  1044. package/dist/layer3/anthropic/prompts/modules/auth-access.d.ts.map +0 -1
  1045. package/dist/layer3/anthropic/prompts/modules/auth-access.js +0 -25
  1046. package/dist/layer3/anthropic/prompts/modules/auth-access.js.map +0 -1
  1047. package/dist/layer3/anthropic/prompts/modules/common.d.ts +0 -11
  1048. package/dist/layer3/anthropic/prompts/modules/common.d.ts.map +0 -1
  1049. package/dist/layer3/anthropic/prompts/modules/common.js +0 -152
  1050. package/dist/layer3/anthropic/prompts/modules/common.js.map +0 -1
  1051. package/dist/layer3/anthropic/prompts/modules/index.d.ts +0 -54
  1052. package/dist/layer3/anthropic/prompts/modules/index.d.ts.map +0 -1
  1053. package/dist/layer3/anthropic/prompts/modules/index.js +0 -185
  1054. package/dist/layer3/anthropic/prompts/modules/index.js.map +0 -1
  1055. package/dist/layer3/anthropic/prompts/modules/owasp-classic.d.ts +0 -8
  1056. package/dist/layer3/anthropic/prompts/modules/owasp-classic.d.ts.map +0 -1
  1057. package/dist/layer3/anthropic/prompts/modules/owasp-classic.js +0 -84
  1058. package/dist/layer3/anthropic/prompts/modules/owasp-classic.js.map +0 -1
  1059. package/dist/layer3/anthropic/prompts/modules/secrets-crypto.d.ts +0 -8
  1060. package/dist/layer3/anthropic/prompts/modules/secrets-crypto.d.ts.map +0 -1
  1061. package/dist/layer3/anthropic/prompts/modules/secrets-crypto.js +0 -68
  1062. package/dist/layer3/anthropic/prompts/modules/secrets-crypto.js.map +0 -1
  1063. package/dist/layer3/anthropic/prompts/modules/xss-prompt.d.ts +0 -8
  1064. package/dist/layer3/anthropic/prompts/modules/xss-prompt.d.ts.map +0 -1
  1065. package/dist/layer3/anthropic/prompts/modules/xss-prompt.js +0 -22
  1066. package/dist/layer3/anthropic/prompts/modules/xss-prompt.js.map +0 -1
  1067. package/dist/layer3/anthropic/prompts/semantic-analysis.d.ts +0 -15
  1068. package/dist/layer3/anthropic/prompts/semantic-analysis.d.ts.map +0 -1
  1069. package/dist/layer3/anthropic/prompts/semantic-analysis.js +0 -169
  1070. package/dist/layer3/anthropic/prompts/semantic-analysis.js.map +0 -1
  1071. package/dist/layer3/anthropic/prompts/validation.d.ts +0 -18
  1072. package/dist/layer3/anthropic/prompts/validation.d.ts.map +0 -1
  1073. package/dist/layer3/anthropic/prompts/validation.js +0 -25
  1074. package/dist/layer3/anthropic/prompts/validation.js.map +0 -1
  1075. package/dist/layer3/anthropic/providers/anthropic.d.ts +0 -21
  1076. package/dist/layer3/anthropic/providers/anthropic.d.ts.map +0 -1
  1077. package/dist/layer3/anthropic/providers/anthropic.js +0 -269
  1078. package/dist/layer3/anthropic/providers/anthropic.js.map +0 -1
  1079. package/dist/layer3/anthropic/providers/index.d.ts +0 -8
  1080. package/dist/layer3/anthropic/providers/index.d.ts.map +0 -1
  1081. package/dist/layer3/anthropic/providers/index.js +0 -15
  1082. package/dist/layer3/anthropic/providers/index.js.map +0 -1
  1083. package/dist/layer3/anthropic/providers/openai.d.ts +0 -18
  1084. package/dist/layer3/anthropic/providers/openai.d.ts.map +0 -1
  1085. package/dist/layer3/anthropic/providers/openai.js +0 -343
  1086. package/dist/layer3/anthropic/providers/openai.js.map +0 -1
  1087. package/dist/layer3/anthropic/request-builder.d.ts +0 -27
  1088. package/dist/layer3/anthropic/request-builder.d.ts.map +0 -1
  1089. package/dist/layer3/anthropic/request-builder.js +0 -150
  1090. package/dist/layer3/anthropic/request-builder.js.map +0 -1
  1091. package/dist/layer3/anthropic/types.d.ts +0 -88
  1092. package/dist/layer3/anthropic/types.d.ts.map +0 -1
  1093. package/dist/layer3/anthropic/types.js +0 -38
  1094. package/dist/layer3/anthropic/types.js.map +0 -1
  1095. package/dist/layer3/anthropic/utils/context-extractor.d.ts +0 -55
  1096. package/dist/layer3/anthropic/utils/context-extractor.d.ts.map +0 -1
  1097. package/dist/layer3/anthropic/utils/context-extractor.js +0 -161
  1098. package/dist/layer3/anthropic/utils/context-extractor.js.map +0 -1
  1099. package/dist/layer3/anthropic/utils/index.d.ts +0 -11
  1100. package/dist/layer3/anthropic/utils/index.d.ts.map +0 -1
  1101. package/dist/layer3/anthropic/utils/index.js +0 -27
  1102. package/dist/layer3/anthropic/utils/index.js.map +0 -1
  1103. package/dist/layer3/anthropic/utils/path-helpers.d.ts +0 -21
  1104. package/dist/layer3/anthropic/utils/path-helpers.d.ts.map +0 -1
  1105. package/dist/layer3/anthropic/utils/path-helpers.js +0 -69
  1106. package/dist/layer3/anthropic/utils/path-helpers.js.map +0 -1
  1107. package/dist/layer3/anthropic/utils/response-parser.d.ts +0 -40
  1108. package/dist/layer3/anthropic/utils/response-parser.d.ts.map +0 -1
  1109. package/dist/layer3/anthropic/utils/response-parser.js +0 -285
  1110. package/dist/layer3/anthropic/utils/response-parser.js.map +0 -1
  1111. package/dist/layer3/anthropic/utils/retry.d.ts +0 -15
  1112. package/dist/layer3/anthropic/utils/retry.d.ts.map +0 -1
  1113. package/dist/layer3/anthropic/utils/retry.js +0 -62
  1114. package/dist/layer3/anthropic/utils/retry.js.map +0 -1
  1115. package/dist/layer3/index.d.ts +0 -27
  1116. package/dist/layer3/index.d.ts.map +0 -1
  1117. package/dist/layer3/index.js +0 -150
  1118. package/dist/layer3/index.js.map +0 -1
  1119. package/dist/layer3/osv-check.d.ts +0 -75
  1120. package/dist/layer3/osv-check.d.ts.map +0 -1
  1121. package/dist/layer3/osv-check.js +0 -308
  1122. package/dist/layer3/osv-check.js.map +0 -1
  1123. package/dist/layer3/package-check.d.ts +0 -63
  1124. package/dist/layer3/package-check.d.ts.map +0 -1
  1125. package/dist/layer3/package-check.js +0 -508
  1126. package/dist/layer3/package-check.js.map +0 -1
  1127. package/dist/model/cross-file-taint.d.ts +0 -40
  1128. package/dist/model/cross-file-taint.d.ts.map +0 -1
  1129. package/dist/model/cross-file-taint.js +0 -290
  1130. package/dist/model/cross-file-taint.js.map +0 -1
  1131. package/dist/model/function-classifier.d.ts +0 -32
  1132. package/dist/model/function-classifier.d.ts.map +0 -1
  1133. package/dist/model/function-classifier.js +0 -143
  1134. package/dist/model/function-classifier.js.map +0 -1
  1135. package/dist/model/sanitiser-detection.d.ts +0 -27
  1136. package/dist/model/sanitiser-detection.d.ts.map +0 -1
  1137. package/dist/model/sanitiser-detection.js +0 -224
  1138. package/dist/model/sanitiser-detection.js.map +0 -1
  1139. package/dist/model/sink-matcher.d.ts +0 -17
  1140. package/dist/model/sink-matcher.d.ts.map +0 -1
  1141. package/dist/model/sink-matcher.js +0 -141
  1142. package/dist/model/sink-matcher.js.map +0 -1
  1143. package/dist/model/sink-patterns.d.ts +0 -19
  1144. package/dist/model/sink-patterns.d.ts.map +0 -1
  1145. package/dist/model/sink-patterns.js +0 -88
  1146. package/dist/model/sink-patterns.js.map +0 -1
  1147. package/dist/model/source-discovery.d.ts +0 -15
  1148. package/dist/model/source-discovery.d.ts.map +0 -1
  1149. package/dist/model/source-discovery.js +0 -170
  1150. package/dist/model/source-discovery.js.map +0 -1
  1151. package/dist/model/taint-tracker.d.ts +0 -21
  1152. package/dist/model/taint-tracker.d.ts.map +0 -1
  1153. package/dist/model/taint-tracker.js +0 -281
  1154. package/dist/model/taint-tracker.js.map +0 -1
  1155. package/dist/modes/incremental.d.ts +0 -66
  1156. package/dist/modes/incremental.d.ts.map +0 -1
  1157. package/dist/modes/incremental.js +0 -200
  1158. package/dist/modes/incremental.js.map +0 -1
  1159. package/dist/rules/framework-fixes.d.ts +0 -48
  1160. package/dist/rules/framework-fixes.d.ts.map +0 -1
  1161. package/dist/rules/framework-fixes.js +0 -439
  1162. package/dist/rules/framework-fixes.js.map +0 -1
  1163. package/dist/rules/index.d.ts +0 -8
  1164. package/dist/rules/index.d.ts.map +0 -1
  1165. package/dist/rules/index.js +0 -18
  1166. package/dist/rules/index.js.map +0 -1
  1167. package/dist/rules/metadata.d.ts +0 -43
  1168. package/dist/rules/metadata.d.ts.map +0 -1
  1169. package/dist/rules/metadata.js +0 -800
  1170. package/dist/rules/metadata.js.map +0 -1
  1171. package/dist/score/auto-dismiss.d.ts +0 -28
  1172. package/dist/score/auto-dismiss.d.ts.map +0 -1
  1173. package/dist/score/auto-dismiss.js +0 -200
  1174. package/dist/score/auto-dismiss.js.map +0 -1
  1175. package/dist/suppression/config-loader.d.ts +0 -74
  1176. package/dist/suppression/config-loader.d.ts.map +0 -1
  1177. package/dist/suppression/config-loader.js +0 -424
  1178. package/dist/suppression/config-loader.js.map +0 -1
  1179. package/dist/suppression/hash.d.ts +0 -48
  1180. package/dist/suppression/hash.d.ts.map +0 -1
  1181. package/dist/suppression/hash.js +0 -88
  1182. package/dist/suppression/hash.js.map +0 -1
  1183. package/dist/suppression/index.d.ts +0 -11
  1184. package/dist/suppression/index.d.ts.map +0 -1
  1185. package/dist/suppression/index.js +0 -39
  1186. package/dist/suppression/index.js.map +0 -1
  1187. package/dist/suppression/inline-parser.d.ts +0 -39
  1188. package/dist/suppression/inline-parser.d.ts.map +0 -1
  1189. package/dist/suppression/inline-parser.js +0 -218
  1190. package/dist/suppression/inline-parser.js.map +0 -1
  1191. package/dist/suppression/manager.d.ts +0 -94
  1192. package/dist/suppression/manager.d.ts.map +0 -1
  1193. package/dist/suppression/manager.js +0 -292
  1194. package/dist/suppression/manager.js.map +0 -1
  1195. package/dist/suppression/types.d.ts +0 -151
  1196. package/dist/suppression/types.d.ts.map +0 -1
  1197. package/dist/suppression/types.js +0 -28
  1198. package/dist/suppression/types.js.map +0 -1
  1199. package/dist/types.d.ts +0 -331
  1200. package/dist/types.d.ts.map +0 -1
  1201. package/dist/types.js +0 -124
  1202. package/dist/types.js.map +0 -1
  1203. package/dist/utils/auth-helper-detector.d.ts +0 -56
  1204. package/dist/utils/auth-helper-detector.d.ts.map +0 -1
  1205. package/dist/utils/auth-helper-detector.js +0 -360
  1206. package/dist/utils/auth-helper-detector.js.map +0 -1
  1207. package/dist/utils/code-analysis.d.ts +0 -39
  1208. package/dist/utils/code-analysis.d.ts.map +0 -1
  1209. package/dist/utils/code-analysis.js +0 -159
  1210. package/dist/utils/code-analysis.js.map +0 -1
  1211. package/dist/utils/comment-analyzer.d.ts +0 -38
  1212. package/dist/utils/comment-analyzer.d.ts.map +0 -1
  1213. package/dist/utils/comment-analyzer.js +0 -218
  1214. package/dist/utils/comment-analyzer.js.map +0 -1
  1215. package/dist/utils/context-helpers.d.ts +0 -219
  1216. package/dist/utils/context-helpers.d.ts.map +0 -1
  1217. package/dist/utils/context-helpers.js +0 -886
  1218. package/dist/utils/context-helpers.js.map +0 -1
  1219. package/dist/utils/diff-detector.d.ts +0 -53
  1220. package/dist/utils/diff-detector.d.ts.map +0 -1
  1221. package/dist/utils/diff-detector.js +0 -104
  1222. package/dist/utils/diff-detector.js.map +0 -1
  1223. package/dist/utils/diff-parser.d.ts +0 -80
  1224. package/dist/utils/diff-parser.d.ts.map +0 -1
  1225. package/dist/utils/diff-parser.js +0 -202
  1226. package/dist/utils/diff-parser.js.map +0 -1
  1227. package/dist/utils/environment-context.d.ts +0 -76
  1228. package/dist/utils/environment-context.d.ts.map +0 -1
  1229. package/dist/utils/environment-context.js +0 -271
  1230. package/dist/utils/environment-context.js.map +0 -1
  1231. package/dist/utils/imported-auth-detector.d.ts +0 -37
  1232. package/dist/utils/imported-auth-detector.d.ts.map +0 -1
  1233. package/dist/utils/imported-auth-detector.js +0 -251
  1234. package/dist/utils/imported-auth-detector.js.map +0 -1
  1235. package/dist/utils/intent-detector.d.ts +0 -66
  1236. package/dist/utils/intent-detector.d.ts.map +0 -1
  1237. package/dist/utils/intent-detector.js +0 -282
  1238. package/dist/utils/intent-detector.js.map +0 -1
  1239. package/dist/utils/middleware-detector.d.ts +0 -55
  1240. package/dist/utils/middleware-detector.d.ts.map +0 -1
  1241. package/dist/utils/middleware-detector.js +0 -260
  1242. package/dist/utils/middleware-detector.js.map +0 -1
  1243. package/dist/utils/oauth-flow-detector.d.ts +0 -41
  1244. package/dist/utils/oauth-flow-detector.d.ts.map +0 -1
  1245. package/dist/utils/oauth-flow-detector.js +0 -202
  1246. package/dist/utils/oauth-flow-detector.js.map +0 -1
  1247. package/dist/utils/parsed-file.d.ts +0 -51
  1248. package/dist/utils/parsed-file.d.ts.map +0 -1
  1249. package/dist/utils/parsed-file.js +0 -95
  1250. package/dist/utils/parsed-file.js.map +0 -1
  1251. package/dist/utils/path-exclusions.d.ts +0 -55
  1252. package/dist/utils/path-exclusions.d.ts.map +0 -1
  1253. package/dist/utils/path-exclusions.js +0 -224
  1254. package/dist/utils/path-exclusions.js.map +0 -1
  1255. package/dist/utils/project-context-builder.d.ts +0 -119
  1256. package/dist/utils/project-context-builder.d.ts.map +0 -1
  1257. package/dist/utils/project-context-builder.js +0 -534
  1258. package/dist/utils/project-context-builder.js.map +0 -1
  1259. package/dist/utils/registry-clients.d.ts +0 -93
  1260. package/dist/utils/registry-clients.d.ts.map +0 -1
  1261. package/dist/utils/registry-clients.js +0 -273
  1262. package/dist/utils/registry-clients.js.map +0 -1
  1263. package/dist/utils/route-hierarchy.d.ts +0 -50
  1264. package/dist/utils/route-hierarchy.d.ts.map +0 -1
  1265. package/dist/utils/route-hierarchy.js +0 -226
  1266. package/dist/utils/route-hierarchy.js.map +0 -1
  1267. package/dist/utils/schema-semantics.d.ts +0 -45
  1268. package/dist/utils/schema-semantics.d.ts.map +0 -1
  1269. package/dist/utils/schema-semantics.js +0 -193
  1270. package/dist/utils/schema-semantics.js.map +0 -1
  1271. package/dist/utils/trpc-analyzer.d.ts +0 -78
  1272. package/dist/utils/trpc-analyzer.d.ts.map +0 -1
  1273. package/dist/utils/trpc-analyzer.js +0 -297
  1274. package/dist/utils/trpc-analyzer.js.map +0 -1
  1275. package/src/__tests__/context-engine/cross-file-taint.test.ts +0 -284
  1276. package/src/__tests__/context-engine/function-classifier.test.ts +0 -146
  1277. package/src/__tests__/context-engine/integration.test.ts +0 -320
  1278. package/src/__tests__/context-engine/sanitiser-detection.test.ts +0 -187
  1279. package/src/__tests__/context-engine/sink-matcher.test.ts +0 -251
  1280. package/src/__tests__/context-engine/source-discovery.test.ts +0 -186
  1281. package/src/__tests__/context-engine/taint-tracker.test.ts +0 -182
  1282. package/src/__tests__/snapshots/__snapshots__/anthropic-validation-refactor.test.ts.snap +0 -750
  1283. package/src/__tests__/snapshots/__snapshots__/dangerous-functions-refactor.test.ts.snap +0 -555
  1284. package/src/__tests__/snapshots/anthropic-validation-refactor.test.ts +0 -321
  1285. package/src/__tests__/snapshots/dangerous-functions-refactor.test.ts +0 -439
  1286. package/src/detect/ai-code/agent-tools.ts +0 -1662
  1287. package/src/detect/ai-code/byok-patterns.ts +0 -354
  1288. package/src/detect/ai-code/endpoint-protection.ts +0 -406
  1289. package/src/detect/ai-code/execution-sinks.ts +0 -1310
  1290. package/src/detect/ai-code/fingerprinting.ts +0 -774
  1291. package/src/detect/ai-code/mcp-security.ts +0 -937
  1292. package/src/detect/ai-code/model-supply-chain.ts +0 -535
  1293. package/src/detect/ai-code/package-hallucination.ts +0 -955
  1294. package/src/detect/ai-code/prompt-hygiene.ts +0 -1314
  1295. package/src/detect/ai-code/rag-safety.ts +0 -977
  1296. package/src/detect/ai-code/schema-validation.ts +0 -427
  1297. package/src/detect/secrets/patterns.ts +0 -561
  1298. package/src/detect/secrets/weak-crypto.ts +0 -485
  1299. package/src/detect/structural/__tests__/math-random-enhanced.test.ts +0 -405
  1300. package/src/detect/structural/auth-patterns.ts +0 -621
  1301. package/src/detect/structural/dangerous-functions/child-process.ts +0 -98
  1302. package/src/detect/structural/dangerous-functions/dom-xss.ts +0 -292
  1303. package/src/detect/structural/dangerous-functions/index.ts +0 -1556
  1304. package/src/detect/structural/dangerous-functions/json-parse.ts +0 -393
  1305. package/src/detect/structural/dangerous-functions/math-random.ts +0 -789
  1306. package/src/detect/structural/dangerous-functions/patterns.ts +0 -176
  1307. package/src/detect/structural/dangerous-functions/request-validation.ts +0 -153
  1308. package/src/detect/structural/dangerous-functions/utils/control-flow.ts +0 -35
  1309. package/src/detect/structural/dangerous-functions/utils/helpers.ts +0 -170
  1310. package/src/detect/structural/dangerous-functions/utils/index.ts +0 -25
  1311. package/src/detect/structural/dangerous-functions/utils/schema-validation.ts +0 -106
  1312. package/src/detect/structural/data-exposure.ts +0 -302
  1313. package/src/detect/structural/framework-checks.ts +0 -439
  1314. package/src/detect/structural/log-injection.ts +0 -254
  1315. package/src/detect/structural/logic-gates.ts +0 -256
  1316. package/src/detect/structural/risky-imports.ts +0 -197
  1317. package/src/detect/structural/security-headers.ts +0 -231
  1318. package/src/detect/structural/ssrf-detection.ts +0 -300
  1319. package/src/detect/structural/variables.ts +0 -177
  1320. package/src/detect/structural/xxe-detection.ts +0 -295
  1321. package/src/model/cross-file-taint.ts +0 -374
  1322. package/src/model/function-classifier.ts +0 -184
  1323. package/src/model/sanitiser-detection.ts +0 -268
  1324. package/src/model/sink-matcher.ts +0 -178
  1325. package/src/model/sink-patterns.ts +0 -109
  1326. package/src/model/source-discovery.ts +0 -209
  1327. package/src/model/taint-tracker.ts +0 -333
  1328. package/src/score/auto-dismiss.ts +0 -224
@@ -0,0 +1,1344 @@
1
+ /**
2
+ * Python Taint Engine Tests
3
+ *
4
+ * Tests for Python taint sources, sinks, sanitizers, CFG building,
5
+ * def-use extraction, and end-to-end taint flow detection.
6
+ */
7
+
8
+ import { parseFile, clearASTCache } from '../../parse/ast'
9
+ import type { ParsedAST } from '../../parse/ast'
10
+ import { classifySources } from '../../taint/source-classifier'
11
+ import { classifySinks } from '../../taint/sink-classifier'
12
+ import { buildSanitizerRegistry } from '../../taint/sanitizer-registry'
13
+ import { buildFileCFGs } from '../../taint/cfg-builder'
14
+ import { computeDefUse } from '../../taint/def-use'
15
+ import { analyzeTaintsForFile } from '../../taint/taint-analyzer'
16
+ import type { TaintSource, TaintSourceType } from '../../taint/types'
17
+ import type { TaintSink, TaintSinkType } from '../../taint/types'
18
+
19
+ // Side-effect imports to register taint flow rules
20
+ import '../../detect/ast-rules/taint-flow-ast'
21
+
22
+ function parsePython(code: string, filePath = 'app.py'): ParsedAST {
23
+ const ast = parseFile(code, filePath)
24
+ if (!ast) throw new Error('Failed to parse Python code')
25
+ return ast
26
+ }
27
+
28
+ function getSources(code: string): TaintSource[] {
29
+ return classifySources(parsePython(code))
30
+ }
31
+
32
+ function getSinks(code: string): TaintSink[] {
33
+ return classifySinks(parsePython(code))
34
+ }
35
+
36
+ function findSourceByType(sources: TaintSource[], type: TaintSourceType): TaintSource | undefined {
37
+ return sources.find(s => s.sourceType === type)
38
+ }
39
+
40
+ function findSinkByType(sinks: TaintSink[], type: TaintSinkType): TaintSink | undefined {
41
+ return sinks.find(s => s.sinkType === type)
42
+ }
43
+
44
+ beforeEach(() => {
45
+ clearASTCache()
46
+ })
47
+
48
+ // ============================================================================
49
+ // Source Classifier Tests
50
+ // ============================================================================
51
+
52
+ describe('Python Source Classifier', () => {
53
+ describe('Flask sources', () => {
54
+ it('detects request.form', () => {
55
+ const sources = getSources(`
56
+ from flask import request
57
+ name = request.form['name']
58
+ `)
59
+ const s = findSourceByType(sources, 'http_body')
60
+ expect(s).toBeDefined()
61
+ expect(s!.confidence).toBe('high')
62
+ expect(s!.framework).toBe('flask')
63
+ })
64
+
65
+ it('detects request.args', () => {
66
+ const sources = getSources(`
67
+ from flask import request
68
+ q = request.args.get('q')
69
+ `)
70
+ const s = findSourceByType(sources, 'http_query')
71
+ expect(s).toBeDefined()
72
+ expect(s!.confidence).toBe('high')
73
+ })
74
+
75
+ it('detects request.json', () => {
76
+ const sources = getSources(`
77
+ from flask import request
78
+ data = request.json
79
+ `)
80
+ const s = findSourceByType(sources, 'http_body')
81
+ expect(s).toBeDefined()
82
+ })
83
+
84
+ it('detects request.data', () => {
85
+ const sources = getSources(`
86
+ from flask import request
87
+ raw = request.data
88
+ `)
89
+ const s = findSourceByType(sources, 'http_body')
90
+ expect(s).toBeDefined()
91
+ })
92
+
93
+ it('detects request.values', () => {
94
+ const sources = getSources(`
95
+ from flask import request
96
+ val = request.values
97
+ `)
98
+ const s = findSourceByType(sources, 'http_body')
99
+ expect(s).toBeDefined()
100
+ })
101
+
102
+ it('detects request.files', () => {
103
+ const sources = getSources(`
104
+ from flask import request
105
+ f = request.files
106
+ `)
107
+ const s = findSourceByType(sources, 'file_upload')
108
+ expect(s).toBeDefined()
109
+ })
110
+ })
111
+
112
+ describe('Django sources', () => {
113
+ it('detects request.GET', () => {
114
+ const sources = getSources(`
115
+ def view(request):
116
+ search = request.GET['q']
117
+ `)
118
+ const s = findSourceByType(sources, 'http_query')
119
+ expect(s).toBeDefined()
120
+ expect(s!.framework).toBe('django')
121
+ })
122
+
123
+ it('detects request.POST', () => {
124
+ const sources = getSources(`
125
+ def view(request):
126
+ name = request.POST['name']
127
+ `)
128
+ const s = findSourceByType(sources, 'http_body')
129
+ expect(s).toBeDefined()
130
+ expect(s!.framework).toBe('django')
131
+ })
132
+
133
+ it('detects request.FILES', () => {
134
+ const sources = getSources(`
135
+ def view(request):
136
+ f = request.FILES
137
+ `)
138
+ const s = findSourceByType(sources, 'file_upload')
139
+ expect(s).toBeDefined()
140
+ })
141
+
142
+ it('detects request.META', () => {
143
+ const sources = getSources(`
144
+ def view(request):
145
+ host = request.META
146
+ `)
147
+ const s = findSourceByType(sources, 'http_headers')
148
+ expect(s).toBeDefined()
149
+ })
150
+
151
+ it('detects request.COOKIES', () => {
152
+ const sources = getSources(`
153
+ def view(request):
154
+ c = request.COOKIES
155
+ `)
156
+ const s = findSourceByType(sources, 'http_headers')
157
+ expect(s).toBeDefined()
158
+ })
159
+ })
160
+
161
+ describe('Python general sources', () => {
162
+ it('detects sys.argv', () => {
163
+ const sources = getSources(`
164
+ import sys
165
+ arg = sys.argv[1]
166
+ `)
167
+ const s = findSourceByType(sources, 'cli_args')
168
+ expect(s).toBeDefined()
169
+ })
170
+
171
+ it('detects os.environ', () => {
172
+ const sources = getSources(`
173
+ import os
174
+ val = os.environ
175
+ `)
176
+ const s = findSourceByType(sources, 'env_var')
177
+ expect(s).toBeDefined()
178
+ })
179
+
180
+ it('detects input() builtin', () => {
181
+ const sources = getSources(`
182
+ name = input("Enter name: ")
183
+ `)
184
+ const s = findSourceByType(sources, 'cli_args')
185
+ expect(s).toBeDefined()
186
+ expect(s!.confidence).toBe('high')
187
+ expect(s!.framework).toBe('python')
188
+ })
189
+
190
+ it('does NOT flag static strings as sources', () => {
191
+ const sources = getSources(`
192
+ name = "hello"
193
+ x = 42
194
+ `)
195
+ expect(sources).toHaveLength(0)
196
+ })
197
+ })
198
+ })
199
+
200
+ // ============================================================================
201
+ // Sink Classifier Tests
202
+ // ============================================================================
203
+
204
+ describe('Python Sink Classifier', () => {
205
+ it('detects cursor.execute(f-string) as sql_query sink', () => {
206
+ const sinks = getSinks(`
207
+ import sqlite3
208
+ conn = sqlite3.connect('db.sqlite')
209
+ cursor = conn.cursor()
210
+ name = "test"
211
+ cursor.execute(f"SELECT * FROM users WHERE name = '{name}'")
212
+ `)
213
+ const s = findSinkByType(sinks, 'sql_query')
214
+ expect(s).toBeDefined()
215
+ expect(s!.vulnerableToKinds.has('sql')).toBe(true)
216
+ })
217
+
218
+ it('does NOT flag parameterized queries', () => {
219
+ const sinks = getSinks(`
220
+ import sqlite3
221
+ cursor = sqlite3.connect('db.sqlite').cursor()
222
+ cursor.execute("SELECT * FROM users WHERE name = %s", (name,))
223
+ `)
224
+ const s = findSinkByType(sinks, 'sql_query')
225
+ expect(s).toBeUndefined()
226
+ })
227
+
228
+ it('detects subprocess.run as command_exec sink', () => {
229
+ const sinks = getSinks(`
230
+ import subprocess
231
+ cmd = "ls"
232
+ subprocess.run(cmd, shell=True)
233
+ `)
234
+ const s = findSinkByType(sinks, 'command_exec')
235
+ expect(s).toBeDefined()
236
+ })
237
+
238
+ it('detects os.system as command_exec sink', () => {
239
+ const sinks = getSinks(`
240
+ import os
241
+ cmd = user_input
242
+ os.system(cmd)
243
+ `)
244
+ const s = findSinkByType(sinks, 'command_exec')
245
+ expect(s).toBeDefined()
246
+ })
247
+
248
+ it('detects open() as path_access sink', () => {
249
+ const sinks = getSinks(`
250
+ path = user_path
251
+ f = open(path)
252
+ `)
253
+ const s = findSinkByType(sinks, 'path_access')
254
+ expect(s).toBeDefined()
255
+ })
256
+
257
+ it('detects requests.get as http_request sink', () => {
258
+ const sinks = getSinks(`
259
+ import requests
260
+ url = user_url
261
+ requests.get(url)
262
+ `)
263
+ const s = findSinkByType(sinks, 'http_request')
264
+ expect(s).toBeDefined()
265
+ })
266
+
267
+ it('does NOT flag static URL in requests.get', () => {
268
+ const sinks = getSinks(`
269
+ import requests
270
+ requests.get("https://api.example.com/data")
271
+ `)
272
+ const s = findSinkByType(sinks, 'http_request')
273
+ expect(s).toBeUndefined()
274
+ })
275
+
276
+ it('detects render_template_string as template_render sink', () => {
277
+ const sinks = getSinks(`
278
+ from flask import render_template_string
279
+ html = user_input
280
+ render_template_string(html)
281
+ `)
282
+ const s = findSinkByType(sinks, 'template_render')
283
+ expect(s).toBeDefined()
284
+ })
285
+
286
+ it('detects redirect() as redirect sink', () => {
287
+ const sinks = getSinks(`
288
+ from flask import redirect
289
+ url = user_url
290
+ redirect(url)
291
+ `)
292
+ const s = findSinkByType(sinks, 'redirect')
293
+ expect(s).toBeDefined()
294
+ })
295
+
296
+ it('detects eval() as eval sink', () => {
297
+ const sinks = getSinks(`
298
+ code = user_input
299
+ eval(code)
300
+ `)
301
+ const s = findSinkByType(sinks, 'eval')
302
+ expect(s).toBeDefined()
303
+ })
304
+
305
+ it('detects exec() as eval sink', () => {
306
+ const sinks = getSinks(`
307
+ code = user_input
308
+ exec(code)
309
+ `)
310
+ const s = findSinkByType(sinks, 'eval')
311
+ expect(s).toBeDefined()
312
+ })
313
+
314
+ it('detects Django raw() as sql_query sink', () => {
315
+ const sinks = getSinks(`
316
+ query = "SELECT * FROM users WHERE name = '" + name + "'"
317
+ result = User.objects.raw(query)
318
+ `)
319
+ const s = findSinkByType(sinks, 'sql_query')
320
+ expect(s).toBeDefined()
321
+ })
322
+
323
+ it('detects mark_safe as template_render sink', () => {
324
+ const sinks = getSinks(`
325
+ from django.utils.safestring import mark_safe
326
+ html = user_input
327
+ safe = mark_safe(html)
328
+ `)
329
+ const s = findSinkByType(sinks, 'template_render')
330
+ expect(s).toBeDefined()
331
+ })
332
+ })
333
+
334
+ // ============================================================================
335
+ // CFG Builder Tests
336
+ // ============================================================================
337
+
338
+ describe('Python CFG Builder', () => {
339
+ it('discovers function_definition', () => {
340
+ const ast = parsePython(`
341
+ def hello(name):
342
+ print(name)
343
+ `)
344
+ const cfgs = buildFileCFGs(ast)
345
+ expect(cfgs.has('hello')).toBe(true)
346
+ })
347
+
348
+ it('discovers class method as ClassName.method', () => {
349
+ const ast = parsePython(`
350
+ class MyClass:
351
+ def my_method(self):
352
+ pass
353
+ `)
354
+ const cfgs = buildFileCFGs(ast)
355
+ expect(cfgs.has('MyClass.my_method')).toBe(true)
356
+ })
357
+
358
+ it('creates <module> CFG for module-level code', () => {
359
+ const ast = parsePython(`
360
+ import os
361
+ x = 1
362
+ print(x)
363
+ `)
364
+ const cfgs = buildFileCFGs(ast)
365
+ expect(cfgs.has('<module>')).toBe(true)
366
+ })
367
+
368
+ it('handles if/elif/else branches with proper condition nodes', () => {
369
+ const ast = parsePython(`
370
+ def check(x):
371
+ if x > 0:
372
+ return "positive"
373
+ elif x < 0:
374
+ return "negative"
375
+ else:
376
+ return "zero"
377
+ `)
378
+ const cfgs = buildFileCFGs(ast)
379
+ const cfg = cfgs.get('check')
380
+ expect(cfg).toBeDefined()
381
+ // Should have 2 condition nodes (if + elif), NOT treating elif as opaque statement
382
+ const condNodes = [...cfg!.nodes.values()].filter(n => n.kind === 'condition')
383
+ expect(condNodes.length).toBe(2)
384
+ expect(condNodes.map(n => n.label)).toEqual(
385
+ expect.arrayContaining([expect.stringContaining('x > 0'), expect.stringContaining('x < 0')])
386
+ )
387
+ })
388
+
389
+ it('includes else block in CFG when elif is present', () => {
390
+ const ast = parsePython(`
391
+ def check(x):
392
+ if x > 0:
393
+ a = 1
394
+ elif x < 0:
395
+ a = 2
396
+ else:
397
+ a = 3
398
+ return a
399
+ `)
400
+ const cfgs = buildFileCFGs(ast)
401
+ const cfg = cfgs.get('check')
402
+ expect(cfg).toBeDefined()
403
+ // All three assignments should be in the CFG (not just if and elif)
404
+ const labels = [...cfg!.nodes.values()].map(n => n.label)
405
+ expect(labels.some(l => l?.includes('a = 3'))).toBe(true)
406
+ })
407
+
408
+ it('handles while loop with break', () => {
409
+ const ast = parsePython(`
410
+ def loop():
411
+ while True:
412
+ x = input()
413
+ if x == "quit":
414
+ break
415
+ `)
416
+ const cfgs = buildFileCFGs(ast)
417
+ const cfg = cfgs.get('loop')
418
+ expect(cfg).toBeDefined()
419
+ })
420
+
421
+ it('handles for loop', () => {
422
+ const ast = parsePython(`
423
+ def iterate(items):
424
+ for item in items:
425
+ print(item)
426
+ `)
427
+ const cfgs = buildFileCFGs(ast)
428
+ const cfg = cfgs.get('iterate')
429
+ expect(cfg).toBeDefined()
430
+ expect(cfg!.nodes.size).toBeGreaterThan(2)
431
+ })
432
+
433
+ it('includes finally block in CFG', () => {
434
+ const ast = parsePython(`
435
+ def safe():
436
+ try:
437
+ x = dangerous()
438
+ except ValueError as e:
439
+ print(e)
440
+ finally:
441
+ cleanup()
442
+ `)
443
+ const cfgs = buildFileCFGs(ast)
444
+ const cfg = cfgs.get('safe')
445
+ expect(cfg).toBeDefined()
446
+ // The finally block's cleanup() should be a node in the CFG
447
+ const labels = [...cfg!.nodes.values()].map(n => n.label)
448
+ expect(labels.some(l => l?.includes('cleanup'))).toBe(true)
449
+ })
450
+
451
+ it('handles raise statement', () => {
452
+ const ast = parsePython(`
453
+ def check(x):
454
+ if x < 0:
455
+ raise ValueError("negative")
456
+ return x
457
+ `)
458
+ const cfgs = buildFileCFGs(ast)
459
+ const cfg = cfgs.get('check')
460
+ expect(cfg).toBeDefined()
461
+ })
462
+ })
463
+
464
+ // ============================================================================
465
+ // Def-Use Tests
466
+ // ============================================================================
467
+
468
+ describe('Python Def-Use', () => {
469
+ it('extracts defs/uses from assignment: x = y + z', () => {
470
+ const ast = parsePython(`x = y + z`)
471
+ const root = ast.tree.rootNode
472
+ // Find the assignment node
473
+ const assignment = root.descendantsOfType('assignment')[0]
474
+ expect(assignment).toBeDefined()
475
+ const { defs, uses } = computeDefUse(assignment)
476
+ expect(defs.has('x')).toBe(true)
477
+ expect(uses.has('y')).toBe(true)
478
+ expect(uses.has('z')).toBe(true)
479
+ })
480
+
481
+ it('extracts defs/uses from function call: result = func(a, b)', () => {
482
+ const ast = parsePython(`result = func(a, b)`)
483
+ const root = ast.tree.rootNode
484
+ const assignment = root.descendantsOfType('assignment')[0]
485
+ const { defs, uses } = computeDefUse(assignment)
486
+ expect(defs.has('result')).toBe(true)
487
+ expect(uses.has('func')).toBe(true)
488
+ expect(uses.has('a')).toBe(true)
489
+ expect(uses.has('b')).toBe(true)
490
+ })
491
+
492
+ it('extracts defs/uses from attribute assignment: obj.attr = val', () => {
493
+ const ast = parsePython(`obj.attr = val`)
494
+ const root = ast.tree.rootNode
495
+ const assignment = root.descendantsOfType('assignment')[0]
496
+ const { defs, uses } = computeDefUse(assignment)
497
+ expect(defs.has('obj')).toBe(true)
498
+ expect(uses.has('obj')).toBe(true)
499
+ expect(uses.has('val')).toBe(true)
500
+ })
501
+
502
+ it('extracts defs from tuple unpacking: a, b = get_pair()', () => {
503
+ const ast = parsePython(`a, b = get_pair()`)
504
+ const root = ast.tree.rootNode
505
+ const assignment = root.descendantsOfType('assignment')[0]
506
+ const { defs, uses } = computeDefUse(assignment)
507
+ expect(defs.has('a')).toBe(true)
508
+ expect(defs.has('b')).toBe(true)
509
+ expect(uses.has('get_pair')).toBe(true)
510
+ })
511
+
512
+ it('extracts uses from augmented assignment: x += y', () => {
513
+ const ast = parsePython(`x += y`)
514
+ const root = ast.tree.rootNode
515
+ const augmented = root.descendantsOfType('augmented_assignment')[0]
516
+ const { defs, uses } = computeDefUse(augmented)
517
+ expect(defs.has('x')).toBe(true)
518
+ expect(uses.has('x')).toBe(true)
519
+ expect(uses.has('y')).toBe(true)
520
+ })
521
+
522
+ it('does not recurse into function_definition body', () => {
523
+ const ast = parsePython(`
524
+ def foo():
525
+ x = 1
526
+ y = foo()
527
+ `)
528
+ const root = ast.tree.rootNode
529
+ // The module-level assignment
530
+ const assignments = root.descendantsOfType('assignment')
531
+ // Filter to module-level assignment only (y = foo())
532
+ const moduleAssignment = assignments.find(a => a.parent?.type === 'expression_statement' && a.parent?.parent?.type === 'module')
533
+ expect(moduleAssignment).toBeDefined()
534
+ const { defs, uses } = computeDefUse(moduleAssignment!)
535
+ expect(defs.has('y')).toBe(true)
536
+ expect(uses.has('foo')).toBe(true)
537
+ // Should NOT have x from inside the function
538
+ expect(defs.has('x')).toBe(false)
539
+ })
540
+
541
+ it('handles Python keyword arguments', () => {
542
+ const ast = parsePython(`result = func(key=value)`)
543
+ const root = ast.tree.rootNode
544
+ const assignment = root.descendantsOfType('assignment')[0]
545
+ const { defs, uses } = computeDefUse(assignment)
546
+ expect(defs.has('result')).toBe(true)
547
+ expect(uses.has('func')).toBe(true)
548
+ expect(uses.has('value')).toBe(true)
549
+ })
550
+
551
+ it('skips Python keyword identifiers (None, True, False, self)', () => {
552
+ const ast = parsePython(`x = None`)
553
+ const root = ast.tree.rootNode
554
+ const assignment = root.descendantsOfType('assignment')[0]
555
+ const { defs, uses } = computeDefUse(assignment)
556
+ expect(defs.has('x')).toBe(true)
557
+ // None should be in literals, not uses
558
+ expect(uses.has('None')).toBe(false)
559
+ })
560
+ })
561
+
562
+ // ============================================================================
563
+ // Sanitizer Tests
564
+ // ============================================================================
565
+
566
+ describe('Python Sanitizer Registry', () => {
567
+ it('detects int() as universal sanitizer', () => {
568
+ const ast = parsePython(`
569
+ x = input()
570
+ safe = int(x)
571
+ `)
572
+ const sanitizers = buildSanitizerRegistry(ast)
573
+ const intSan = sanitizers.find(s => s.name === 'int')
574
+ expect(intSan).toBeDefined()
575
+ expect([...intSan!.clearsKinds]).toEqual(expect.arrayContaining(['sql', 'xss', 'command']))
576
+ })
577
+
578
+ it('detects float() as universal sanitizer', () => {
579
+ const ast = parsePython(`
580
+ x = input()
581
+ safe = float(x)
582
+ `)
583
+ const sanitizers = buildSanitizerRegistry(ast)
584
+ expect(sanitizers.find(s => s.name === 'float')).toBeDefined()
585
+ })
586
+
587
+ it('detects bool() as universal sanitizer', () => {
588
+ const ast = parsePython(`
589
+ x = input()
590
+ safe = bool(x)
591
+ `)
592
+ const sanitizers = buildSanitizerRegistry(ast)
593
+ expect(sanitizers.find(s => s.name === 'bool')).toBeDefined()
594
+ })
595
+
596
+ it('detects bleach.clean as xss sanitizer when imported', () => {
597
+ const ast = parsePython(`
598
+ import bleach
599
+ html = user_input
600
+ safe = bleach.clean(html)
601
+ `)
602
+ const sanitizers = buildSanitizerRegistry(ast)
603
+ const bleachSan = sanitizers.find(s => s.name === 'bleach.clean')
604
+ expect(bleachSan).toBeDefined()
605
+ expect(bleachSan!.clearsKinds.has('xss')).toBe(true)
606
+ })
607
+
608
+ it('detects shlex.quote as command sanitizer when imported', () => {
609
+ const ast = parsePython(`
610
+ import shlex
611
+ cmd = user_input
612
+ safe = shlex.quote(cmd)
613
+ `)
614
+ const sanitizers = buildSanitizerRegistry(ast)
615
+ const shlexSan = sanitizers.find(s => s.name === 'shlex.quote')
616
+ expect(shlexSan).toBeDefined()
617
+ expect(shlexSan!.clearsKinds.has('command')).toBe(true)
618
+ })
619
+ })
620
+
621
+ // ============================================================================
622
+ // End-to-End Taint Flow Tests
623
+ // ============================================================================
624
+
625
+ describe('Python End-to-End Taint Flow', () => {
626
+ it('detects Flask SQL injection: request.form → cursor.execute(f-string)', () => {
627
+ const ast = parsePython(`
628
+ from flask import request
629
+ import sqlite3
630
+
631
+ def search():
632
+ name = request.form['name']
633
+ conn = sqlite3.connect('db.sqlite')
634
+ cursor = conn.cursor()
635
+ cursor.execute(f"SELECT * FROM users WHERE name = '{name}'")
636
+ `, 'routes/search.py')
637
+ const findings = analyzeTaintsForFile(ast, ast.filePath)
638
+ const sqlFinding = findings.find(f => f.matchingKinds.has('sql'))
639
+ expect(sqlFinding).toBeDefined()
640
+ expect(sqlFinding!.source.sourceType).toBe('http_body')
641
+ expect(sqlFinding!.sink.sinkType).toBe('sql_query')
642
+ })
643
+
644
+ it('detects Django command injection: request.POST → os.system', () => {
645
+ const ast = parsePython(`
646
+ import os
647
+
648
+ def run_command(request):
649
+ cmd = request.POST['cmd']
650
+ os.system(cmd)
651
+ `, 'views/admin.py')
652
+ const findings = analyzeTaintsForFile(ast, ast.filePath)
653
+ const cmdFinding = findings.find(f => f.matchingKinds.has('command'))
654
+ expect(cmdFinding).toBeDefined()
655
+ expect(cmdFinding!.source.sourceType).toBe('http_body')
656
+ expect(cmdFinding!.sink.sinkType).toBe('command_exec')
657
+ })
658
+
659
+ it('detects Flask SSRF: request.args → requests.get', () => {
660
+ const ast = parsePython(`
661
+ from flask import request
662
+ import requests
663
+
664
+ def proxy():
665
+ url = request.args['url']
666
+ resp = requests.get(url)
667
+ `, 'routes/proxy.py')
668
+ const findings = analyzeTaintsForFile(ast, ast.filePath)
669
+ const ssrfFinding = findings.find(f => f.matchingKinds.has('ssrf'))
670
+ expect(ssrfFinding).toBeDefined()
671
+ expect(ssrfFinding!.sink.sinkType).toBe('http_request')
672
+ })
673
+
674
+ it('detects path traversal: request.form → open()', () => {
675
+ const ast = parsePython(`
676
+ from flask import request
677
+
678
+ def read_file():
679
+ path = request.form['file']
680
+ f = open(path)
681
+ `, 'routes/files.py')
682
+ const findings = analyzeTaintsForFile(ast, ast.filePath)
683
+ const pathFinding = findings.find(f => f.matchingKinds.has('path'))
684
+ expect(pathFinding).toBeDefined()
685
+ expect(pathFinding!.sink.sinkType).toBe('path_access')
686
+ })
687
+
688
+ it('does NOT flag sanitized flow: request.form → int() → cursor.execute', () => {
689
+ // int() sanitizer must be on a SEPARATE line from the source assignment.
690
+ // At the source node, seed re-injection overrides sanitizers (by design).
691
+ const ast = parsePython(`
692
+ from flask import request
693
+ import sqlite3
694
+
695
+ def get_user():
696
+ raw_id = request.form['id']
697
+ user_id = int(raw_id)
698
+ conn = sqlite3.connect('db.sqlite')
699
+ cursor = conn.cursor()
700
+ cursor.execute(f"SELECT * FROM users WHERE id = {user_id}")
701
+ `, 'routes/users.py')
702
+ const findings = analyzeTaintsForFile(ast, ast.filePath)
703
+ const sqlFinding = findings.find(f => f.matchingKinds.has('sql'))
704
+ // int() sanitizes all taint kinds, so no SQL finding should appear
705
+ expect(sqlFinding).toBeUndefined()
706
+ })
707
+
708
+ it('does NOT flag parameterized query', () => {
709
+ const ast = parsePython(`
710
+ from flask import request
711
+ import sqlite3
712
+
713
+ def safe_search():
714
+ name = request.form['name']
715
+ conn = sqlite3.connect('db.sqlite')
716
+ cursor = conn.cursor()
717
+ cursor.execute("SELECT * FROM users WHERE name = %s", (name,))
718
+ `, 'routes/safe.py')
719
+ const findings = analyzeTaintsForFile(ast, ast.filePath)
720
+ const sqlFinding = findings.find(f => f.matchingKinds.has('sql'))
721
+ expect(sqlFinding).toBeUndefined()
722
+ })
723
+
724
+ it('detects multi-step taint: form → variable → f-string → execute', () => {
725
+ const ast = parsePython(`
726
+ from flask import request
727
+ import sqlite3
728
+
729
+ def complex_search():
730
+ name = request.form['name']
731
+ query = f"SELECT * FROM users WHERE name = '{name}'"
732
+ conn = sqlite3.connect('db.sqlite')
733
+ cursor = conn.cursor()
734
+ cursor.execute(query)
735
+ `, 'routes/complex.py')
736
+ const findings = analyzeTaintsForFile(ast, ast.filePath)
737
+ const sqlFinding = findings.find(f => f.matchingKinds.has('sql'))
738
+ expect(sqlFinding).toBeDefined()
739
+ })
740
+
741
+ it('detects eval with user input', () => {
742
+ const ast = parsePython(`
743
+ from flask import request
744
+
745
+ def dangerous():
746
+ code = request.form['code']
747
+ eval(code)
748
+ `, 'routes/danger.py')
749
+ const findings = analyzeTaintsForFile(ast, ast.filePath)
750
+ const cmdFinding = findings.find(f => f.matchingKinds.has('command'))
751
+ expect(cmdFinding).toBeDefined()
752
+ expect(cmdFinding!.sink.sinkType).toBe('eval')
753
+ })
754
+
755
+ it('detects redirect with user input', () => {
756
+ const ast = parsePython(`
757
+ from flask import request, redirect
758
+
759
+ def redir():
760
+ url = request.args['next']
761
+ return redirect(url)
762
+ `, 'routes/redir.py')
763
+ const findings = analyzeTaintsForFile(ast, ast.filePath)
764
+ const ssrfFinding = findings.find(f => f.matchingKinds.has('ssrf'))
765
+ expect(ssrfFinding).toBeDefined()
766
+ expect(ssrfFinding!.sink.sinkType).toBe('redirect')
767
+ })
768
+
769
+ it('detects render_template_string with user input (XSS)', () => {
770
+ const ast = parsePython(`
771
+ from flask import request, render_template_string
772
+
773
+ def template():
774
+ name = request.form['name']
775
+ return render_template_string(name)
776
+ `, 'routes/template.py')
777
+ const findings = analyzeTaintsForFile(ast, ast.filePath)
778
+ const xssFinding = findings.find(f => f.matchingKinds.has('xss'))
779
+ expect(xssFinding).toBeDefined()
780
+ expect(xssFinding!.sink.sinkType).toBe('template_render')
781
+ })
782
+
783
+ it('detects taint flow through else block of if/elif/else', () => {
784
+ const ast = parsePython(`
785
+ from flask import request
786
+ import sqlite3
787
+
788
+ def search(mode):
789
+ if mode == 'safe':
790
+ name = 'default'
791
+ elif mode == 'other':
792
+ name = 'other'
793
+ else:
794
+ name = request.form['name']
795
+ conn = sqlite3.connect('db.sqlite')
796
+ cursor = conn.cursor()
797
+ cursor.execute(f"SELECT * FROM users WHERE name = '{name}'")
798
+ `, 'routes/elif_else.py')
799
+ const findings = analyzeTaintsForFile(ast, ast.filePath)
800
+ const sqlFinding = findings.find(f => f.matchingKinds.has('sql'))
801
+ expect(sqlFinding).toBeDefined()
802
+ expect(sqlFinding!.source.sourceType).toBe('http_body')
803
+ expect(sqlFinding!.sink.sinkType).toBe('sql_query')
804
+ })
805
+
806
+ it('detects taint flow through elif block', () => {
807
+ const ast = parsePython(`
808
+ from flask import request
809
+ import os
810
+
811
+ def run(mode):
812
+ if mode == 'safe':
813
+ cmd = 'echo safe'
814
+ elif mode == 'user':
815
+ cmd = request.form['cmd']
816
+ else:
817
+ cmd = 'echo default'
818
+ os.system(cmd)
819
+ `, 'routes/elif.py')
820
+ const findings = analyzeTaintsForFile(ast, ast.filePath)
821
+ const cmdFinding = findings.find(f => f.matchingKinds.has('command'))
822
+ expect(cmdFinding).toBeDefined()
823
+ expect(cmdFinding!.sink.sinkType).toBe('command_exec')
824
+ })
825
+ })
826
+
827
+ // ============================================================================
828
+ // Python LLM Output Source Tests
829
+ // ============================================================================
830
+
831
+ describe('Python LLM output sources', () => {
832
+ it('detects OpenAI response.choices[0].message.content as llm_output', () => {
833
+ const sources = getSources(`
834
+ from openai import OpenAI
835
+ client = OpenAI()
836
+ response = client.chat.completions.create(model="gpt-4", messages=[])
837
+ text = response.choices[0].message.content
838
+ `)
839
+ const s = findSourceByType(sources, 'llm_output')
840
+ expect(s).toBeDefined()
841
+ })
842
+
843
+ it('detects Anthropic response.content[0].text as llm_output', () => {
844
+ const sources = getSources(`
845
+ import anthropic
846
+ client = anthropic.Anthropic()
847
+ response = client.messages.create(model="claude-3", messages=[])
848
+ text = response.content[0].text
849
+ `)
850
+ const s = findSourceByType(sources, 'llm_output')
851
+ expect(s).toBeDefined()
852
+ })
853
+
854
+ it('detects LlamaIndex response.response as llm_output', () => {
855
+ const sources = getSources(`
856
+ from llama_index import VectorStoreIndex
857
+ index = VectorStoreIndex.from_documents(docs)
858
+ query_engine = index.as_query_engine()
859
+ response = query_engine.query("question")
860
+ text = response.response
861
+ `)
862
+ const s = findSourceByType(sources, 'llm_output')
863
+ expect(s).toBeDefined()
864
+ })
865
+
866
+ it('detects import-aware LLM call return: from openai import OpenAI', () => {
867
+ const sources = getSources(`
868
+ from openai import OpenAI
869
+ client = OpenAI()
870
+ result = client.chat.completions.create(model="gpt-4", messages=[])
871
+ `)
872
+ const llmSource = sources.find(s => s.sourceType === 'llm_output' && s.variable === 'result')
873
+ expect(llmSource).toBeDefined()
874
+ expect(llmSource!.confidence).toBe('high')
875
+ })
876
+
877
+ it('detects import-aware LLM call return: from langchain_openai import ChatOpenAI', () => {
878
+ const sources = getSources(`
879
+ from langchain_openai import ChatOpenAI
880
+ llm = ChatOpenAI(model="gpt-4")
881
+ result = llm.invoke("hello")
882
+ `)
883
+ const llmSource = sources.find(s => s.sourceType === 'llm_output' && s.variable === 'result')
884
+ expect(llmSource).toBeDefined()
885
+ })
886
+ })
887
+
888
+ // ============================================================================
889
+ // FastAPI Source Tests
890
+ // ============================================================================
891
+
892
+ describe('FastAPI sources', () => {
893
+ it('detects Query() parameter as http_query source', () => {
894
+ const sources = getSources(`
895
+ from fastapi import FastAPI, Query
896
+
897
+ app = FastAPI()
898
+
899
+ @app.get("/search")
900
+ def search(q: str = Query(...)):
901
+ return {"q": q}
902
+ `)
903
+ const s = findSourceByType(sources, 'http_query')
904
+ expect(s).toBeDefined()
905
+ expect(s!.framework).toBe('fastapi')
906
+ expect(s!.variable).toBe('q')
907
+ })
908
+
909
+ it('detects Body() parameter as http_body source', () => {
910
+ const sources = getSources(`
911
+ from fastapi import FastAPI, Body
912
+
913
+ app = FastAPI()
914
+
915
+ @app.post("/submit")
916
+ def submit(data: dict = Body(...)):
917
+ return data
918
+ `)
919
+ const s = findSourceByType(sources, 'http_body')
920
+ expect(s).toBeDefined()
921
+ expect(s!.framework).toBe('fastapi')
922
+ })
923
+
924
+ it('detects Form() parameter as form_data source', () => {
925
+ const sources = getSources(`
926
+ from fastapi import FastAPI, Form
927
+
928
+ app = FastAPI()
929
+
930
+ @app.post("/login")
931
+ def login(username: str = Form(...)):
932
+ return {"user": username}
933
+ `)
934
+ const s = findSourceByType(sources, 'form_data')
935
+ expect(s).toBeDefined()
936
+ expect(s!.framework).toBe('fastapi')
937
+ })
938
+
939
+ it('detects request.query_params as http_query source', () => {
940
+ const sources = getSources(`
941
+ from fastapi import Request
942
+
943
+ async def handler(request: Request):
944
+ q = request.query_params
945
+ `)
946
+ const s = findSourceByType(sources, 'http_query')
947
+ expect(s).toBeDefined()
948
+ expect(s!.framework).toBe('fastapi')
949
+ })
950
+
951
+ it('does NOT flag plain function parameters without FastAPI decorators', () => {
952
+ const sources = getSources(`
953
+ def plain_function(q: str = "default"):
954
+ return q
955
+ `)
956
+ const s = findSourceByType(sources, 'http_query')
957
+ expect(s).toBeUndefined()
958
+ })
959
+ })
960
+
961
+ // ============================================================================
962
+ // Python LLM Prompt Sink Tests
963
+ // ============================================================================
964
+
965
+ describe('Python LLM prompt sinks', () => {
966
+ // P1: OpenAI
967
+ it('detects OpenAI messages with system role as system_prompt sink', () => {
968
+ const sinks = getSinks(`
969
+ from openai import OpenAI
970
+ client = OpenAI()
971
+ text = dynamic_input
972
+ client.chat.completions.create(
973
+ model="gpt-4",
974
+ messages=[{"role": "system", "content": text}]
975
+ )
976
+ `)
977
+ const s = findSinkByType(sinks, 'system_prompt')
978
+ expect(s).toBeDefined()
979
+ })
980
+
981
+ it('does NOT flag OpenAI messages with user role (user role is intended for user input)', () => {
982
+ const sinks = getSinks(`
983
+ from openai import OpenAI
984
+ client = OpenAI()
985
+ msg = dynamic_input
986
+ client.chat.completions.create(
987
+ model="gpt-4",
988
+ messages=[{"role": "user", "content": msg}]
989
+ )
990
+ `)
991
+ const promptSinks = sinks.filter(s => s.sinkType === 'prompt_construction' || s.sinkType === 'system_prompt')
992
+ expect(promptSinks).toHaveLength(0)
993
+ })
994
+
995
+ it('does NOT flag static string messages in OpenAI call', () => {
996
+ const sinks = getSinks(`
997
+ from openai import OpenAI
998
+ client = OpenAI()
999
+ client.chat.completions.create(
1000
+ model="gpt-4",
1001
+ messages=[{"role": "user", "content": "Hello, how are you?"}]
1002
+ )
1003
+ `)
1004
+ const promptSink = sinks.find(s => s.sinkType === 'prompt_construction' || s.sinkType === 'system_prompt')
1005
+ expect(promptSink).toBeUndefined()
1006
+ })
1007
+
1008
+ // P2: Anthropic
1009
+ it('detects Anthropic system= keyword as system_prompt sink', () => {
1010
+ const sinks = getSinks(`
1011
+ import anthropic
1012
+ client = anthropic.Anthropic()
1013
+ sys_prompt = dynamic_text
1014
+ client.messages.create(
1015
+ model="claude-3",
1016
+ system=sys_prompt,
1017
+ messages=[]
1018
+ )
1019
+ `)
1020
+ const s = findSinkByType(sinks, 'system_prompt')
1021
+ expect(s).toBeDefined()
1022
+ })
1023
+
1024
+ it('does NOT flag Anthropic messages with user role (user role is intended for user input)', () => {
1025
+ const sinks = getSinks(`
1026
+ import anthropic
1027
+ client = anthropic.Anthropic()
1028
+ msg = user_input
1029
+ client.messages.create(
1030
+ model="claude-3",
1031
+ messages=[{"role": "user", "content": msg}]
1032
+ )
1033
+ `)
1034
+ const promptSinks = sinks.filter(s => s.sinkType === 'prompt_construction' || s.sinkType === 'system_prompt')
1035
+ expect(promptSinks).toHaveLength(0)
1036
+ })
1037
+
1038
+ // P3: LangChain
1039
+ it('detects SystemMessage(content=dynamic) as system_prompt sink', () => {
1040
+ const sinks = getSinks(`
1041
+ from langchain_core.messages import SystemMessage
1042
+ text = user_input
1043
+ msg = SystemMessage(content=text)
1044
+ `)
1045
+ const s = findSinkByType(sinks, 'system_prompt')
1046
+ expect(s).toBeDefined()
1047
+ })
1048
+
1049
+ it('detects HumanMessage(content=dynamic) as prompt_construction sink', () => {
1050
+ const sinks = getSinks(`
1051
+ from langchain_core.messages import HumanMessage
1052
+ text = user_input
1053
+ msg = HumanMessage(content=text)
1054
+ `)
1055
+ const s = findSinkByType(sinks, 'prompt_construction')
1056
+ expect(s).toBeDefined()
1057
+ })
1058
+
1059
+ it('detects SystemMessage(dynamic) positional arg as system_prompt sink', () => {
1060
+ const sinks = getSinks(`
1061
+ from langchain_core.messages import SystemMessage
1062
+ text = user_input
1063
+ msg = SystemMessage(text)
1064
+ `)
1065
+ const s = findSinkByType(sinks, 'system_prompt')
1066
+ expect(s).toBeDefined()
1067
+ })
1068
+
1069
+ // P4: Generic LLM methods
1070
+ it('detects llm.invoke(user_input) as prompt_construction sink', () => {
1071
+ const sinks = getSinks(`
1072
+ from langchain_openai import ChatOpenAI
1073
+ llm = ChatOpenAI()
1074
+ text = user_input
1075
+ llm.invoke(text)
1076
+ `)
1077
+ const s = findSinkByType(sinks, 'prompt_construction')
1078
+ expect(s).toBeDefined()
1079
+ })
1080
+
1081
+ it('detects chain.run(user_input) as prompt_construction sink', () => {
1082
+ const sinks = getSinks(`
1083
+ from langchain_openai import ChatOpenAI
1084
+ chain = ChatOpenAI()
1085
+ text = user_input
1086
+ chain.run(text)
1087
+ `)
1088
+ const s = findSinkByType(sinks, 'prompt_construction')
1089
+ expect(s).toBeDefined()
1090
+ })
1091
+
1092
+ // P5: messages.append
1093
+ it('detects messages.append({"role": "system", "content": dynamic}) as system_prompt', () => {
1094
+ const sinks = getSinks(`
1095
+ messages = []
1096
+ text = user_input
1097
+ messages.append({"role": "system", "content": text})
1098
+ `)
1099
+ const s = findSinkByType(sinks, 'system_prompt')
1100
+ expect(s).toBeDefined()
1101
+ })
1102
+
1103
+ it('does NOT flag messages.append with user role (user role is intended for user input)', () => {
1104
+ const sinks = getSinks(`
1105
+ messages = []
1106
+ text = user_input
1107
+ messages.append({"role": "user", "content": text})
1108
+ `)
1109
+ const promptSinks = sinks.filter(s => s.sinkType === 'prompt_construction' || s.sinkType === 'system_prompt')
1110
+ expect(promptSinks).toHaveLength(0)
1111
+ })
1112
+
1113
+ // P6: Google AI
1114
+ it('detects model.generate_content(dynamic) as prompt_construction sink', () => {
1115
+ const sinks = getSinks(`
1116
+ import google.generativeai as genai
1117
+ model = genai.GenerativeModel('gemini-pro')
1118
+ text = user_input
1119
+ model.generate_content(text)
1120
+ `)
1121
+ const s = findSinkByType(sinks, 'prompt_construction')
1122
+ expect(s).toBeDefined()
1123
+ })
1124
+
1125
+ // P7: LlamaIndex
1126
+ it('detects query_engine.query(user_input) as prompt_construction sink', () => {
1127
+ const sinks = getSinks(`
1128
+ from llama_index import VectorStoreIndex
1129
+ query_engine = VectorStoreIndex.from_documents(docs).as_query_engine()
1130
+ text = user_input
1131
+ query_engine.query(text)
1132
+ `)
1133
+ const s = findSinkByType(sinks, 'prompt_construction')
1134
+ expect(s).toBeDefined()
1135
+ })
1136
+
1137
+ // Negative
1138
+ it('does NOT flag static LLM calls with hardcoded messages', () => {
1139
+ const sinks = getSinks(`
1140
+ from langchain_core.messages import SystemMessage
1141
+ msg = SystemMessage("You are a helpful assistant.")
1142
+ `)
1143
+ const promptSink = sinks.find(s => s.sinkType === 'system_prompt' || s.sinkType === 'prompt_construction')
1144
+ expect(promptSink).toBeUndefined()
1145
+ })
1146
+ })
1147
+
1148
+ // ============================================================================
1149
+ // Python LLM Taint Flow Tests
1150
+ // ============================================================================
1151
+
1152
+ describe('Python LLM Taint Flow', () => {
1153
+ // Prompt injection (user input → LLM prompt)
1154
+ it('Flask request.form → OpenAI messages (user role) = no finding (user role is safe)', () => {
1155
+ const ast = parsePython(`
1156
+ from flask import request
1157
+ from openai import OpenAI
1158
+
1159
+ def chat():
1160
+ user_msg = request.form['message']
1161
+ client = OpenAI()
1162
+ response = client.chat.completions.create(
1163
+ model="gpt-4",
1164
+ messages=[{"role": "user", "content": user_msg}]
1165
+ )
1166
+ `, 'routes/chat.py')
1167
+ const findings = analyzeTaintsForFile(ast, ast.filePath)
1168
+ const promptFinding = findings.find(f => [...f.matchingKinds].includes('prompt'))
1169
+ // User-role messages are the intended place for user input — no prompt injection
1170
+ expect(promptFinding).toBeUndefined()
1171
+ })
1172
+
1173
+ it('Flask request.args → Anthropic system= keyword = prompt injection', () => {
1174
+ const ast = parsePython(`
1175
+ from flask import request
1176
+ import anthropic
1177
+
1178
+ def chat():
1179
+ system_text = request.args['system']
1180
+ client = anthropic.Anthropic()
1181
+ response = client.messages.create(
1182
+ model="claude-3",
1183
+ system=system_text,
1184
+ messages=[]
1185
+ )
1186
+ `, 'routes/anthropic_chat.py')
1187
+ const findings = analyzeTaintsForFile(ast, ast.filePath)
1188
+ const promptFinding = findings.find(f => [...f.matchingKinds].includes('prompt'))
1189
+ expect(promptFinding).toBeDefined()
1190
+ expect(promptFinding!.sink.sinkType).toBe('system_prompt')
1191
+ })
1192
+
1193
+ it('Django request.POST → LangChain HumanMessage = prompt injection', () => {
1194
+ const ast = parsePython(`
1195
+ from langchain_core.messages import HumanMessage
1196
+
1197
+ def chat_view(request):
1198
+ text = request.POST['message']
1199
+ msg = HumanMessage(content=text)
1200
+ `, 'views/chat.py')
1201
+ const findings = analyzeTaintsForFile(ast, ast.filePath)
1202
+ const promptFinding = findings.find(f => [...f.matchingKinds].includes('prompt'))
1203
+ expect(promptFinding).toBeDefined()
1204
+ expect(promptFinding!.sink.sinkType).toBe('prompt_construction')
1205
+ })
1206
+
1207
+ it('FastAPI request.query_params → OpenAI messages (user role) = no finding (user role is safe)', () => {
1208
+ const ast = parsePython(`
1209
+ from fastapi import FastAPI, Request
1210
+ from openai import OpenAI
1211
+
1212
+ app = FastAPI()
1213
+
1214
+ @app.get("/ask")
1215
+ async def ask(request: Request):
1216
+ q = request.query_params
1217
+ client = OpenAI()
1218
+ response = client.chat.completions.create(
1219
+ model="gpt-4",
1220
+ messages=[{"role": "user", "content": q}]
1221
+ )
1222
+ `, 'routes/ask.py')
1223
+ const findings = analyzeTaintsForFile(ast, ast.filePath)
1224
+ const promptFinding = findings.find(f => [...f.matchingKinds].includes('prompt'))
1225
+ // User-role messages are the intended place for user input — no prompt injection
1226
+ expect(promptFinding).toBeUndefined()
1227
+ })
1228
+
1229
+ it('multi-step: request.form → variable → f-string → SystemMessage', () => {
1230
+ const ast = parsePython(`
1231
+ from flask import request
1232
+ from langchain_core.messages import SystemMessage
1233
+
1234
+ def chat():
1235
+ persona = request.form['persona']
1236
+ prompt = f"You are a {persona}. Be helpful."
1237
+ msg = SystemMessage(content=prompt)
1238
+ `, 'routes/multistep.py')
1239
+ const findings = analyzeTaintsForFile(ast, ast.filePath)
1240
+ const promptFinding = findings.find(f => [...f.matchingKinds].includes('prompt'))
1241
+ expect(promptFinding).toBeDefined()
1242
+ expect(promptFinding!.sink.sinkType).toBe('system_prompt')
1243
+ })
1244
+
1245
+ // Unsafe execution (LLM output → dangerous sink)
1246
+ it('OpenAI response.choices[0].message.content → eval() = command taint', () => {
1247
+ const ast = parsePython(`
1248
+ from openai import OpenAI
1249
+
1250
+ def execute():
1251
+ client = OpenAI()
1252
+ response = client.chat.completions.create(
1253
+ model="gpt-4",
1254
+ messages=[{"role": "user", "content": "write code"}]
1255
+ )
1256
+ code = response.choices[0].message.content
1257
+ eval(code)
1258
+ `, 'routes/exec.py')
1259
+ const findings = analyzeTaintsForFile(ast, ast.filePath)
1260
+ const cmdFinding = findings.find(f => [...f.matchingKinds].includes('command'))
1261
+ expect(cmdFinding).toBeDefined()
1262
+ expect(cmdFinding!.source.sourceType).toBe('llm_output')
1263
+ })
1264
+
1265
+ it('OpenAI response → subprocess.run() = command taint', () => {
1266
+ const ast = parsePython(`
1267
+ from openai import OpenAI
1268
+ import subprocess
1269
+
1270
+ def run_cmd():
1271
+ client = OpenAI()
1272
+ response = client.chat.completions.create(
1273
+ model="gpt-4",
1274
+ messages=[{"role": "user", "content": "give me a command"}]
1275
+ )
1276
+ cmd = response.choices[0].message.content
1277
+ subprocess.run(cmd, shell=True)
1278
+ `, 'routes/run_cmd.py')
1279
+ const findings = analyzeTaintsForFile(ast, ast.filePath)
1280
+ const cmdFinding = findings.find(f => [...f.matchingKinds].includes('command'))
1281
+ expect(cmdFinding).toBeDefined()
1282
+ expect(cmdFinding!.source.sourceType).toBe('llm_output')
1283
+ expect(cmdFinding!.sink.sinkType).toBe('command_exec')
1284
+ })
1285
+
1286
+ it('LLM output variable → cursor.execute(f-string) = sql taint', () => {
1287
+ const ast = parsePython(`
1288
+ from openai import OpenAI
1289
+ import sqlite3
1290
+
1291
+ def query_db():
1292
+ client = OpenAI()
1293
+ response = client.chat.completions.create(
1294
+ model="gpt-4",
1295
+ messages=[{"role": "user", "content": "generate SQL"}]
1296
+ )
1297
+ query = response.choices[0].message.content
1298
+ conn = sqlite3.connect('db.sqlite')
1299
+ cursor = conn.cursor()
1300
+ cursor.execute(query)
1301
+ `, 'routes/query.py')
1302
+ const findings = analyzeTaintsForFile(ast, ast.filePath)
1303
+ const sqlFinding = findings.find(f => [...f.matchingKinds].includes('sql'))
1304
+ expect(sqlFinding).toBeDefined()
1305
+ expect(sqlFinding!.source.sourceType).toBe('llm_output')
1306
+ expect(sqlFinding!.sink.sinkType).toBe('sql_query')
1307
+ })
1308
+
1309
+ // Negative cases
1310
+ it('does NOT flag sanitized: input → int() → messages', () => {
1311
+ const ast = parsePython(`
1312
+ from flask import request
1313
+ from openai import OpenAI
1314
+
1315
+ def ask():
1316
+ raw_count = request.form['count']
1317
+ count = int(raw_count)
1318
+ client = OpenAI()
1319
+ response = client.chat.completions.create(
1320
+ model="gpt-4",
1321
+ messages=[{"role": "user", "content": count}]
1322
+ )
1323
+ `, 'routes/sanitized.py')
1324
+ const findings = analyzeTaintsForFile(ast, ast.filePath)
1325
+ const promptFinding = findings.find(f => [...f.matchingKinds].includes('prompt'))
1326
+ expect(promptFinding).toBeUndefined()
1327
+ })
1328
+
1329
+ it('does NOT flag hardcoded prompt: static string → OpenAI messages', () => {
1330
+ const ast = parsePython(`
1331
+ from openai import OpenAI
1332
+
1333
+ def safe_chat():
1334
+ client = OpenAI()
1335
+ response = client.chat.completions.create(
1336
+ model="gpt-4",
1337
+ messages=[{"role": "system", "content": "You are helpful."}]
1338
+ )
1339
+ `, 'routes/safe.py')
1340
+ const findings = analyzeTaintsForFile(ast, ast.filePath)
1341
+ const promptFinding = findings.find(f => [...f.matchingKinds].includes('prompt'))
1342
+ expect(promptFinding).toBeUndefined()
1343
+ })
1344
+ })