@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,1576 @@
1
+ "use strict";
2
+ /**
3
+ * Taint Propagation Engine
4
+ *
5
+ * Forward worklist dataflow analysis. Seeds taint at sources, propagates
6
+ * through CFG to fixpoint, then checks if tainted data reaches sinks
7
+ * without proper sanitization.
8
+ *
9
+ * Algorithm:
10
+ * 1. Map sources/sinks/sanitizers to CFG nodes via AST containment
11
+ * 2. Seed source nodes with taint state
12
+ * 3. Worklist: propagate taint forward through CFG, applying transfer
13
+ * functions at each node (assignment, call, destructuring, etc.)
14
+ * 4. At fixpoint: check each sink node for matching taint kinds
15
+ * 5. Reconstruct source-to-sink paths via backward slice
16
+ */
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.isDescendantOf = isDescendantOf;
19
+ exports.findContainingCFGNode = findContainingCFGNode;
20
+ exports.findContainingCFGNodeFast = findContainingCFGNodeFast;
21
+ exports.buildCFGNodeMap = buildCFGNodeMap;
22
+ exports.mergeStates = mergeStates;
23
+ exports.buildSanitizerMap = buildSanitizerMap;
24
+ exports.resolveCalleeReturnTaint = resolveCalleeReturnTaint;
25
+ exports.applyTransfer = applyTransfer;
26
+ exports.mapSourcesToCFG = mapSourcesToCFG;
27
+ exports.mapSinksToCFG = mapSinksToCFG;
28
+ exports.runFixpointInternal = runFixpointInternal;
29
+ exports.checkSinksInternal = checkSinksInternal;
30
+ exports.propagateFunction = propagateFunction;
31
+ const cfg_builder_1 = require("./cfg-builder");
32
+ const propagation_types_1 = require("./propagation-types");
33
+ const ast_1 = require("../parse/ast");
34
+ const sink_classifier_1 = require("./sink-classifier");
35
+ const sanitizer_registry_1 = require("./sanitizer-registry");
36
+ const call_analysis_1 = require("../detect/ast-rules/helpers/call-analysis");
37
+ const python_helpers_1 = require("../detect/ast-rules/helpers/python-helpers");
38
+ const async_flow_1 = require("./async-flow");
39
+ const constant_propagation_1 = require("./constant-propagation");
40
+ const taint_summary_1 = require("./taint-summary");
41
+ // ============================================================================
42
+ // AST → CFGNode Matching
43
+ // ============================================================================
44
+ /**
45
+ * Check if `child` is a descendant of (or equal to) `ancestor` in the AST.
46
+ */
47
+ function isDescendantOf(child, ancestor) {
48
+ let current = child;
49
+ while (current) {
50
+ if (current.id === ancestor.id)
51
+ return true;
52
+ current = current.parent;
53
+ }
54
+ return false;
55
+ }
56
+ /**
57
+ * Find the CFG node that contains a given AST node.
58
+ * Returns the first CFG node whose astNode is an ancestor of (or equal to) the target.
59
+ */
60
+ function findContainingCFGNode(cfg, astNode) {
61
+ for (const [, cfgNode] of cfg.nodes) {
62
+ if (!cfgNode.astNode)
63
+ continue;
64
+ if (isDescendantOf(astNode, cfgNode.astNode))
65
+ return cfgNode;
66
+ }
67
+ return null;
68
+ }
69
+ /**
70
+ * Phase 8 (Part 4): O(D) parent-chain walk using pre-built CFG node map.
71
+ * Walks up the AST parent chain until a mapped node is found.
72
+ * D = AST depth (5-15), vs O(N) where N = CFG nodes (50-200).
73
+ */
74
+ function findContainingCFGNodeFast(cfgNodeMap, astNode) {
75
+ let current = astNode;
76
+ while (current) {
77
+ const cfgNode = cfgNodeMap.get(current.id);
78
+ if (cfgNode)
79
+ return cfgNode;
80
+ current = current.parent;
81
+ }
82
+ return null;
83
+ }
84
+ /**
85
+ * Build a map from AST node ID → CFGNode for all nodes in a CFG.
86
+ */
87
+ function buildCFGNodeMap(cfg) {
88
+ const map = new Map();
89
+ for (const [, cfgNode] of cfg.nodes) {
90
+ if (cfgNode.astNode) {
91
+ map.set(cfgNode.astNode.id, cfgNode);
92
+ }
93
+ }
94
+ return map;
95
+ }
96
+ // ============================================================================
97
+ // Taint State Helpers
98
+ // ============================================================================
99
+ /** Clone a TaintState (deep copy of field maps and sets). */
100
+ function cloneState(state) {
101
+ const clone = new Map();
102
+ for (const [varName, fieldMap] of state) {
103
+ const clonedFieldMap = new Map();
104
+ for (const [field, kinds] of fieldMap) {
105
+ clonedFieldMap.set(field, new Set(kinds));
106
+ }
107
+ clone.set(varName, clonedFieldMap);
108
+ }
109
+ return clone;
110
+ }
111
+ /** Merge multiple predecessor out-states into one in-state (union). */
112
+ function mergeStates(states) {
113
+ const merged = new Map();
114
+ for (const state of states) {
115
+ for (const [varName, fieldMap] of state) {
116
+ let existingFieldMap = merged.get(varName);
117
+ if (!existingFieldMap) {
118
+ existingFieldMap = new Map();
119
+ merged.set(varName, existingFieldMap);
120
+ }
121
+ for (const [field, kinds] of fieldMap) {
122
+ const existingKinds = existingFieldMap.get(field);
123
+ if (existingKinds) {
124
+ for (const k of kinds)
125
+ existingKinds.add(k);
126
+ }
127
+ else {
128
+ existingFieldMap.set(field, new Set(kinds));
129
+ }
130
+ }
131
+ }
132
+ }
133
+ return merged;
134
+ }
135
+ /** Check if two TaintStates are equal. */
136
+ function statesEqual(a, b) {
137
+ // Phase 8 (3c): identity fast path — catches cases where applyTransfer returned same ref
138
+ if (a === b)
139
+ return true;
140
+ if (a.size !== b.size)
141
+ return false;
142
+ for (const [varName, aFieldMap] of a) {
143
+ const bFieldMap = b.get(varName);
144
+ if (!bFieldMap)
145
+ return false;
146
+ if (aFieldMap.size !== bFieldMap.size)
147
+ return false;
148
+ for (const [field, aKinds] of aFieldMap) {
149
+ const bKinds = bFieldMap.get(field);
150
+ if (!bKinds)
151
+ return false;
152
+ if (aKinds.size !== bKinds.size)
153
+ return false;
154
+ for (const k of aKinds) {
155
+ if (!bKinds.has(k))
156
+ return false;
157
+ }
158
+ }
159
+ }
160
+ return true;
161
+ }
162
+ /** Collect taint from a set of used variables in the current state. */
163
+ function collectUseTaint(uses, state) {
164
+ const result = new Set();
165
+ for (const u of uses) {
166
+ const kinds = (0, propagation_types_1.getTaint)(state, u);
167
+ if (kinds) {
168
+ for (const k of kinds)
169
+ result.add(k);
170
+ }
171
+ }
172
+ return result;
173
+ }
174
+ /**
175
+ * Build a map from CFG node ID → sanitizers active in that node.
176
+ * Phase 8: accepts optional cfgNodeMap for O(D) lookup instead of O(N).
177
+ */
178
+ function buildSanitizerMap(cfg, sanitizers, cfgNodeMap) {
179
+ const map = new Map();
180
+ for (const s of sanitizers) {
181
+ const cfgNode = cfgNodeMap
182
+ ? findContainingCFGNodeFast(cfgNodeMap, s.node)
183
+ : findContainingCFGNode(cfg, s.node);
184
+ if (!cfgNode)
185
+ continue;
186
+ const existing = map.get(cfgNode.id);
187
+ if (existing) {
188
+ existing.push(s);
189
+ }
190
+ else {
191
+ map.set(cfgNode.id, [s]);
192
+ }
193
+ }
194
+ return map;
195
+ }
196
+ // ============================================================================
197
+ // Expression-level Transfer Function
198
+ // ============================================================================
199
+ /**
200
+ * Resolve taint for the RHS of an assignment by walking its AST.
201
+ *
202
+ * Returns the set of taint kinds that the RHS expression carries,
203
+ * considering sanitizer calls and optionally cross-file call resolution.
204
+ */
205
+ function resolveExpressionTaint(exprNode, inState, sanitizers, callContext, callerFile) {
206
+ const result = new Set();
207
+ // Literal values: no taint
208
+ if (isLiteral(exprNode))
209
+ return result;
210
+ // Identifier: look up in state
211
+ if (exprNode.type === 'identifier') {
212
+ const kinds = (0, propagation_types_1.getTaint)(inState, exprNode.text);
213
+ if (kinds)
214
+ for (const k of kinds)
215
+ result.add(k);
216
+ return result;
217
+ }
218
+ // Helper: shorthand for recursive calls with context forwarding
219
+ const resolve = (node) => resolveExpressionTaint(node, inState, sanitizers, callContext, callerFile);
220
+ // Await: taint propagates through (Python: 'await', JS: 'await_expression')
221
+ if (exprNode.type === 'await_expression' || exprNode.type === 'await') {
222
+ const inner = exprNode.namedChildren[0];
223
+ if (inner) {
224
+ const innerTaint = resolve(inner);
225
+ for (const k of innerTaint)
226
+ result.add(k);
227
+ }
228
+ return result;
229
+ }
230
+ // Parenthesized: pass through
231
+ if (exprNode.type === 'parenthesized_expression') {
232
+ const inner = exprNode.namedChildren[0];
233
+ if (inner) {
234
+ const innerTaint = resolve(inner);
235
+ for (const k of innerTaint)
236
+ result.add(k);
237
+ }
238
+ return result;
239
+ }
240
+ // Call expression: check sanitizers, then cross-file resolution, then conservative
241
+ // Python: 'call', JS: 'call_expression'
242
+ if (exprNode.type === 'call_expression' || exprNode.type === 'call') {
243
+ return resolveCallTaint(exprNode, inState, sanitizers, callContext, callerFile);
244
+ }
245
+ // New expression: union of arg taint
246
+ if (exprNode.type === 'new_expression') {
247
+ const args = exprNode.childForFieldName('arguments');
248
+ if (args) {
249
+ for (const arg of args.namedChildren) {
250
+ const argTaint = resolve(arg);
251
+ for (const k of argTaint)
252
+ result.add(k);
253
+ }
254
+ }
255
+ return result;
256
+ }
257
+ // Binary expression / template literal: union of both sides
258
+ // Python: 'binary_operator', JS: 'binary_expression'
259
+ if (exprNode.type === 'binary_expression' || exprNode.type === 'binary_operator') {
260
+ const left = exprNode.childForFieldName('left');
261
+ const right = exprNode.childForFieldName('right');
262
+ if (left) {
263
+ const lt = resolve(left);
264
+ for (const k of lt)
265
+ result.add(k);
266
+ }
267
+ if (right) {
268
+ const rt = resolve(right);
269
+ for (const k of rt)
270
+ result.add(k);
271
+ }
272
+ return result;
273
+ }
274
+ // Python boolean/comparison operators: walk children for taint
275
+ if (exprNode.type === 'boolean_operator' || exprNode.type === 'comparison_operator' ||
276
+ exprNode.type === 'not_operator') {
277
+ for (const child of exprNode.namedChildren) {
278
+ const ct = resolve(child);
279
+ for (const k of ct)
280
+ result.add(k);
281
+ }
282
+ return result;
283
+ }
284
+ // Python f-string: string node with interpolation children
285
+ // Must check BEFORE the fallback walkAST to properly handle f-string taint
286
+ if (exprNode.type === 'string' && exprNode.descendantsOfType('interpolation').length > 0) {
287
+ for (const interp of exprNode.descendantsOfType('interpolation')) {
288
+ for (const child of interp.namedChildren) {
289
+ const childTaint = resolve(child);
290
+ for (const k of childTaint)
291
+ result.add(k);
292
+ }
293
+ }
294
+ return result;
295
+ }
296
+ // Python concatenated_string: "foo" + "bar" or "a" "b" style
297
+ if (exprNode.type === 'concatenated_string') {
298
+ for (const child of exprNode.namedChildren) {
299
+ const ct = resolve(child);
300
+ for (const k of ct)
301
+ result.add(k);
302
+ }
303
+ return result;
304
+ }
305
+ // Template string: union of all substitutions
306
+ if (exprNode.type === 'template_string') {
307
+ const subs = exprNode.descendantsOfType('template_substitution');
308
+ for (const sub of subs) {
309
+ for (const child of sub.namedChildren) {
310
+ const childTaint = resolve(child);
311
+ for (const k of childTaint)
312
+ result.add(k);
313
+ }
314
+ }
315
+ return result;
316
+ }
317
+ // Member expression: field-aware taint resolution
318
+ // Python: 'attribute' + 'subscript', JS: 'member_expression' + 'subscript_expression'
319
+ if (exprNode.type === 'member_expression' || exprNode.type === 'subscript_expression' ||
320
+ exprNode.type === 'attribute' || exprNode.type === 'subscript') {
321
+ const obj = exprNode.childForFieldName('object')
322
+ ?? exprNode.childForFieldName('value'); // Python subscript uses 'value' field
323
+ if (obj) {
324
+ // Try field-specific taint: obj.field → getFieldTaint(state, "obj", "field")
325
+ if ((exprNode.type === 'member_expression' || exprNode.type === 'attribute') && obj.type === 'identifier') {
326
+ const prop = exprNode.type === 'attribute'
327
+ ? exprNode.childForFieldName('attribute')
328
+ : exprNode.childForFieldName('property');
329
+ if (prop && (prop.type === 'property_identifier' || prop.type === 'identifier')) {
330
+ const fieldTaint = (0, propagation_types_1.getFieldTaint)(inState, obj.text, prop.text);
331
+ if (fieldTaint)
332
+ for (const k of fieldTaint)
333
+ result.add(k);
334
+ return result;
335
+ }
336
+ }
337
+ // Computed/dynamic access or deep chain: fall back to whole-object taint
338
+ const objTaint = resolve(obj);
339
+ for (const k of objTaint)
340
+ result.add(k);
341
+ }
342
+ // Computed index may also carry taint
343
+ if (exprNode.type === 'subscript_expression' || exprNode.type === 'subscript') {
344
+ const index = exprNode.childForFieldName('index')
345
+ ?? exprNode.childForFieldName('subscript'); // Python subscript field name
346
+ if (index) {
347
+ const idxTaint = resolve(index);
348
+ for (const k of idxTaint)
349
+ result.add(k);
350
+ }
351
+ }
352
+ return result;
353
+ }
354
+ // Spread element
355
+ if (exprNode.type === 'spread_element') {
356
+ const inner = exprNode.namedChildren[0];
357
+ if (inner) {
358
+ const innerTaint = resolve(inner);
359
+ for (const k of innerTaint)
360
+ result.add(k);
361
+ }
362
+ return result;
363
+ }
364
+ // Object literal: union of all value taint (whole-object view for backward compat)
365
+ if (exprNode.type === 'object') {
366
+ for (const child of exprNode.namedChildren) {
367
+ if (child.type === 'pair') {
368
+ const value = child.childForFieldName('value');
369
+ if (value) {
370
+ const vt = resolve(value);
371
+ for (const k of vt)
372
+ result.add(k);
373
+ }
374
+ }
375
+ else if (child.type === 'shorthand_property_identifier') {
376
+ const kinds = (0, propagation_types_1.getTaint)(inState, child.text);
377
+ if (kinds)
378
+ for (const k of kinds)
379
+ result.add(k);
380
+ }
381
+ else if (child.type === 'spread_element') {
382
+ const inner = child.namedChildren[0];
383
+ if (inner) {
384
+ const innerTaint = resolve(inner);
385
+ for (const k of innerTaint)
386
+ result.add(k);
387
+ }
388
+ }
389
+ }
390
+ return result;
391
+ }
392
+ // Array literal / Python list/tuple: union of all element taint
393
+ if (exprNode.type === 'array' || exprNode.type === 'list' || exprNode.type === 'tuple') {
394
+ for (const child of exprNode.namedChildren) {
395
+ const ct = resolve(child);
396
+ for (const k of ct)
397
+ result.add(k);
398
+ }
399
+ return result;
400
+ }
401
+ // Python dictionary: union of all value taint
402
+ if (exprNode.type === 'dictionary') {
403
+ for (const child of exprNode.namedChildren) {
404
+ if (child.type === 'pair') {
405
+ const value = child.childForFieldName('value');
406
+ if (value) {
407
+ const vt = resolve(value);
408
+ for (const k of vt)
409
+ result.add(k);
410
+ }
411
+ }
412
+ else {
413
+ const ct = resolve(child);
414
+ for (const k of ct)
415
+ result.add(k);
416
+ }
417
+ }
418
+ return result;
419
+ }
420
+ // Ternary: union of both branches (conservative)
421
+ // Python: 'conditional_expression', JS: 'ternary_expression'
422
+ if (exprNode.type === 'ternary_expression' || exprNode.type === 'conditional_expression') {
423
+ for (const child of exprNode.namedChildren) {
424
+ const ct = resolve(child);
425
+ for (const k of ct)
426
+ result.add(k);
427
+ }
428
+ return result;
429
+ }
430
+ // Unary expression: propagate from operand
431
+ // Python: 'unary_operator', JS: 'unary_expression'
432
+ if (exprNode.type === 'unary_expression' || exprNode.type === 'unary_operator') {
433
+ const arg = exprNode.namedChildren[0];
434
+ if (arg) {
435
+ const at = resolve(arg);
436
+ for (const k of at)
437
+ result.add(k);
438
+ }
439
+ return result;
440
+ }
441
+ // Python keyword_argument: extract taint from value
442
+ if (exprNode.type === 'keyword_argument') {
443
+ const value = exprNode.childForFieldName('value');
444
+ if (value) {
445
+ const vt = resolve(value);
446
+ for (const k of vt)
447
+ result.add(k);
448
+ }
449
+ return result;
450
+ }
451
+ // Type assertion / as expression: propagate through
452
+ if (exprNode.type === 'as_expression' || exprNode.type === 'type_assertion' ||
453
+ exprNode.type === 'non_null_expression' || exprNode.type === 'satisfies_expression') {
454
+ const inner = exprNode.namedChildren[0];
455
+ if (inner) {
456
+ const innerTaint = resolve(inner);
457
+ for (const k of innerTaint)
458
+ result.add(k);
459
+ }
460
+ return result;
461
+ }
462
+ // Fallback: conservatively collect taint from all identifiers in the expression
463
+ (0, ast_1.walkAST)(exprNode, (node) => {
464
+ if (node.type === 'identifier') {
465
+ const kinds = (0, propagation_types_1.getTaint)(inState, node.text);
466
+ if (kinds)
467
+ for (const k of kinds)
468
+ result.add(k);
469
+ }
470
+ // Don't descend into nested function expressions
471
+ if (node.type === 'arrow_function' || node.type === 'function_expression' ||
472
+ node.type === 'function_definition' || node.type === 'lambda')
473
+ return true;
474
+ return false;
475
+ });
476
+ return result;
477
+ }
478
+ /**
479
+ * Resolve taint for a call expression, checking sanitizers and cross-file callees.
480
+ */
481
+ function resolveCallTaint(callNode, inState, sanitizers, callContext, callerFile) {
482
+ const result = new Set();
483
+ const resolve = (node) => resolveExpressionTaint(node, inState, sanitizers, callContext, callerFile);
484
+ // First, collect taint from all arguments (and per-argument taint for cross-file)
485
+ const argsNode = callNode.childForFieldName('arguments');
486
+ const argTaint = new Set();
487
+ const perArgTaint = [];
488
+ if (argsNode) {
489
+ for (const arg of argsNode.namedChildren) {
490
+ const at = resolve(arg);
491
+ perArgTaint.push(at);
492
+ for (const k of at)
493
+ argTaint.add(k);
494
+ }
495
+ }
496
+ // Also get taint from the callee (for method chains: tainted.toString())
497
+ // Python: 'attribute', JS: 'member_expression'
498
+ const fnNode = callNode.childForFieldName('function');
499
+ if (fnNode?.type === 'member_expression' || fnNode?.type === 'attribute') {
500
+ const obj = fnNode.childForFieldName('object');
501
+ if (obj) {
502
+ const objTaint = resolve(obj);
503
+ for (const k of objTaint)
504
+ argTaint.add(k);
505
+ }
506
+ }
507
+ // Check if this call is a sanitizer
508
+ const matchingSanitizer = findMatchingSanitizer(callNode, sanitizers);
509
+ if (matchingSanitizer) {
510
+ // Sanitizer: result = argTaint minus clearsKinds
511
+ for (const k of argTaint) {
512
+ if (!matchingSanitizer.clearsKinds.has(k)) {
513
+ result.add(k);
514
+ }
515
+ }
516
+ return result;
517
+ }
518
+ // Cross-file / inter-procedural resolution
519
+ if (callContext && callerFile && argTaint.size > 0) {
520
+ const calleeResult = resolveCalleeReturnTaint(callNode, perArgTaint, callContext, callerFile);
521
+ if (calleeResult !== null) {
522
+ return calleeResult.returnTaint;
523
+ }
524
+ }
525
+ // Not a sanitizer, not cross-file resolved: conservatively propagate all arg taint
526
+ return argTaint;
527
+ }
528
+ // ============================================================================
529
+ // Cross-File Call Resolution
530
+ // ============================================================================
531
+ /**
532
+ * Resolve the return taint from following a call into another function/file.
533
+ *
534
+ * 1. Resolve call target name
535
+ * 2. Look up in CrossFileIndex (resolveImport or functionDefs)
536
+ * 3. If found and not in callStack (recursion guard):
537
+ * a. Parse callee file's AST, build CFG
538
+ * b. Create synthetic sources from argument taint → parameter names
539
+ * c. Run propagation on callee's CFG
540
+ * d. Collect return-value taint from return statements
541
+ * 4. Return the taint kinds flowing out + path steps
542
+ */
543
+ function resolveCalleeReturnTaint(callNode, perArgTaint, ctx, callerFile) {
544
+ // Resolve the call target (try JS first, then Python fallback)
545
+ let resolved = (0, call_analysis_1.resolveCallTarget)(callNode);
546
+ if (!resolved) {
547
+ const pyResolved = (0, python_helpers_1.resolvePythonCallTarget)(callNode);
548
+ if (pyResolved) {
549
+ resolved = { type: pyResolved.type, name: pyResolved.name, object: pyResolved.object };
550
+ }
551
+ }
552
+ if (!resolved)
553
+ return null;
554
+ const { crossFileIndex, allASTs, callStack, maxDepth } = ctx;
555
+ // Try to find the function definition
556
+ let funcDef = crossFileIndex.resolveImport.get(`${callerFile}:${resolved.name}`);
557
+ // Also try namespace.method pattern
558
+ if (!funcDef && resolved.type === 'member' && resolved.object) {
559
+ funcDef = crossFileIndex.resolveImport.get(`${callerFile}:${resolved.object}.${resolved.name}`);
560
+ }
561
+ // Also try local function
562
+ if (!funcDef) {
563
+ funcDef = crossFileIndex.functionDefs.get(`${callerFile}:${resolved.name}`);
564
+ }
565
+ if (!funcDef)
566
+ return null;
567
+ // Recursion guard
568
+ const callKey = `${funcDef.filePath}:${funcDef.functionName}`;
569
+ if (callStack.has(callKey))
570
+ return null;
571
+ if (callStack.size >= maxDepth)
572
+ return null;
573
+ // Check cache
574
+ const taintSig = perArgTaint.map(s => [...s].sort().join(',')).join('|');
575
+ const cacheKey = `${callKey}:${taintSig}`;
576
+ if (ctx.resultCache.has(cacheKey)) {
577
+ return ctx.resultCache.get(cacheKey);
578
+ }
579
+ // Phase 8: Try summary-based composition first (much faster than full analysis)
580
+ if (ctx.summaryCache && ctx.analysisCache) {
581
+ const summary = (0, taint_summary_1.getOrBuildSummary)(funcDef, ctx);
582
+ if (summary) {
583
+ const result = (0, taint_summary_1.composeSummary)(summary, perArgTaint, callerFile, callNode);
584
+ ctx.resultCache.set(cacheKey, result.returnTaint.size > 0 || result.calleeFindings.length > 0 ? result : null);
585
+ return result.returnTaint.size > 0 || result.calleeFindings.length > 0 ? result : null;
586
+ }
587
+ }
588
+ // Get callee AST
589
+ const calleeAST = allASTs.get(funcDef.filePath);
590
+ if (!calleeAST) {
591
+ ctx.resultCache.set(cacheKey, null);
592
+ return null;
593
+ }
594
+ // Phase 8: Use analysis cache if available, otherwise recompute
595
+ const fileCache = ctx.analysisCache?.get(funcDef.filePath);
596
+ const calleeCFGs = fileCache?.cfgs ?? (0, cfg_builder_1.buildFileCFGs)(calleeAST);
597
+ // Find the specific function's CFG
598
+ let calleeCFG;
599
+ for (const [name, cfg] of calleeCFGs) {
600
+ if (name === funcDef.functionName) {
601
+ calleeCFG = cfg;
602
+ break;
603
+ }
604
+ }
605
+ if (!calleeCFG) {
606
+ ctx.resultCache.set(cacheKey, null);
607
+ return null;
608
+ }
609
+ // Create synthetic sources from argument taint → parameter names
610
+ const syntheticSources = [];
611
+ for (let i = 0; i < funcDef.params.length && i < perArgTaint.length; i++) {
612
+ const paramTaint = perArgTaint[i];
613
+ if (paramTaint.size === 0)
614
+ continue;
615
+ // Find the parameter's AST node in the callee function
616
+ const paramNode = findParamNode(funcDef.astNode, funcDef.params[i]);
617
+ if (!paramNode)
618
+ continue;
619
+ syntheticSources.push({
620
+ node: paramNode,
621
+ line: paramNode.startPosition.row + 1,
622
+ variable: funcDef.params[i],
623
+ expression: `${funcDef.functionName}(${funcDef.params[i]})`,
624
+ sourceType: 'external_api', // synthetic source
625
+ taintKinds: new Set(paramTaint),
626
+ confidence: 'high',
627
+ });
628
+ }
629
+ if (syntheticSources.length === 0) {
630
+ ctx.resultCache.set(cacheKey, null);
631
+ return null;
632
+ }
633
+ // Phase 8: Get sinks and sanitizers from cache or recompute
634
+ const calleeSinks = fileCache?.sinks ?? (0, sink_classifier_1.classifySinks)(calleeAST);
635
+ const calleeSanitizers = fileCache?.sanitizers ?? (0, sanitizer_registry_1.buildSanitizerRegistry)(calleeAST);
636
+ // Map synthetic parameter sources to the CFG entry node.
637
+ // Parameters aren't inside any statement node, so mapSourcesToCFG would fail.
638
+ // Instead, seed them at the entry node — parameters are defined at function entry.
639
+ let entryNodeId = -1;
640
+ for (const [id, node] of calleeCFG.nodes) {
641
+ if (node.kind === 'entry') {
642
+ entryNodeId = id;
643
+ break;
644
+ }
645
+ }
646
+ if (entryNodeId === -1) {
647
+ ctx.resultCache.set(cacheKey, null);
648
+ return null;
649
+ }
650
+ const sourceMappings = syntheticSources.map(source => ({
651
+ source,
652
+ cfgNodeId: entryNodeId,
653
+ }));
654
+ // Phase 8 (Part 4): use cached CFG node map for O(D) lookup
655
+ const calleeCFGNodeMap = fileCache?.cfgNodeMaps.get(funcDef.functionName);
656
+ const sinkMappings = mapSinksToCFG(calleeCFG, calleeSinks, calleeCFGNodeMap);
657
+ const sanitizerMap = buildSanitizerMap(calleeCFG, calleeSanitizers, calleeCFGNodeMap);
658
+ // Push to call stack
659
+ callStack.add(callKey);
660
+ // Create child context for deeper calls
661
+ const childContext = {
662
+ ...ctx,
663
+ callStack: new Set(callStack),
664
+ };
665
+ // Run fixpoint ONCE — used for both callee findings and return taint
666
+ const calleeConstants = calleeCFG.functionNode ? (0, constant_propagation_1.collectConstants)(calleeCFG.functionNode) : new Map();
667
+ const outStates = runFixpointInternal(calleeCFG, sourceMappings, sanitizerMap, funcDef.filePath, childContext, calleeConstants);
668
+ const calleeFindings = deduplicateFindings(checkSinksInternal(calleeCFG, outStates, sinkMappings, sourceMappings, funcDef.filePath));
669
+ // Pop from call stack
670
+ callStack.delete(callKey);
671
+ // Extract return-value taint from the already-computed out-states
672
+ const returnTaint = extractReturnTaint(calleeCFG, outStates, calleeSanitizers, childContext, funcDef.filePath);
673
+ // Build path steps
674
+ const steps = [
675
+ {
676
+ nodeId: 0,
677
+ line: callNode.startPosition.row + 1,
678
+ variable: funcDef.functionName,
679
+ taintKinds: new Set(returnTaint),
680
+ description: `CALL_ENTRY ${funcDef.functionName}() in ${funcDef.filePath}`,
681
+ stepType: 'call_entry',
682
+ filePath: funcDef.filePath,
683
+ functionName: funcDef.functionName,
684
+ },
685
+ {
686
+ nodeId: 0,
687
+ line: callNode.startPosition.row + 1,
688
+ variable: funcDef.functionName,
689
+ taintKinds: new Set(returnTaint),
690
+ description: `CALL_RETURN ${funcDef.functionName}() → ${[...returnTaint].join(',')}`,
691
+ stepType: 'call_return',
692
+ filePath: callerFile,
693
+ functionName: funcDef.functionName,
694
+ },
695
+ ];
696
+ const calleeResult = {
697
+ returnTaint,
698
+ steps,
699
+ calleeFindings,
700
+ };
701
+ ctx.resultCache.set(cacheKey, calleeResult);
702
+ return calleeResult;
703
+ }
704
+ /**
705
+ * Extract taint kinds from return statements using pre-computed out-states.
706
+ * Walks all return statements in the CFG and resolves expression taint.
707
+ */
708
+ function extractReturnTaint(cfg, outStates, sanitizers, callContext, filePath) {
709
+ const returnTaint = new Set();
710
+ for (const [, cfgNode] of cfg.nodes) {
711
+ if (!cfgNode.astNode)
712
+ continue;
713
+ const ast = cfgNode.astNode;
714
+ if (ast.type !== 'return_statement')
715
+ continue;
716
+ const returnExpr = ast.namedChildren[0];
717
+ if (!returnExpr)
718
+ continue;
719
+ // Get the taint state at this node: merge predecessors + own out-state
720
+ const predIds = (0, cfg_builder_1.getPredecessors)(cfg, cfgNode.id);
721
+ const predStates = [];
722
+ for (const pId of predIds) {
723
+ const ps = outStates.get(pId);
724
+ if (ps)
725
+ predStates.push(ps);
726
+ }
727
+ const nodeInState = mergeStates(predStates);
728
+ const nodeState = mergeStates([nodeInState, outStates.get(cfgNode.id) ?? new Map()]);
729
+ const exprTaint = resolveExpressionTaint(returnExpr, nodeState, sanitizers, callContext, filePath);
730
+ for (const k of exprTaint)
731
+ returnTaint.add(k);
732
+ }
733
+ return returnTaint;
734
+ }
735
+ /** Find a parameter's AST node in a function definition. */
736
+ function findParamNode(fnNode, paramName) {
737
+ const params = fnNode.childForFieldName('parameters');
738
+ if (!params)
739
+ return null;
740
+ for (const child of params.namedChildren) {
741
+ if (child.type === 'identifier' && child.text === paramName)
742
+ return child;
743
+ // JS/TS param types
744
+ if (child.type === 'required_parameter' || child.type === 'optional_parameter') {
745
+ const pattern = child.childForFieldName('pattern');
746
+ if (pattern?.type === 'identifier' && pattern.text === paramName)
747
+ return pattern;
748
+ }
749
+ if (child.type === 'assignment_pattern') {
750
+ const left = child.childForFieldName('left');
751
+ if (left?.type === 'identifier' && left.text === paramName)
752
+ return left;
753
+ }
754
+ // Python param types
755
+ if (child.type === 'typed_parameter' || child.type === 'default_parameter' ||
756
+ child.type === 'typed_default_parameter') {
757
+ const nameNode = child.namedChildren.find(c => c.type === 'identifier');
758
+ if (nameNode && nameNode.text === paramName)
759
+ return nameNode;
760
+ }
761
+ if (child.type === 'list_splat_pattern' || child.type === 'dictionary_splat_pattern') {
762
+ const ident = child.namedChildren.find(c => c.type === 'identifier');
763
+ if (ident && ident.text === paramName)
764
+ return ident;
765
+ }
766
+ }
767
+ // Fallback: search for identifier in params subtree
768
+ let found = null;
769
+ (0, ast_1.walkAST)(params, (node) => {
770
+ if (node.type === 'identifier' && node.text === paramName && !found) {
771
+ found = node;
772
+ return true;
773
+ }
774
+ return false;
775
+ });
776
+ return found;
777
+ }
778
+ /**
779
+ * Find a sanitizer whose AST node matches this call expression.
780
+ */
781
+ function findMatchingSanitizer(callNode, sanitizers) {
782
+ for (const s of sanitizers) {
783
+ if (s.node.id === callNode.id)
784
+ return s;
785
+ // Also check if the sanitizer's node is a parent/ancestor of this call
786
+ if (isDescendantOf(callNode, s.node))
787
+ return s;
788
+ }
789
+ return null;
790
+ }
791
+ /** Check if a node represents a literal value (no taint). */
792
+ function isLiteral(node) {
793
+ switch (node.type) {
794
+ case 'string':
795
+ // Python f-strings have type 'string' but contain interpolation children — NOT a literal
796
+ if (node.descendantsOfType('interpolation').length > 0)
797
+ return false;
798
+ return true;
799
+ case 'number':
800
+ case 'true':
801
+ case 'false':
802
+ case 'null':
803
+ case 'undefined':
804
+ case 'regex':
805
+ // Python literals
806
+ case 'integer':
807
+ case 'float':
808
+ case 'none':
809
+ return true;
810
+ default:
811
+ return false;
812
+ }
813
+ }
814
+ // ============================================================================
815
+ // Statement-level Transfer Function
816
+ // ============================================================================
817
+ /**
818
+ * Apply the transfer function for a single CFG node.
819
+ * Given the incoming taint state, compute the outgoing taint state.
820
+ */
821
+ function applyTransfer(cfgNode, inState, sanitizerMap, callContext, callerFile, constantMap) {
822
+ // Phase 8 (3b): skip clone for no-op nodes — entry, exit, and nodes without AST
823
+ if (!cfgNode.astNode)
824
+ return inState;
825
+ if (cfgNode.kind === 'entry' || cfgNode.kind === 'exit')
826
+ return inState;
827
+ // Phase 8 (3b): condition nodes with no defs and no sanitizers are read-only
828
+ if (cfgNode.kind === 'condition' && cfgNode.defs.size === 0) {
829
+ const hasSanitizers = sanitizerMap.has(cfgNode.id);
830
+ if (!hasSanitizers)
831
+ return inState;
832
+ }
833
+ const outState = cloneState(inState);
834
+ const sanitizers = sanitizerMap.get(cfgNode.id) ?? [];
835
+ const ast = cfgNode.astNode;
836
+ applyNodeTransfer(ast, outState, sanitizers, callContext, callerFile, constantMap);
837
+ return outState;
838
+ }
839
+ /**
840
+ * Recursively apply transfer for an AST node within a CFG statement.
841
+ */
842
+ function applyNodeTransfer(node, state, sanitizers, callContext, callerFile, constantMap) {
843
+ // Helper for expression taint resolution with context forwarding
844
+ const resolve = (expr) => resolveExpressionTaint(expr, state, sanitizers, callContext, callerFile);
845
+ // Variable declaration: const x = <expr>
846
+ if (node.type === 'lexical_declaration' || node.type === 'variable_declaration') {
847
+ for (const child of node.namedChildren) {
848
+ applyNodeTransfer(child, state, sanitizers, callContext, callerFile, constantMap);
849
+ }
850
+ return;
851
+ }
852
+ if (node.type === 'variable_declarator') {
853
+ const nameNode = node.childForFieldName('name');
854
+ const valueNode = node.childForFieldName('value');
855
+ if (!nameNode || !valueNode)
856
+ return;
857
+ if (nameNode.type === 'identifier') {
858
+ // Constant propagation: if RHS is entirely constant-derived, clear taint
859
+ if (constantMap && (0, constant_propagation_1.isConstantExpression)(valueNode, constantMap)) {
860
+ (0, propagation_types_1.deleteTaint)(state, nameNode.text);
861
+ return;
862
+ }
863
+ // Simple: const x = expr
864
+ const rhsTaint = resolve(valueNode);
865
+ if (rhsTaint.size > 0) {
866
+ (0, propagation_types_1.setTaint)(state, nameNode.text, rhsTaint);
867
+ }
868
+ else {
869
+ (0, propagation_types_1.deleteTaint)(state, nameNode.text);
870
+ }
871
+ }
872
+ else if (nameNode.type === 'object_pattern' || nameNode.type === 'array_pattern') {
873
+ // Destructuring: const { a, b } = expr
874
+ const rhsTaint = resolve(valueNode);
875
+ const rhsVarName = valueNode.type === 'identifier' ? valueNode.text
876
+ : (valueNode.type === 'member_expression' ? getMemberRoot(valueNode) : null);
877
+ applyDestructuringTaint(nameNode, rhsTaint, state, rhsVarName ?? undefined);
878
+ }
879
+ return;
880
+ }
881
+ // Assignment: x = expr
882
+ // Python: 'assignment', JS: 'assignment_expression'
883
+ if (node.type === 'assignment_expression' || node.type === 'assignment') {
884
+ const left = node.childForFieldName('left');
885
+ const right = node.childForFieldName('right');
886
+ if (!left || !right)
887
+ return;
888
+ if (left.type === 'identifier') {
889
+ // Constant propagation: if RHS is entirely constant-derived, clear taint
890
+ if (constantMap && (0, constant_propagation_1.isConstantExpression)(right, constantMap)) {
891
+ (0, propagation_types_1.deleteTaint)(state, left.text);
892
+ return;
893
+ }
894
+ const rhsTaint = resolve(right);
895
+ if (rhsTaint.size > 0) {
896
+ (0, propagation_types_1.setTaint)(state, left.text, rhsTaint);
897
+ }
898
+ else {
899
+ (0, propagation_types_1.deleteTaint)(state, left.text);
900
+ }
901
+ }
902
+ else if (left.type === 'object_pattern' || left.type === 'array_pattern' ||
903
+ left.type === 'tuple_pattern' || left.type === 'list_pattern' ||
904
+ left.type === 'pattern_list' || left.type === 'tuple' || left.type === 'list') {
905
+ // Destructuring / Python unpacking: a, b = expr
906
+ const rhsTaint = resolve(right);
907
+ const rhsVarName = right.type === 'identifier' ? right.text
908
+ : (right.type === 'member_expression' || right.type === 'attribute' ? getMemberRoot(right) : null);
909
+ applyDestructuringTaint(left, rhsTaint, state, rhsVarName ?? undefined);
910
+ }
911
+ else if (left.type === 'member_expression' || left.type === 'attribute') {
912
+ // obj.prop = val — field-level taint
913
+ // Python: 'attribute' with fields 'object'/'attribute', JS: 'member_expression' with 'object'/'property'
914
+ const obj = left.childForFieldName('object');
915
+ const prop = left.type === 'attribute'
916
+ ? left.childForFieldName('attribute')
917
+ : left.childForFieldName('property');
918
+ if (obj?.type === 'identifier' && prop && (prop.type === 'property_identifier' || prop.type === 'identifier')) {
919
+ // One-level field assignment: obj.field = val
920
+ const rhsTaint = resolve(right);
921
+ if (rhsTaint.size > 0) {
922
+ (0, propagation_types_1.setFieldTaint)(state, obj.text, prop.text, rhsTaint);
923
+ }
924
+ }
925
+ else {
926
+ // Deep chain or computed: fall back to root object taint
927
+ const root = getMemberRoot(left);
928
+ if (root) {
929
+ const rhsTaint = resolve(right);
930
+ // Phase 8: clone before mutating — getTaint may return internal Set reference
931
+ const existing = new Set((0, propagation_types_1.getTaint)(state, root) ?? []);
932
+ for (const k of rhsTaint)
933
+ existing.add(k);
934
+ if (existing.size > 0)
935
+ (0, propagation_types_1.setTaint)(state, root, existing);
936
+ }
937
+ }
938
+ }
939
+ return;
940
+ }
941
+ // Augmented assignment: x += expr
942
+ // Python: 'augmented_assignment', JS: 'augmented_assignment_expression'
943
+ if (node.type === 'augmented_assignment_expression' || node.type === 'augmented_assignment') {
944
+ const left = node.childForFieldName('left');
945
+ const right = node.childForFieldName('right');
946
+ if (!left || !right)
947
+ return;
948
+ if (left.type === 'identifier') {
949
+ const rhsTaint = resolve(right);
950
+ // Phase 8: clone before mutating — getTaint may return internal Set reference
951
+ const existing = new Set((0, propagation_types_1.getTaint)(state, left.text) ?? []);
952
+ for (const k of rhsTaint)
953
+ existing.add(k);
954
+ if (existing.size > 0)
955
+ (0, propagation_types_1.setTaint)(state, left.text, existing);
956
+ }
957
+ return;
958
+ }
959
+ // Expression statement: unwrap the inner expression
960
+ if (node.type === 'expression_statement') {
961
+ for (const child of node.namedChildren) {
962
+ applyNodeTransfer(child, state, sanitizers, callContext, callerFile, constantMap);
963
+ }
964
+ return;
965
+ }
966
+ // For-in header: captures iteration variable taint from the right side
967
+ if (node.type === 'for_in_statement') {
968
+ const left = node.childForFieldName('left');
969
+ const right = node.childForFieldName('right');
970
+ if (left && right) {
971
+ const rhsTaint = resolve(right);
972
+ if (left.type === 'identifier') {
973
+ if (rhsTaint.size > 0)
974
+ (0, propagation_types_1.setTaint)(state, left.text, rhsTaint);
975
+ }
976
+ else {
977
+ // Destructuring in for-of/for-in
978
+ applyDestructuringTaint(left, rhsTaint, state);
979
+ }
980
+ }
981
+ return;
982
+ }
983
+ // Python for loop with left/right fields: for x in iterable
984
+ if (node.type === 'for_statement') {
985
+ const left = node.childForFieldName('left');
986
+ const right = node.childForFieldName('right');
987
+ if (left && right) {
988
+ const rhsTaint = resolve(right);
989
+ if (left.type === 'identifier') {
990
+ if (rhsTaint.size > 0)
991
+ (0, propagation_types_1.setTaint)(state, left.text, rhsTaint);
992
+ }
993
+ else {
994
+ applyDestructuringTaint(left, rhsTaint, state);
995
+ }
996
+ }
997
+ return;
998
+ }
999
+ // Python with statement: with expr as var
1000
+ if (node.type === 'with_statement') {
1001
+ // The with_clause may contain 'as_pattern' nodes: expr as name
1002
+ for (const child of node.namedChildren) {
1003
+ if (child.type === 'with_clause') {
1004
+ for (const item of child.namedChildren) {
1005
+ if (item.type === 'with_item' || item.type === 'as_pattern') {
1006
+ const expr = item.namedChildren[0];
1007
+ const alias = item.namedChildren[1];
1008
+ if (expr && alias?.type === 'identifier') {
1009
+ const exprTaint = resolve(expr);
1010
+ if (exprTaint.size > 0)
1011
+ (0, propagation_types_1.setTaint)(state, alias.text, exprTaint);
1012
+ }
1013
+ }
1014
+ }
1015
+ }
1016
+ }
1017
+ return;
1018
+ }
1019
+ // Standalone call expression: trigger expression resolution so cross-file
1020
+ // analysis discovers callee findings (sinks reached inside the called function).
1021
+ // Without this, standalone calls like `query(input)` would be silently ignored.
1022
+ // Python: 'call', JS: 'call_expression'
1023
+ if (node.type === 'call_expression' || node.type === 'call') {
1024
+ // Inject taint into callback parameters for promise chains and callback APIs.
1025
+ // This must happen BEFORE resolve() so the taint state is available when
1026
+ // analyzing the callback body's expressions.
1027
+ (0, async_flow_1.injectPromiseChainTaint)(node, state);
1028
+ (0, async_flow_1.injectCallbackTaint)(node, state);
1029
+ resolve(node);
1030
+ return;
1031
+ }
1032
+ // Return / throw: no defs, but the expression is "used"
1033
+ // (no state changes needed — uses are tracked by def-use)
1034
+ }
1035
+ /**
1036
+ * Apply taint from a destructuring pattern.
1037
+ * When rhsVarName is provided and object_pattern is used, field-specific
1038
+ * taint is extracted per destructured key. Otherwise falls back to whole-object taint.
1039
+ */
1040
+ function applyDestructuringTaint(pattern, rhsTaint, state, rhsVarName) {
1041
+ if (rhsTaint.size === 0)
1042
+ return;
1043
+ if (pattern.type === 'identifier') {
1044
+ (0, propagation_types_1.setTaint)(state, pattern.text, new Set(rhsTaint));
1045
+ return;
1046
+ }
1047
+ if (pattern.type === 'object_pattern') {
1048
+ for (const prop of pattern.namedChildren) {
1049
+ if (prop.type === 'shorthand_property_identifier_pattern') {
1050
+ // { email } = obj → email gets field-specific taint from obj.email
1051
+ if (rhsVarName) {
1052
+ const fieldTaint = (0, propagation_types_1.getFieldTaint)(state, rhsVarName, prop.text);
1053
+ if (fieldTaint && fieldTaint.size > 0) {
1054
+ (0, propagation_types_1.setTaint)(state, prop.text, new Set(fieldTaint));
1055
+ }
1056
+ else {
1057
+ // Field has no taint — don't assign whole-object taint
1058
+ (0, propagation_types_1.deleteTaint)(state, prop.text);
1059
+ }
1060
+ }
1061
+ else {
1062
+ (0, propagation_types_1.setTaint)(state, prop.text, new Set(rhsTaint));
1063
+ }
1064
+ }
1065
+ else if (prop.type === 'pair_pattern') {
1066
+ // { email: e } = obj → e gets taint from obj.email
1067
+ const key = prop.childForFieldName('key');
1068
+ const value = prop.childForFieldName('value');
1069
+ if (value && rhsVarName && key) {
1070
+ const fieldName = key.text;
1071
+ const fieldTaint = (0, propagation_types_1.getFieldTaint)(state, rhsVarName, fieldName);
1072
+ if (fieldTaint && fieldTaint.size > 0) {
1073
+ applyDestructuringTaint(value, fieldTaint, state);
1074
+ }
1075
+ }
1076
+ else if (value) {
1077
+ applyDestructuringTaint(value, rhsTaint, state);
1078
+ }
1079
+ }
1080
+ else if (prop.type === 'rest_pattern') {
1081
+ // { ...rest } = obj → rest gets whole-object taint (conservative)
1082
+ const inner = prop.namedChildren[0];
1083
+ if (inner)
1084
+ applyDestructuringTaint(inner, rhsTaint, state);
1085
+ }
1086
+ }
1087
+ return;
1088
+ }
1089
+ if (pattern.type === 'array_pattern') {
1090
+ for (const elem of pattern.namedChildren) {
1091
+ applyDestructuringTaint(elem, rhsTaint, state);
1092
+ }
1093
+ return;
1094
+ }
1095
+ // Python unpacking: a, b = expr / (a, b) = expr / [a, b] = expr
1096
+ if (pattern.type === 'tuple_pattern' || pattern.type === 'list_pattern' ||
1097
+ pattern.type === 'pattern_list' || pattern.type === 'expression_list' ||
1098
+ pattern.type === 'tuple' || pattern.type === 'list') {
1099
+ for (const elem of pattern.namedChildren) {
1100
+ applyDestructuringTaint(elem, rhsTaint, state);
1101
+ }
1102
+ return;
1103
+ }
1104
+ // Python list_splat_pattern: *rest
1105
+ if (pattern.type === 'list_splat_pattern') {
1106
+ const inner = pattern.namedChildren[0];
1107
+ if (inner)
1108
+ applyDestructuringTaint(inner, rhsTaint, state);
1109
+ return;
1110
+ }
1111
+ if (pattern.type === 'assignment_pattern') {
1112
+ const left = pattern.childForFieldName('left');
1113
+ if (left)
1114
+ applyDestructuringTaint(left, rhsTaint, state, rhsVarName);
1115
+ return;
1116
+ }
1117
+ if (pattern.type === 'rest_pattern') {
1118
+ const inner = pattern.namedChildren[0];
1119
+ if (inner)
1120
+ applyDestructuringTaint(inner, rhsTaint, state);
1121
+ }
1122
+ }
1123
+ /** Get the root identifier of a member expression chain: `a.b.c` → 'a'. */
1124
+ function getMemberRoot(node) {
1125
+ let current = node;
1126
+ while (current.type === 'member_expression' || current.type === 'subscript_expression' ||
1127
+ current.type === 'attribute' || current.type === 'subscript') {
1128
+ const obj = current.childForFieldName('object')
1129
+ ?? current.childForFieldName('value'); // Python subscript uses 'value' field
1130
+ if (!obj)
1131
+ return null;
1132
+ current = obj;
1133
+ }
1134
+ return current.type === 'identifier' ? current.text : null;
1135
+ }
1136
+ /**
1137
+ * Map sources to their containing CFG nodes.
1138
+ * Phase 8: accepts optional cfgNodeMap for O(D) lookup instead of O(N).
1139
+ */
1140
+ function mapSourcesToCFG(cfg, sources, cfgNodeMap) {
1141
+ const mappings = [];
1142
+ for (const source of sources) {
1143
+ const cfgNode = cfgNodeMap
1144
+ ? findContainingCFGNodeFast(cfgNodeMap, source.node)
1145
+ : findContainingCFGNode(cfg, source.node);
1146
+ if (cfgNode) {
1147
+ mappings.push({ source, cfgNodeId: cfgNode.id });
1148
+ }
1149
+ }
1150
+ return mappings;
1151
+ }
1152
+ /**
1153
+ * Map sinks to their containing CFG nodes.
1154
+ * Phase 8: accepts optional cfgNodeMap for O(D) lookup instead of O(N).
1155
+ */
1156
+ function mapSinksToCFG(cfg, sinks, cfgNodeMap) {
1157
+ const mappings = [];
1158
+ for (const sink of sinks) {
1159
+ const cfgNode = cfgNodeMap
1160
+ ? findContainingCFGNodeFast(cfgNodeMap, sink.node)
1161
+ : findContainingCFGNode(cfg, sink.node);
1162
+ if (cfgNode) {
1163
+ mappings.push({ sink, cfgNodeId: cfgNode.id });
1164
+ }
1165
+ }
1166
+ return mappings;
1167
+ }
1168
+ // ============================================================================
1169
+ // Worklist Algorithm
1170
+ // ============================================================================
1171
+ const MAX_ITERATIONS = 1000;
1172
+ /**
1173
+ * Run the worklist fixpoint algorithm on a CFG.
1174
+ *
1175
+ * Seeds taint at source nodes, propagates forward through the CFG until
1176
+ * no more state changes occur (fixpoint). Returns the per-node out-states.
1177
+ *
1178
+ * Exported as runFixpointInternal for use by taint-summary.ts (Phase 8).
1179
+ */
1180
+ function runFixpointInternal(cfg, sourceMappings, sanitizerMap, filePath, callContext, constantMap) {
1181
+ // Per-node out-states
1182
+ const outStates = new Map();
1183
+ for (const [id] of cfg.nodes) {
1184
+ outStates.set(id, new Map());
1185
+ }
1186
+ // Seed sources: set source variable taint in the source node's out-state
1187
+ const worklist = new Set();
1188
+ // Build a per-node source seed map so seeds survive worklist overwrites.
1189
+ // Without this, when a predecessor's propagation causes node N to be
1190
+ // re-processed, applyTransfer overwrites the seeded out-state with just
1191
+ // the propagated in-state — losing any source taint that was seeded here.
1192
+ const sourceSeeds = new Map();
1193
+ for (const { source, cfgNodeId } of sourceMappings) {
1194
+ const state = outStates.get(cfgNodeId);
1195
+ const cfgNode = cfg.nodes.get(cfgNodeId);
1196
+ const varName = source.variable;
1197
+ const isDestructuring = varName.startsWith('{') || varName.startsWith('[');
1198
+ if (isDestructuring && cfgNode && cfgNode.defs.size > 0) {
1199
+ for (const defVar of cfgNode.defs) {
1200
+ // Phase 8: clone before mutating — getTaint may return internal Set reference
1201
+ const existing = new Set((0, propagation_types_1.getTaint)(state, defVar) ?? []);
1202
+ for (const k of source.taintKinds)
1203
+ existing.add(k);
1204
+ (0, propagation_types_1.setTaint)(state, defVar, existing);
1205
+ }
1206
+ }
1207
+ else {
1208
+ // Phase 8: clone before mutating — getTaint may return internal Set reference
1209
+ const existing = new Set((0, propagation_types_1.getTaint)(state, varName) ?? []);
1210
+ for (const k of source.taintKinds)
1211
+ existing.add(k);
1212
+ (0, propagation_types_1.setTaint)(state, varName, existing);
1213
+ // For compound source variables (e.g. "req.body", "req.query"), also seed
1214
+ // the root identifier. The expression-level resolver walks member chains
1215
+ // from the root, so `req.body.email` resolves `req` → tainted → propagates.
1216
+ if (varName.includes('.')) {
1217
+ const root = varName.split('.')[0];
1218
+ const rootExisting = new Set((0, propagation_types_1.getTaint)(state, root) ?? []);
1219
+ for (const k of source.taintKinds)
1220
+ rootExisting.add(k);
1221
+ (0, propagation_types_1.setTaint)(state, root, rootExisting);
1222
+ }
1223
+ }
1224
+ // Record seed for re-injection during worklist
1225
+ if (!sourceSeeds.has(cfgNodeId))
1226
+ sourceSeeds.set(cfgNodeId, []);
1227
+ sourceSeeds.get(cfgNodeId).push({
1228
+ variable: varName,
1229
+ kinds: new Set(source.taintKinds),
1230
+ isDestructuring,
1231
+ defs: cfgNode?.defs ?? new Set(),
1232
+ });
1233
+ // Push successors to worklist (the source node's out-state is now seeded)
1234
+ for (const succ of (0, cfg_builder_1.getSuccessors)(cfg, cfgNodeId)) {
1235
+ worklist.add(succ);
1236
+ }
1237
+ }
1238
+ // Iterate to fixpoint
1239
+ let iterations = 0;
1240
+ while (worklist.size > 0 && iterations < MAX_ITERATIONS) {
1241
+ iterations++;
1242
+ // Pop first element from worklist
1243
+ const nodeId = worklist.values().next().value;
1244
+ worklist.delete(nodeId);
1245
+ const cfgNode = cfg.nodes.get(nodeId);
1246
+ if (!cfgNode)
1247
+ continue;
1248
+ // Compute in-state = merge of all predecessor out-states
1249
+ // Phase 8 (3a): single-predecessor fast path — skip mergeStates allocation for ~70% of nodes
1250
+ const predIds = (0, cfg_builder_1.getPredecessors)(cfg, nodeId);
1251
+ let inState;
1252
+ if (predIds.length === 1) {
1253
+ const ps = outStates.get(predIds[0]);
1254
+ inState = ps ?? new Map();
1255
+ }
1256
+ else {
1257
+ const predStates = [];
1258
+ for (const pId of predIds) {
1259
+ const ps = outStates.get(pId);
1260
+ if (ps)
1261
+ predStates.push(ps);
1262
+ }
1263
+ inState = mergeStates(predStates);
1264
+ }
1265
+ // Apply transfer function
1266
+ const newOutState = applyTransfer(cfgNode, inState, sanitizerMap, callContext, filePath, constantMap);
1267
+ // Re-inject source seeds: if this node has sources, ensure their taint
1268
+ // survives the transfer function (which only sees predecessor in-state).
1269
+ // Phase 8: clone before mutating — getTaint may return internal Set reference
1270
+ const seeds = sourceSeeds.get(nodeId);
1271
+ if (seeds) {
1272
+ for (const seed of seeds) {
1273
+ if (seed.isDestructuring && seed.defs.size > 0) {
1274
+ for (const defVar of seed.defs) {
1275
+ const existing = new Set((0, propagation_types_1.getTaint)(newOutState, defVar) ?? []);
1276
+ for (const k of seed.kinds)
1277
+ existing.add(k);
1278
+ (0, propagation_types_1.setTaint)(newOutState, defVar, existing);
1279
+ }
1280
+ }
1281
+ else {
1282
+ const existing = new Set((0, propagation_types_1.getTaint)(newOutState, seed.variable) ?? []);
1283
+ for (const k of seed.kinds)
1284
+ existing.add(k);
1285
+ (0, propagation_types_1.setTaint)(newOutState, seed.variable, existing);
1286
+ if (seed.variable.includes('.')) {
1287
+ const root = seed.variable.split('.')[0];
1288
+ const rootExisting = new Set((0, propagation_types_1.getTaint)(newOutState, root) ?? []);
1289
+ for (const k of seed.kinds)
1290
+ rootExisting.add(k);
1291
+ (0, propagation_types_1.setTaint)(newOutState, root, rootExisting);
1292
+ }
1293
+ }
1294
+ }
1295
+ }
1296
+ // Check if state changed
1297
+ const oldOutState = outStates.get(nodeId);
1298
+ // Phase 8 (3d): identity check — if applyTransfer returned same ref, no change possible
1299
+ if (newOutState !== oldOutState && !statesEqual(newOutState, oldOutState)) {
1300
+ outStates.set(nodeId, newOutState);
1301
+ // Push all successors to worklist
1302
+ for (const succ of (0, cfg_builder_1.getSuccessors)(cfg, nodeId)) {
1303
+ worklist.add(succ);
1304
+ }
1305
+ }
1306
+ }
1307
+ if (iterations >= MAX_ITERATIONS) {
1308
+ console.warn(`[taint] Worklist hit iteration limit (${MAX_ITERATIONS}) for ${cfg.functionName} — results may be incomplete`);
1309
+ }
1310
+ return outStates;
1311
+ }
1312
+ /**
1313
+ * Check sinks for tainted data given computed out-states.
1314
+ * Returns findings for each source→sink pair with matching taint kinds.
1315
+ *
1316
+ * Exported as checkSinksInternal for use by taint-summary.ts (Phase 8).
1317
+ */
1318
+ function checkSinksInternal(cfg, outStates, sinkMappings, sourceMappings, filePath) {
1319
+ const findings = [];
1320
+ for (const { sink, cfgNodeId } of sinkMappings) {
1321
+ // The taint state at the sink is the in-state (merge of predecessor outs)
1322
+ const predIds = (0, cfg_builder_1.getPredecessors)(cfg, cfgNodeId);
1323
+ const predStates = [];
1324
+ for (const pId of predIds) {
1325
+ const ps = outStates.get(pId);
1326
+ if (ps)
1327
+ predStates.push(ps);
1328
+ }
1329
+ // Also include the sink node's own out-state predecessor contributions
1330
+ // But more importantly, check the in-state to the sink node
1331
+ const sinkInState = mergeStates(predStates);
1332
+ // Also check the out-state of the sink's own node (for cases where
1333
+ // source and sink are in the same statement or sink uses vars from its own node)
1334
+ const sinkOutState = outStates.get(cfgNodeId) ?? new Map();
1335
+ // Merge both for maximum coverage
1336
+ const combined = mergeStates([sinkInState, sinkOutState]);
1337
+ // Find which variables at this sink are tainted with matching kinds
1338
+ const sinkNode = cfg.nodes.get(cfgNodeId);
1339
+ if (!sinkNode)
1340
+ continue;
1341
+ // Get all variables used by the sink expression
1342
+ const sinkUses = extractSinkUses(sink, sinkNode);
1343
+ // Extract field-level accesses from the sink for precise taint checking
1344
+ const sinkFieldAccesses = extractSinkFieldAccesses(sink);
1345
+ for (const varName of sinkUses) {
1346
+ // Check if this variable has a field-level access in the sink
1347
+ const fieldAccess = sinkFieldAccesses.get(varName);
1348
+ const varTaint = fieldAccess
1349
+ ? (0, propagation_types_1.getFieldTaint)(combined, varName, fieldAccess)
1350
+ : (0, propagation_types_1.getTaint)(combined, varName);
1351
+ if (!varTaint || varTaint.size === 0)
1352
+ continue;
1353
+ // Find matching kinds: intersection of variable's taint and sink's vulnerable kinds
1354
+ const matchingKinds = new Set();
1355
+ for (const k of varTaint) {
1356
+ if (sink.vulnerableToKinds.has(k)) {
1357
+ matchingKinds.add(k);
1358
+ }
1359
+ }
1360
+ if (matchingKinds.size === 0)
1361
+ continue;
1362
+ // Find which source(s) contributed this taint
1363
+ for (const { source } of sourceMappings) {
1364
+ // Check if source's taint kinds overlap with matching kinds
1365
+ const sourceOverlap = new Set();
1366
+ for (const k of matchingKinds) {
1367
+ if (source.taintKinds.has(k))
1368
+ sourceOverlap.add(k);
1369
+ }
1370
+ if (sourceOverlap.size === 0)
1371
+ continue;
1372
+ // Reconstruct path
1373
+ const path = reconstructPath(cfg, outStates, source, sink, varName, sourceMappings, cfgNodeId);
1374
+ findings.push({
1375
+ source,
1376
+ sink,
1377
+ path,
1378
+ matchingKinds: sourceOverlap,
1379
+ functionName: cfg.functionName,
1380
+ filePath,
1381
+ });
1382
+ }
1383
+ }
1384
+ }
1385
+ return findings;
1386
+ }
1387
+ /**
1388
+ * Propagate taint through a single function's CFG.
1389
+ *
1390
+ * Returns all taint findings (source→sink pairs with matching kinds).
1391
+ * When callContext is provided, calls to imported/local functions are
1392
+ * resolved inter-procedurally.
1393
+ */
1394
+ function propagateFunction(cfg, sourceMappings, sinkMappings, sanitizerMap, filePath, callContext) {
1395
+ // Collect constants for this function scope
1396
+ const constantMap = cfg.functionNode ? (0, constant_propagation_1.collectConstants)(cfg.functionNode) : new Map();
1397
+ const outStates = runFixpointInternal(cfg, sourceMappings, sanitizerMap, filePath, callContext, constantMap);
1398
+ const findings = checkSinksInternal(cfg, outStates, sinkMappings, sourceMappings, filePath);
1399
+ return deduplicateFindings(findings);
1400
+ }
1401
+ /**
1402
+ * Extract variables used by a sink expression.
1403
+ * Uses the CFG node's `uses` set plus any identifiers in the sink's AST.
1404
+ *
1405
+ * When `sink.relevantArgNodes` is set (e.g., SSRF sinks), only variables
1406
+ * within those specific argument nodes are collected — taint in other
1407
+ * arguments (like request body) won't trigger the finding.
1408
+ */
1409
+ function extractSinkUses(sink, cfgNode) {
1410
+ // When the sink specifies relevant arg nodes, ONLY collect vars from those nodes.
1411
+ // This prevents e.g. tainted body data from triggering SSRF (which requires tainted URL).
1412
+ if (sink.relevantArgNodes && sink.relevantArgNodes.length > 0) {
1413
+ const uses = new Set();
1414
+ for (const argNode of sink.relevantArgNodes) {
1415
+ (0, ast_1.walkAST)(argNode, (node) => {
1416
+ if (node.type === 'identifier') {
1417
+ uses.add(node.text);
1418
+ }
1419
+ if (node.type === 'arrow_function' || node.type === 'function_expression')
1420
+ return true;
1421
+ return false;
1422
+ });
1423
+ }
1424
+ return uses;
1425
+ }
1426
+ // Default: collect from entire sink expression + CFG node uses
1427
+ const uses = new Set(cfgNode.uses);
1428
+ (0, ast_1.walkAST)(sink.node, (node) => {
1429
+ if (node.type === 'identifier') {
1430
+ uses.add(node.text);
1431
+ }
1432
+ if (node.type === 'arrow_function' || node.type === 'function_expression')
1433
+ return true;
1434
+ return false;
1435
+ });
1436
+ return uses;
1437
+ }
1438
+ /**
1439
+ * Extract one-level field accesses from a sink expression.
1440
+ * Returns a map of root variable → field name for `obj.field` patterns.
1441
+ * Used for field-sensitive sink checking.
1442
+ */
1443
+ function extractSinkFieldAccesses(sink) {
1444
+ const accesses = new Map();
1445
+ // Walk the sink's arguments to find member expression patterns
1446
+ (0, ast_1.walkAST)(sink.node, (node) => {
1447
+ if (node.type === 'member_expression') {
1448
+ const obj = node.childForFieldName('object');
1449
+ const prop = node.childForFieldName('property');
1450
+ if (obj?.type === 'identifier' && prop?.type === 'property_identifier') {
1451
+ accesses.set(obj.text, prop.text);
1452
+ }
1453
+ }
1454
+ if (node.type === 'arrow_function' || node.type === 'function_expression')
1455
+ return true;
1456
+ return false;
1457
+ });
1458
+ return accesses;
1459
+ }
1460
+ // ============================================================================
1461
+ // Path Reconstruction
1462
+ // ============================================================================
1463
+ /**
1464
+ * Reconstruct the path from source to sink via backward slice.
1465
+ */
1466
+ function reconstructPath(cfg, outStates, source, sink, sinkVar, sourceMappings, sinkNodeId) {
1467
+ const steps = [];
1468
+ // Step 1: Sink step
1469
+ const sinkNode = cfg.nodes.get(sinkNodeId);
1470
+ if (sinkNode) {
1471
+ steps.unshift({
1472
+ nodeId: sinkNodeId,
1473
+ line: sink.line,
1474
+ variable: sinkVar,
1475
+ taintKinds: new Set(sink.vulnerableToKinds),
1476
+ description: `SINK ${sink.expression.slice(0, 60)}`,
1477
+ stepType: 'sink',
1478
+ });
1479
+ }
1480
+ // Step 2: Walk backward from sink to source
1481
+ const visited = new Set();
1482
+ let currentVar = sinkVar;
1483
+ let currentNodeId = sinkNodeId;
1484
+ for (let depth = 0; depth < 50; depth++) {
1485
+ visited.add(currentNodeId);
1486
+ // Check if we've reached a source node
1487
+ const sourceMapping = sourceMappings.find(sm => sm.source === source && sm.cfgNodeId === currentNodeId);
1488
+ if (sourceMapping)
1489
+ break;
1490
+ // Find a predecessor that has taint for the current variable
1491
+ const predIds = (0, cfg_builder_1.getPredecessors)(cfg, currentNodeId);
1492
+ let foundPred = false;
1493
+ for (const predId of predIds) {
1494
+ if (visited.has(predId))
1495
+ continue;
1496
+ const predState = outStates.get(predId);
1497
+ if (!predState)
1498
+ continue;
1499
+ // Check if this predecessor contributes taint for our variable
1500
+ const predTaint = (0, propagation_types_1.getTaint)(predState, currentVar);
1501
+ if (!predTaint || predTaint.size === 0)
1502
+ continue;
1503
+ const predNode = cfg.nodes.get(predId);
1504
+ if (!predNode)
1505
+ continue;
1506
+ // Check if this node defines the variable (it's a propagation step)
1507
+ if (predNode.defs.has(currentVar)) {
1508
+ steps.unshift({
1509
+ nodeId: predId,
1510
+ line: predNode.line,
1511
+ variable: currentVar,
1512
+ taintKinds: new Set(predTaint),
1513
+ description: `ASSIGN ${predNode.label}`,
1514
+ stepType: 'propagation',
1515
+ });
1516
+ // Check what variable(s) contributed to this def
1517
+ // Look at the node's uses that are tainted
1518
+ for (const use of predNode.uses) {
1519
+ const useTaint = (0, propagation_types_1.getTaint)(predState, use); // check predecessor's state
1520
+ if (!useTaint || useTaint.size === 0) {
1521
+ // Also check in-state (merge of pred's preds)
1522
+ const predPredIds = (0, cfg_builder_1.getPredecessors)(cfg, predId);
1523
+ for (const ppId of predPredIds) {
1524
+ const ppState = outStates.get(ppId);
1525
+ const ppTaint = ppState ? (0, propagation_types_1.getTaint)(ppState, use) : undefined;
1526
+ if (ppTaint && ppTaint.size > 0) {
1527
+ currentVar = use;
1528
+ break;
1529
+ }
1530
+ }
1531
+ if (currentVar !== use)
1532
+ continue;
1533
+ }
1534
+ else {
1535
+ currentVar = use;
1536
+ }
1537
+ break;
1538
+ }
1539
+ }
1540
+ currentNodeId = predId;
1541
+ foundPred = true;
1542
+ break;
1543
+ }
1544
+ if (!foundPred)
1545
+ break;
1546
+ }
1547
+ // Step 3: Source step
1548
+ steps.unshift({
1549
+ nodeId: sourceMappings.find(sm => sm.source === source)?.cfgNodeId ?? 0,
1550
+ line: source.line,
1551
+ variable: source.variable,
1552
+ taintKinds: new Set(source.taintKinds),
1553
+ description: `SOURCE ${source.expression.slice(0, 60)}`,
1554
+ stepType: 'source',
1555
+ });
1556
+ return steps;
1557
+ }
1558
+ // ============================================================================
1559
+ // Deduplication
1560
+ // ============================================================================
1561
+ /**
1562
+ * Deduplicate findings: same source line + same sink line + same kinds = one finding.
1563
+ */
1564
+ function deduplicateFindings(findings) {
1565
+ const seen = new Set();
1566
+ const result = [];
1567
+ for (const f of findings) {
1568
+ const key = `${f.source.line}:${f.sink.line}:${[...f.matchingKinds].sort().join(',')}`;
1569
+ if (seen.has(key))
1570
+ continue;
1571
+ seen.add(key);
1572
+ result.push(f);
1573
+ }
1574
+ return result;
1575
+ }
1576
+ //# sourceMappingURL=propagation.js.map