@oculum/scanner 1.0.14 → 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 (1323) 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.map +1 -1
  199. package/dist/detect/secrets/config-audit.js +36 -3
  200. package/dist/detect/secrets/config-audit.js.map +1 -1
  201. package/dist/detect/secrets/entropy.d.ts.map +1 -1
  202. package/dist/detect/secrets/entropy.js +180 -0
  203. package/dist/detect/secrets/entropy.js.map +1 -1
  204. package/dist/detect/secrets/index.d.ts +0 -2
  205. package/dist/detect/secrets/index.d.ts.map +1 -1
  206. package/dist/detect/secrets/index.js +7 -17
  207. package/dist/detect/secrets/index.js.map +1 -1
  208. package/dist/detect/structural/index.d.ts +15 -28
  209. package/dist/detect/structural/index.d.ts.map +1 -1
  210. package/dist/detect/structural/index.js +20 -497
  211. package/dist/detect/structural/index.js.map +1 -1
  212. package/dist/index.d.ts +3 -0
  213. package/dist/index.d.ts.map +1 -1
  214. package/dist/index.js +9 -1
  215. package/dist/index.js.map +1 -1
  216. package/dist/model/auth-helper-detector.d.ts.map +1 -1
  217. package/dist/model/auth-helper-detector.js +2 -7
  218. package/dist/model/auth-helper-detector.js.map +1 -1
  219. package/dist/model/import-resolver.d.ts.map +1 -1
  220. package/dist/model/import-resolver.js +94 -0
  221. package/dist/model/import-resolver.js.map +1 -1
  222. package/dist/model/imported-auth-detector.js +8 -8
  223. package/dist/model/imported-auth-detector.js.map +1 -1
  224. package/dist/model/index.d.ts +8 -0
  225. package/dist/model/index.d.ts.map +1 -1
  226. package/dist/model/index.js +198 -73
  227. package/dist/model/index.js.map +1 -1
  228. package/dist/model/module-graph.d.ts.map +1 -1
  229. package/dist/model/module-graph.js +22 -9
  230. package/dist/model/module-graph.js.map +1 -1
  231. package/dist/model/project-context.d.ts +1 -1
  232. package/dist/model/project-context.d.ts.map +1 -1
  233. package/dist/model/project-context.js +34 -0
  234. package/dist/model/project-context.js.map +1 -1
  235. package/dist/model/route-auth-resolver.d.ts.map +1 -1
  236. package/dist/model/route-auth-resolver.js +17 -2
  237. package/dist/model/route-auth-resolver.js.map +1 -1
  238. package/dist/model/route-discovery/index.js +1 -1
  239. package/dist/model/route-discovery/index.js.map +1 -1
  240. package/dist/model/route-discovery/nextjs.js +1 -1
  241. package/dist/model/route-discovery/nextjs.js.map +1 -1
  242. package/dist/model/route-discovery/python.d.ts +6 -3
  243. package/dist/model/route-discovery/python.d.ts.map +1 -1
  244. package/dist/model/route-discovery/python.js +132 -9
  245. package/dist/model/route-discovery/python.js.map +1 -1
  246. package/dist/model/route-discovery/types.d.ts +1 -1
  247. package/dist/model/route-discovery/types.d.ts.map +1 -1
  248. package/dist/model/route-discovery/utils.d.ts +8 -0
  249. package/dist/model/route-discovery/utils.d.ts.map +1 -1
  250. package/dist/model/route-discovery/utils.js +70 -0
  251. package/dist/model/route-discovery/utils.js.map +1 -1
  252. package/dist/model/taint-types.d.ts +0 -4
  253. package/dist/model/taint-types.d.ts.map +1 -1
  254. package/dist/parse/ast.d.ts +58 -0
  255. package/dist/parse/ast.d.ts.map +1 -0
  256. package/dist/parse/ast.js +230 -0
  257. package/dist/parse/ast.js.map +1 -0
  258. package/dist/parse/call-graph.d.ts +41 -0
  259. package/dist/parse/call-graph.d.ts.map +1 -0
  260. package/dist/parse/call-graph.js +386 -0
  261. package/dist/parse/call-graph.js.map +1 -0
  262. package/dist/parse/file-classifier.d.ts +11 -0
  263. package/dist/parse/file-classifier.d.ts.map +1 -1
  264. package/dist/parse/file-classifier.js +63 -15
  265. package/dist/parse/file-classifier.js.map +1 -1
  266. package/dist/parse/node-index.d.ts +32 -0
  267. package/dist/parse/node-index.d.ts.map +1 -0
  268. package/dist/parse/node-index.js +103 -0
  269. package/dist/parse/node-index.js.map +1 -0
  270. package/dist/parse/type-extractor.d.ts +50 -0
  271. package/dist/parse/type-extractor.d.ts.map +1 -0
  272. package/dist/parse/type-extractor.js +243 -0
  273. package/dist/parse/type-extractor.js.map +1 -0
  274. package/dist/pipeline/config.d.ts +7 -1
  275. package/dist/pipeline/config.d.ts.map +1 -1
  276. package/dist/pipeline/config.js.map +1 -1
  277. package/dist/pipeline/index.d.ts +3 -3
  278. package/dist/pipeline/index.d.ts.map +1 -1
  279. package/dist/pipeline/index.js +192 -64
  280. package/dist/pipeline/index.js.map +1 -1
  281. package/dist/pipeline/modes/incremental.d.ts.map +1 -1
  282. package/dist/pipeline/modes/incremental.js +2 -7
  283. package/dist/pipeline/modes/incremental.js.map +1 -1
  284. package/dist/postprocess/dedup.d.ts +5 -2
  285. package/dist/postprocess/dedup.d.ts.map +1 -1
  286. package/dist/postprocess/dedup.js +47 -16
  287. package/dist/postprocess/dedup.js.map +1 -1
  288. package/dist/report/build-result.d.ts +9 -4
  289. package/dist/report/build-result.d.ts.map +1 -1
  290. package/dist/report/build-result.js +15 -4
  291. package/dist/report/build-result.js.map +1 -1
  292. package/dist/report/formatters/cli-terminal.d.ts +1 -1
  293. package/dist/report/formatters/cli-terminal.d.ts.map +1 -1
  294. package/dist/report/formatters/cli-terminal.js +434 -231
  295. package/dist/report/formatters/cli-terminal.js.map +1 -1
  296. package/dist/report/sanitize.d.ts +10 -0
  297. package/dist/report/sanitize.d.ts.map +1 -0
  298. package/dist/report/sanitize.js +19 -0
  299. package/dist/report/sanitize.js.map +1 -0
  300. package/dist/score/adjustments.d.ts +20 -2
  301. package/dist/score/adjustments.d.ts.map +1 -1
  302. package/dist/score/adjustments.js +108 -37
  303. package/dist/score/adjustments.js.map +1 -1
  304. package/dist/score/confidence.d.ts +6 -0
  305. package/dist/score/confidence.d.ts.map +1 -1
  306. package/dist/score/confidence.js +10 -4
  307. package/dist/score/confidence.js.map +1 -1
  308. package/dist/score/evidence.d.ts +25 -0
  309. package/dist/score/evidence.d.ts.map +1 -0
  310. package/dist/score/evidence.js +51 -0
  311. package/dist/score/evidence.js.map +1 -0
  312. package/dist/score/index.d.ts +3 -1
  313. package/dist/score/index.d.ts.map +1 -1
  314. package/dist/score/index.js +25 -50
  315. package/dist/score/index.js.map +1 -1
  316. package/dist/score/types.d.ts +5 -1
  317. package/dist/score/types.d.ts.map +1 -1
  318. package/dist/shared/category-filter.d.ts.map +1 -1
  319. package/dist/shared/category-filter.js +12 -0
  320. package/dist/shared/category-filter.js.map +1 -1
  321. package/dist/shared/regex-utils.d.ts +3 -0
  322. package/dist/shared/regex-utils.d.ts.map +1 -0
  323. package/dist/shared/regex-utils.js +8 -0
  324. package/dist/shared/regex-utils.js.map +1 -0
  325. package/dist/shared/registry-clients.d.ts +7 -0
  326. package/dist/shared/registry-clients.d.ts.map +1 -1
  327. package/dist/shared/registry-clients.js +94 -17
  328. package/dist/shared/registry-clients.js.map +1 -1
  329. package/dist/shared/rules/metadata.d.ts.map +1 -1
  330. package/dist/shared/rules/metadata.js +17 -0
  331. package/dist/shared/rules/metadata.js.map +1 -1
  332. package/dist/shared/types.d.ts +59 -15
  333. package/dist/shared/types.d.ts.map +1 -1
  334. package/dist/shared/types.js +38 -21
  335. package/dist/shared/types.js.map +1 -1
  336. package/dist/taint/async-flow.d.ts +44 -0
  337. package/dist/taint/async-flow.d.ts.map +1 -0
  338. package/dist/taint/async-flow.js +271 -0
  339. package/dist/taint/async-flow.js.map +1 -0
  340. package/dist/taint/cfg-builder.d.ts +35 -0
  341. package/dist/taint/cfg-builder.d.ts.map +1 -0
  342. package/dist/taint/cfg-builder.js +980 -0
  343. package/dist/taint/cfg-builder.js.map +1 -0
  344. package/dist/taint/cfg-types.d.ts +76 -0
  345. package/dist/taint/cfg-types.d.ts.map +1 -0
  346. package/dist/taint/cfg-types.js +13 -0
  347. package/dist/taint/cfg-types.js.map +1 -0
  348. package/dist/taint/constant-propagation.d.ts +34 -0
  349. package/dist/taint/constant-propagation.d.ts.map +1 -0
  350. package/dist/taint/constant-propagation.js +164 -0
  351. package/dist/taint/constant-propagation.js.map +1 -0
  352. package/dist/taint/cross-file-analyzer.d.ts +27 -0
  353. package/dist/taint/cross-file-analyzer.d.ts.map +1 -0
  354. package/dist/taint/cross-file-analyzer.js +99 -0
  355. package/dist/taint/cross-file-analyzer.js.map +1 -0
  356. package/dist/taint/cross-file-index.d.ts +59 -0
  357. package/dist/taint/cross-file-index.d.ts.map +1 -0
  358. package/dist/taint/cross-file-index.js +183 -0
  359. package/dist/taint/cross-file-index.js.map +1 -0
  360. package/dist/taint/def-use.d.ts +27 -0
  361. package/dist/taint/def-use.d.ts.map +1 -0
  362. package/dist/taint/def-use.js +519 -0
  363. package/dist/taint/def-use.js.map +1 -0
  364. package/dist/taint/file-analysis-cache.d.ts +47 -0
  365. package/dist/taint/file-analysis-cache.d.ts.map +1 -0
  366. package/dist/taint/file-analysis-cache.js +107 -0
  367. package/dist/taint/file-analysis-cache.js.map +1 -0
  368. package/dist/taint/framework-models.d.ts +77 -0
  369. package/dist/taint/framework-models.d.ts.map +1 -0
  370. package/dist/taint/framework-models.js +258 -0
  371. package/dist/taint/framework-models.js.map +1 -0
  372. package/dist/taint/helpers.d.ts +31 -0
  373. package/dist/taint/helpers.d.ts.map +1 -0
  374. package/dist/taint/helpers.js +130 -0
  375. package/dist/taint/helpers.js.map +1 -0
  376. package/dist/taint/index.d.ts +28 -0
  377. package/dist/taint/index.d.ts.map +1 -0
  378. package/dist/taint/index.js +77 -0
  379. package/dist/taint/index.js.map +1 -0
  380. package/dist/taint/llm-registry.d.ts +47 -0
  381. package/dist/taint/llm-registry.d.ts.map +1 -0
  382. package/dist/taint/llm-registry.js +152 -0
  383. package/dist/taint/llm-registry.js.map +1 -0
  384. package/dist/taint/llm-risk-scoring.d.ts +54 -0
  385. package/dist/taint/llm-risk-scoring.d.ts.map +1 -0
  386. package/dist/taint/llm-risk-scoring.js +376 -0
  387. package/dist/taint/llm-risk-scoring.js.map +1 -0
  388. package/dist/taint/propagation-types.d.ts +104 -0
  389. package/dist/taint/propagation-types.d.ts.map +1 -0
  390. package/dist/taint/propagation-types.js +98 -0
  391. package/dist/taint/propagation-types.js.map +1 -0
  392. package/dist/taint/propagation.d.ts +111 -0
  393. package/dist/taint/propagation.d.ts.map +1 -0
  394. package/dist/taint/propagation.js +1576 -0
  395. package/dist/taint/propagation.js.map +1 -0
  396. package/dist/taint/sanitizer-registry.d.ts +26 -0
  397. package/dist/taint/sanitizer-registry.d.ts.map +1 -0
  398. package/dist/taint/sanitizer-registry.js +422 -0
  399. package/dist/taint/sanitizer-registry.js.map +1 -0
  400. package/dist/taint/sink-classifier.d.ts +27 -0
  401. package/dist/taint/sink-classifier.d.ts.map +1 -0
  402. package/dist/taint/sink-classifier.js +1166 -0
  403. package/dist/taint/sink-classifier.js.map +1 -0
  404. package/dist/taint/source-classifier.d.ts +29 -0
  405. package/dist/taint/source-classifier.d.ts.map +1 -0
  406. package/dist/taint/source-classifier.js +814 -0
  407. package/dist/taint/source-classifier.js.map +1 -0
  408. package/dist/taint/taint-analyzer.d.ts +33 -0
  409. package/dist/taint/taint-analyzer.d.ts.map +1 -0
  410. package/dist/taint/taint-analyzer.js +88 -0
  411. package/dist/taint/taint-analyzer.js.map +1 -0
  412. package/dist/taint/taint-summary.d.ts +37 -0
  413. package/dist/taint/taint-summary.d.ts.map +1 -0
  414. package/dist/taint/taint-summary.js +293 -0
  415. package/dist/taint/taint-summary.js.map +1 -0
  416. package/dist/taint/types.d.ts +47 -0
  417. package/dist/taint/types.d.ts.map +1 -0
  418. package/dist/taint/types.js +19 -0
  419. package/dist/taint/types.js.map +1 -0
  420. package/dist/validate/clients.d.ts +2 -1
  421. package/dist/validate/clients.d.ts.map +1 -1
  422. package/dist/validate/clients.js +3 -2
  423. package/dist/validate/clients.js.map +1 -1
  424. package/dist/validate/index.d.ts +5 -6
  425. package/dist/validate/index.d.ts.map +1 -1
  426. package/dist/validate/index.js +22 -21
  427. package/dist/validate/index.js.map +1 -1
  428. package/dist/validate/prompts/modules/ai-patterns.d.ts +1 -1
  429. package/dist/validate/prompts/modules/ai-patterns.d.ts.map +1 -1
  430. package/dist/validate/prompts/modules/ai-patterns.js +16 -0
  431. package/dist/validate/prompts/modules/ai-patterns.js.map +1 -1
  432. package/dist/validate/prompts/modules/common.d.ts +1 -1
  433. package/dist/validate/prompts/modules/common.d.ts.map +1 -1
  434. package/dist/validate/prompts/modules/common.js +12 -3
  435. package/dist/validate/prompts/modules/common.js.map +1 -1
  436. package/dist/validate/providers/anthropic.d.ts +4 -4
  437. package/dist/validate/providers/anthropic.d.ts.map +1 -1
  438. package/dist/validate/providers/anthropic.js +85 -58
  439. package/dist/validate/providers/anthropic.js.map +1 -1
  440. package/dist/validate/providers/openai.d.ts +4 -4
  441. package/dist/validate/providers/openai.d.ts.map +1 -1
  442. package/dist/validate/providers/openai.js +149 -99
  443. package/dist/validate/providers/openai.js.map +1 -1
  444. package/dist/validate/request-builder.d.ts +2 -8
  445. package/dist/validate/request-builder.d.ts.map +1 -1
  446. package/dist/validate/request-builder.js +4 -34
  447. package/dist/validate/request-builder.js.map +1 -1
  448. package/dist/validate/types.d.ts +9 -0
  449. package/dist/validate/types.d.ts.map +1 -1
  450. package/dist/validate/types.js.map +1 -1
  451. package/dist/validate/utils/path-helpers.js +2 -2
  452. package/dist/validate/utils/path-helpers.js.map +1 -1
  453. package/dist/validate/utils/response-parser.d.ts +10 -0
  454. package/dist/validate/utils/response-parser.d.ts.map +1 -1
  455. package/dist/validate/utils/response-parser.js +21 -2
  456. package/dist/validate/utils/response-parser.js.map +1 -1
  457. package/dist/validate/utils/retry.d.ts.map +1 -1
  458. package/dist/validate/utils/retry.js +19 -4
  459. package/dist/validate/utils/retry.js.map +1 -1
  460. package/package.json +7 -4
  461. package/src/__tests__/benchmark/fixtures/layer2/ai-execution-sinks.ts +1 -1
  462. package/src/__tests__/benchmark/planted-benchmark.test.ts +337 -0
  463. package/src/__tests__/benchmark/utils/test-runner.ts +38 -4
  464. package/src/__tests__/category-filter.test.ts +5 -1
  465. package/src/__tests__/context-engine/route-discovery/python.test.ts +726 -0
  466. package/src/__tests__/detect/ast-rules.test.ts +1043 -0
  467. package/src/__tests__/detect/offline-mode.test.ts +147 -0
  468. package/src/__tests__/detect/python-ast-rules.test.ts +569 -0
  469. package/src/__tests__/detect/python-helpers.test.ts +536 -0
  470. package/src/__tests__/detect/python-sast-rules.test.ts +453 -0
  471. package/src/__tests__/detect/rules-file-backdoor-decoders.test.ts +151 -0
  472. package/src/__tests__/detect/rules-file-backdoor.test.ts +284 -0
  473. package/src/__tests__/detect/taint-fix-templates.test.ts +150 -0
  474. package/src/__tests__/detect/taint-path-serialization.test.ts +170 -0
  475. package/src/__tests__/parse/call-graph.test.ts +300 -0
  476. package/src/__tests__/parse/python-parser.test.ts +274 -0
  477. package/src/__tests__/regression/known-false-positives.test.ts +491 -9
  478. package/src/__tests__/regression/rules-file-backdoor.test.ts +137 -0
  479. package/src/__tests__/score/adjustments.test.ts +34 -16
  480. package/src/__tests__/score/confidence.test.ts +84 -57
  481. package/src/__tests__/score/evidence-scoring.test.ts +249 -0
  482. package/src/__tests__/score/evidence.test.ts +144 -0
  483. package/src/__tests__/score/scoring-integration.test.ts +56 -34
  484. package/src/__tests__/score/taint-adjustments.test.ts +14 -228
  485. package/src/__tests__/snapshots/__snapshots__/scan-depth.test.ts.snap +65 -59
  486. package/src/__tests__/snapshots/scan-depth.test.ts +39 -7
  487. package/src/__tests__/taint/async-flow.test.ts +247 -0
  488. package/src/__tests__/taint/cfg-builder.test.ts +835 -0
  489. package/src/__tests__/taint/constant-propagation.test.ts +302 -0
  490. package/src/__tests__/taint/cross-file-index.test.ts +683 -0
  491. package/src/__tests__/taint/cross-file-integration.test.ts +275 -0
  492. package/src/__tests__/taint/cross-file-propagation.test.ts +910 -0
  493. package/src/__tests__/taint/def-use.test.ts +132 -0
  494. package/src/__tests__/taint/field-sensitive-sinks.test.ts +179 -0
  495. package/src/__tests__/taint/field-sensitivity.test.ts +342 -0
  496. package/src/__tests__/taint/file-analysis-cache.test.ts +290 -0
  497. package/src/__tests__/taint/framework-models.test.ts +227 -0
  498. package/src/__tests__/taint/llm-flow-graph.test.ts +850 -0
  499. package/src/__tests__/taint/llm-risk-scoring.test.ts +439 -0
  500. package/src/__tests__/taint/performance-parity.test.ts +315 -0
  501. package/src/__tests__/taint/propagation.test.ts +621 -0
  502. package/src/__tests__/taint/python-cross-file.test.ts +494 -0
  503. package/src/__tests__/taint/python-taint.test.ts +1344 -0
  504. package/src/__tests__/taint/sanitizer-registry.test.ts +304 -0
  505. package/src/__tests__/taint/sanitizer-regression.test.ts +111 -0
  506. package/src/__tests__/taint/sink-classifier.test.ts +537 -0
  507. package/src/__tests__/taint/source-classifier.test.ts +367 -0
  508. package/src/__tests__/taint/taint-pipeline.test.ts +418 -0
  509. package/src/__tests__/taint/taint-smoke.test.ts +400 -0
  510. package/src/__tests__/taint/taint-summary.test.ts +472 -0
  511. package/src/detect/ai-code/index.ts +6 -11
  512. package/src/detect/ast-rules/agent-tools-ast.ts +861 -0
  513. package/src/detect/ast-rules/ai-fingerprinting-ast.ts +451 -0
  514. package/src/detect/ast-rules/auth-patterns-ast.ts +304 -0
  515. package/src/detect/ast-rules/byok-ast.ts +195 -0
  516. package/src/detect/ast-rules/child-process-ast.ts +276 -0
  517. package/src/detect/ast-rules/dangerous-eval-ast.ts +227 -0
  518. package/src/detect/ast-rules/data-exposure-ast.ts +162 -0
  519. package/src/detect/ast-rules/dom-xss-ast.ts +260 -0
  520. package/src/detect/ast-rules/endpoint-protection-ast.ts +231 -0
  521. package/src/detect/ast-rules/entropy-ast.ts +268 -0
  522. package/src/detect/ast-rules/flask-debug-ast.ts +148 -0
  523. package/src/detect/ast-rules/framework-checks-ast.ts +200 -0
  524. package/src/detect/ast-rules/helpers/call-analysis.ts +256 -0
  525. package/src/detect/ast-rules/helpers/context-detection.ts +277 -0
  526. package/src/detect/ast-rules/helpers/control-flow.ts +179 -0
  527. package/src/detect/ast-rules/helpers/import-analysis.ts +185 -0
  528. package/src/detect/ast-rules/helpers/index.ts +133 -0
  529. package/src/detect/ast-rules/helpers/python-helpers.ts +1054 -0
  530. package/src/detect/ast-rules/helpers/scope-analysis.ts +224 -0
  531. package/src/detect/ast-rules/helpers/string-analysis.ts +215 -0
  532. package/src/detect/ast-rules/helpers/type-extraction.ts +138 -0
  533. package/src/detect/ast-rules/helpers/user-input.ts +256 -0
  534. package/src/detect/ast-rules/index.ts +311 -0
  535. package/src/detect/ast-rules/json-parse-ast.ts +162 -0
  536. package/src/detect/ast-rules/log-injection-ast.ts +243 -0
  537. package/src/detect/ast-rules/logic-gates-ast.ts +343 -0
  538. package/src/detect/ast-rules/mcp-security-ast.ts +808 -0
  539. package/src/detect/ast-rules/model-supply-chain-ast.ts +202 -0
  540. package/src/detect/ast-rules/package-hallucination-ast.ts +664 -0
  541. package/src/detect/ast-rules/prompt-hygiene-ast.ts +329 -0
  542. package/src/detect/ast-rules/rag-safety-ast.ts +689 -0
  543. package/src/detect/ast-rules/request-validation-ast.ts +122 -0
  544. package/src/detect/ast-rules/risky-imports-ast.ts +133 -0
  545. package/src/detect/ast-rules/schema-validation-ast.ts +244 -0
  546. package/src/detect/ast-rules/secret-patterns-ast.ts +223 -0
  547. package/src/detect/ast-rules/security-headers-ast.ts +206 -0
  548. package/src/detect/ast-rules/sql-injection-ast.ts +614 -0
  549. package/src/detect/ast-rules/ssrf-ast.ts +601 -0
  550. package/src/detect/ast-rules/taint-fix-templates.ts +108 -0
  551. package/src/detect/ast-rules/taint-flow-ast.ts +416 -0
  552. package/src/detect/ast-rules/variables-ast.ts +446 -0
  553. package/src/detect/ast-rules/weak-crypto-ast.ts +441 -0
  554. package/src/detect/ast-rules/xxe-ast.ts +184 -0
  555. package/src/detect/config/agent-skill-injection.ts +2 -24
  556. package/src/detect/config/index.ts +1 -0
  557. package/src/detect/config/osv-check.ts +6 -1
  558. package/src/detect/config/package-check.ts +6 -1
  559. package/src/detect/config/rules-file-backdoor.ts +438 -0
  560. package/src/detect/index.ts +146 -52
  561. package/src/detect/secrets/config-audit.ts +37 -3
  562. package/src/detect/secrets/entropy.ts +195 -0
  563. package/src/detect/secrets/index.ts +7 -16
  564. package/src/detect/structural/index.ts +23 -566
  565. package/src/index.ts +7 -0
  566. package/src/model/auth-helper-detector.ts +1 -7
  567. package/src/model/import-resolver.ts +104 -0
  568. package/src/model/imported-auth-detector.ts +1 -1
  569. package/src/model/index.ts +240 -80
  570. package/src/model/module-graph.ts +17 -5
  571. package/src/model/project-context.ts +28 -1
  572. package/src/model/route-auth-resolver.ts +18 -3
  573. package/src/model/route-discovery/index.ts +1 -1
  574. package/src/model/route-discovery/nextjs.ts +1 -1
  575. package/src/model/route-discovery/python.ts +156 -9
  576. package/src/model/route-discovery/types.ts +1 -1
  577. package/src/model/route-discovery/utils.ts +73 -0
  578. package/src/model/taint-types.ts +1 -6
  579. package/src/parse/ast.ts +271 -0
  580. package/src/parse/call-graph.ts +419 -0
  581. package/src/parse/file-classifier.ts +69 -15
  582. package/src/parse/node-index.ts +118 -0
  583. package/src/parse/type-extractor.ts +293 -0
  584. package/src/pipeline/config.ts +7 -0
  585. package/src/pipeline/index.ts +464 -199
  586. package/src/pipeline/modes/incremental.ts +1 -7
  587. package/src/postprocess/dedup.ts +48 -17
  588. package/src/report/build-result.ts +57 -29
  589. package/src/report/formatters/cli-terminal.ts +731 -415
  590. package/src/report/sanitize.ts +27 -0
  591. package/src/score/adjustments.ts +113 -40
  592. package/src/score/confidence.ts +10 -5
  593. package/src/score/evidence.ts +55 -0
  594. package/src/score/index.ts +27 -55
  595. package/src/score/types.ts +4 -0
  596. package/src/shared/category-filter.ts +12 -0
  597. package/src/shared/regex-utils.ts +4 -0
  598. package/src/shared/registry-clients.ts +106 -18
  599. package/src/shared/rules/__tests__/metadata.test.ts +5 -1
  600. package/src/shared/rules/metadata.ts +19 -0
  601. package/src/shared/types.ts +372 -253
  602. package/src/taint/async-flow.ts +301 -0
  603. package/src/taint/cfg-builder.ts +1127 -0
  604. package/src/taint/cfg-types.ts +110 -0
  605. package/src/taint/constant-propagation.ts +170 -0
  606. package/src/taint/cross-file-analyzer.ts +118 -0
  607. package/src/taint/cross-file-index.ts +275 -0
  608. package/src/taint/def-use.ts +556 -0
  609. package/src/taint/file-analysis-cache.ts +145 -0
  610. package/src/taint/framework-models.ts +313 -0
  611. package/src/taint/helpers.ts +138 -0
  612. package/src/taint/index.ts +71 -0
  613. package/src/taint/llm-registry.ts +174 -0
  614. package/src/taint/llm-risk-scoring.ts +412 -0
  615. package/src/taint/propagation-types.ts +188 -0
  616. package/src/taint/propagation.ts +1750 -0
  617. package/src/taint/sanitizer-registry.ts +490 -0
  618. package/src/taint/sink-classifier.ts +1402 -0
  619. package/src/taint/source-classifier.ts +859 -0
  620. package/src/taint/taint-analyzer.ts +112 -0
  621. package/src/taint/taint-summary.ts +341 -0
  622. package/src/taint/types.ts +86 -0
  623. package/src/validate/clients.ts +3 -2
  624. package/src/validate/index.ts +89 -53
  625. package/src/validate/prompts/modules/ai-patterns.ts +16 -0
  626. package/src/validate/prompts/modules/common.ts +12 -3
  627. package/src/validate/providers/anthropic.ts +254 -148
  628. package/src/validate/providers/openai.ts +363 -218
  629. package/src/validate/request-builder.ts +2 -45
  630. package/src/validate/types.ts +9 -0
  631. package/src/validate/utils/path-helpers.ts +2 -2
  632. package/src/validate/utils/response-parser.ts +32 -3
  633. package/src/validate/utils/retry.ts +19 -4
  634. package/dist/ai-context/index.d.ts +0 -6
  635. package/dist/ai-context/index.d.ts.map +0 -1
  636. package/dist/ai-context/index.js +0 -13
  637. package/dist/ai-context/index.js.map +0 -1
  638. package/dist/ai-context/manager.d.ts +0 -67
  639. package/dist/ai-context/manager.d.ts.map +0 -1
  640. package/dist/ai-context/manager.js +0 -104
  641. package/dist/ai-context/manager.js.map +0 -1
  642. package/dist/baseline/diff.d.ts +0 -32
  643. package/dist/baseline/diff.d.ts.map +0 -1
  644. package/dist/baseline/diff.js +0 -119
  645. package/dist/baseline/diff.js.map +0 -1
  646. package/dist/baseline/index.d.ts +0 -9
  647. package/dist/baseline/index.d.ts.map +0 -1
  648. package/dist/baseline/index.js +0 -19
  649. package/dist/baseline/index.js.map +0 -1
  650. package/dist/baseline/manager.d.ts +0 -67
  651. package/dist/baseline/manager.d.ts.map +0 -1
  652. package/dist/baseline/manager.js +0 -180
  653. package/dist/baseline/manager.js.map +0 -1
  654. package/dist/baseline/types.d.ts +0 -91
  655. package/dist/baseline/types.d.ts.map +0 -1
  656. package/dist/baseline/types.js +0 -12
  657. package/dist/baseline/types.js.map +0 -1
  658. package/dist/category-filter.d.ts +0 -125
  659. package/dist/category-filter.d.ts.map +0 -1
  660. package/dist/category-filter.js +0 -360
  661. package/dist/category-filter.js.map +0 -1
  662. package/dist/detect/ai-code/agent-tools.d.ts +0 -22
  663. package/dist/detect/ai-code/agent-tools.d.ts.map +0 -1
  664. package/dist/detect/ai-code/agent-tools.js +0 -1509
  665. package/dist/detect/ai-code/agent-tools.js.map +0 -1
  666. package/dist/detect/ai-code/byok-patterns.d.ts +0 -15
  667. package/dist/detect/ai-code/byok-patterns.d.ts.map +0 -1
  668. package/dist/detect/ai-code/byok-patterns.js +0 -313
  669. package/dist/detect/ai-code/byok-patterns.js.map +0 -1
  670. package/dist/detect/ai-code/endpoint-protection.d.ts +0 -38
  671. package/dist/detect/ai-code/endpoint-protection.d.ts.map +0 -1
  672. package/dist/detect/ai-code/endpoint-protection.js +0 -349
  673. package/dist/detect/ai-code/endpoint-protection.js.map +0 -1
  674. package/dist/detect/ai-code/execution-sinks.d.ts +0 -21
  675. package/dist/detect/ai-code/execution-sinks.d.ts.map +0 -1
  676. package/dist/detect/ai-code/execution-sinks.js +0 -1158
  677. package/dist/detect/ai-code/execution-sinks.js.map +0 -1
  678. package/dist/detect/ai-code/fingerprinting.d.ts +0 -10
  679. package/dist/detect/ai-code/fingerprinting.d.ts.map +0 -1
  680. package/dist/detect/ai-code/fingerprinting.js +0 -665
  681. package/dist/detect/ai-code/fingerprinting.js.map +0 -1
  682. package/dist/detect/ai-code/mcp-security.d.ts +0 -20
  683. package/dist/detect/ai-code/mcp-security.d.ts.map +0 -1
  684. package/dist/detect/ai-code/mcp-security.js +0 -880
  685. package/dist/detect/ai-code/mcp-security.js.map +0 -1
  686. package/dist/detect/ai-code/model-supply-chain.d.ts +0 -23
  687. package/dist/detect/ai-code/model-supply-chain.d.ts.map +0 -1
  688. package/dist/detect/ai-code/model-supply-chain.js +0 -447
  689. package/dist/detect/ai-code/model-supply-chain.js.map +0 -1
  690. package/dist/detect/ai-code/package-hallucination.d.ts +0 -22
  691. package/dist/detect/ai-code/package-hallucination.d.ts.map +0 -1
  692. package/dist/detect/ai-code/package-hallucination.js +0 -841
  693. package/dist/detect/ai-code/package-hallucination.js.map +0 -1
  694. package/dist/detect/ai-code/prompt-hygiene.d.ts +0 -22
  695. package/dist/detect/ai-code/prompt-hygiene.d.ts.map +0 -1
  696. package/dist/detect/ai-code/prompt-hygiene.js +0 -1177
  697. package/dist/detect/ai-code/prompt-hygiene.js.map +0 -1
  698. package/dist/detect/ai-code/rag-safety.d.ts +0 -24
  699. package/dist/detect/ai-code/rag-safety.d.ts.map +0 -1
  700. package/dist/detect/ai-code/rag-safety.js +0 -913
  701. package/dist/detect/ai-code/rag-safety.js.map +0 -1
  702. package/dist/detect/ai-code/schema-validation.d.ts +0 -28
  703. package/dist/detect/ai-code/schema-validation.d.ts.map +0 -1
  704. package/dist/detect/ai-code/schema-validation.js +0 -378
  705. package/dist/detect/ai-code/schema-validation.js.map +0 -1
  706. package/dist/detect/secrets/patterns.d.ts +0 -11
  707. package/dist/detect/secrets/patterns.d.ts.map +0 -1
  708. package/dist/detect/secrets/patterns.js +0 -518
  709. package/dist/detect/secrets/patterns.js.map +0 -1
  710. package/dist/detect/secrets/weak-crypto.d.ts +0 -10
  711. package/dist/detect/secrets/weak-crypto.d.ts.map +0 -1
  712. package/dist/detect/secrets/weak-crypto.js +0 -432
  713. package/dist/detect/secrets/weak-crypto.js.map +0 -1
  714. package/dist/detect/structural/auth-patterns.d.ts +0 -22
  715. package/dist/detect/structural/auth-patterns.d.ts.map +0 -1
  716. package/dist/detect/structural/auth-patterns.js +0 -533
  717. package/dist/detect/structural/auth-patterns.js.map +0 -1
  718. package/dist/detect/structural/dangerous-functions/child-process.d.ts +0 -16
  719. package/dist/detect/structural/dangerous-functions/child-process.d.ts.map +0 -1
  720. package/dist/detect/structural/dangerous-functions/child-process.js +0 -74
  721. package/dist/detect/structural/dangerous-functions/child-process.js.map +0 -1
  722. package/dist/detect/structural/dangerous-functions/dom-xss.d.ts +0 -34
  723. package/dist/detect/structural/dangerous-functions/dom-xss.d.ts.map +0 -1
  724. package/dist/detect/structural/dangerous-functions/dom-xss.js +0 -230
  725. package/dist/detect/structural/dangerous-functions/dom-xss.js.map +0 -1
  726. package/dist/detect/structural/dangerous-functions/index.d.ts +0 -16
  727. package/dist/detect/structural/dangerous-functions/index.d.ts.map +0 -1
  728. package/dist/detect/structural/dangerous-functions/index.js +0 -1193
  729. package/dist/detect/structural/dangerous-functions/index.js.map +0 -1
  730. package/dist/detect/structural/dangerous-functions/json-parse.d.ts +0 -31
  731. package/dist/detect/structural/dangerous-functions/json-parse.d.ts.map +0 -1
  732. package/dist/detect/structural/dangerous-functions/json-parse.js +0 -326
  733. package/dist/detect/structural/dangerous-functions/json-parse.js.map +0 -1
  734. package/dist/detect/structural/dangerous-functions/math-random.d.ts +0 -111
  735. package/dist/detect/structural/dangerous-functions/math-random.d.ts.map +0 -1
  736. package/dist/detect/structural/dangerous-functions/math-random.js +0 -684
  737. package/dist/detect/structural/dangerous-functions/math-random.js.map +0 -1
  738. package/dist/detect/structural/dangerous-functions/patterns.d.ts +0 -21
  739. package/dist/detect/structural/dangerous-functions/patterns.d.ts.map +0 -1
  740. package/dist/detect/structural/dangerous-functions/patterns.js +0 -163
  741. package/dist/detect/structural/dangerous-functions/patterns.js.map +0 -1
  742. package/dist/detect/structural/dangerous-functions/request-validation.d.ts +0 -13
  743. package/dist/detect/structural/dangerous-functions/request-validation.d.ts.map +0 -1
  744. package/dist/detect/structural/dangerous-functions/request-validation.js +0 -126
  745. package/dist/detect/structural/dangerous-functions/request-validation.js.map +0 -1
  746. package/dist/detect/structural/dangerous-functions/utils/control-flow.d.ts +0 -24
  747. package/dist/detect/structural/dangerous-functions/utils/control-flow.d.ts.map +0 -1
  748. package/dist/detect/structural/dangerous-functions/utils/control-flow.js +0 -70
  749. package/dist/detect/structural/dangerous-functions/utils/control-flow.js.map +0 -1
  750. package/dist/detect/structural/dangerous-functions/utils/helpers.d.ts +0 -31
  751. package/dist/detect/structural/dangerous-functions/utils/helpers.d.ts.map +0 -1
  752. package/dist/detect/structural/dangerous-functions/utils/helpers.js +0 -147
  753. package/dist/detect/structural/dangerous-functions/utils/helpers.js.map +0 -1
  754. package/dist/detect/structural/dangerous-functions/utils/index.d.ts +0 -9
  755. package/dist/detect/structural/dangerous-functions/utils/index.d.ts.map +0 -1
  756. package/dist/detect/structural/dangerous-functions/utils/index.js +0 -23
  757. package/dist/detect/structural/dangerous-functions/utils/index.js.map +0 -1
  758. package/dist/detect/structural/dangerous-functions/utils/schema-validation.d.ts +0 -22
  759. package/dist/detect/structural/dangerous-functions/utils/schema-validation.d.ts.map +0 -1
  760. package/dist/detect/structural/dangerous-functions/utils/schema-validation.js +0 -102
  761. package/dist/detect/structural/dangerous-functions/utils/schema-validation.js.map +0 -1
  762. package/dist/detect/structural/data-exposure.d.ts +0 -19
  763. package/dist/detect/structural/data-exposure.d.ts.map +0 -1
  764. package/dist/detect/structural/data-exposure.js +0 -262
  765. package/dist/detect/structural/data-exposure.js.map +0 -1
  766. package/dist/detect/structural/framework-checks.d.ts +0 -10
  767. package/dist/detect/structural/framework-checks.d.ts.map +0 -1
  768. package/dist/detect/structural/framework-checks.js +0 -389
  769. package/dist/detect/structural/framework-checks.js.map +0 -1
  770. package/dist/detect/structural/log-injection.d.ts +0 -18
  771. package/dist/detect/structural/log-injection.d.ts.map +0 -1
  772. package/dist/detect/structural/log-injection.js +0 -217
  773. package/dist/detect/structural/log-injection.js.map +0 -1
  774. package/dist/detect/structural/logic-gates.d.ts +0 -10
  775. package/dist/detect/structural/logic-gates.d.ts.map +0 -1
  776. package/dist/detect/structural/logic-gates.js +0 -227
  777. package/dist/detect/structural/logic-gates.js.map +0 -1
  778. package/dist/detect/structural/risky-imports.d.ts +0 -10
  779. package/dist/detect/structural/risky-imports.d.ts.map +0 -1
  780. package/dist/detect/structural/risky-imports.js +0 -168
  781. package/dist/detect/structural/risky-imports.js.map +0 -1
  782. package/dist/detect/structural/security-headers.d.ts +0 -18
  783. package/dist/detect/structural/security-headers.d.ts.map +0 -1
  784. package/dist/detect/structural/security-headers.js +0 -196
  785. package/dist/detect/structural/security-headers.js.map +0 -1
  786. package/dist/detect/structural/ssrf-detection.d.ts +0 -18
  787. package/dist/detect/structural/ssrf-detection.d.ts.map +0 -1
  788. package/dist/detect/structural/ssrf-detection.js +0 -263
  789. package/dist/detect/structural/ssrf-detection.js.map +0 -1
  790. package/dist/detect/structural/variables.d.ts +0 -11
  791. package/dist/detect/structural/variables.d.ts.map +0 -1
  792. package/dist/detect/structural/variables.js +0 -159
  793. package/dist/detect/structural/variables.js.map +0 -1
  794. package/dist/detect/structural/xxe-detection.d.ts +0 -18
  795. package/dist/detect/structural/xxe-detection.d.ts.map +0 -1
  796. package/dist/detect/structural/xxe-detection.js +0 -245
  797. package/dist/detect/structural/xxe-detection.js.map +0 -1
  798. package/dist/filtering/context-adjustments.d.ts +0 -23
  799. package/dist/filtering/context-adjustments.d.ts.map +0 -1
  800. package/dist/filtering/context-adjustments.js +0 -100
  801. package/dist/filtering/context-adjustments.js.map +0 -1
  802. package/dist/filtering/index.d.ts +0 -3
  803. package/dist/filtering/index.d.ts.map +0 -1
  804. package/dist/filtering/index.js +0 -8
  805. package/dist/filtering/index.js.map +0 -1
  806. package/dist/filtering/pipeline.d.ts +0 -48
  807. package/dist/filtering/pipeline.d.ts.map +0 -1
  808. package/dist/filtering/pipeline.js +0 -76
  809. package/dist/filtering/pipeline.js.map +0 -1
  810. package/dist/formatters/ai-context.d.ts +0 -23
  811. package/dist/formatters/ai-context.d.ts.map +0 -1
  812. package/dist/formatters/ai-context.js +0 -238
  813. package/dist/formatters/ai-context.js.map +0 -1
  814. package/dist/formatters/cli-terminal.d.ts +0 -65
  815. package/dist/formatters/cli-terminal.d.ts.map +0 -1
  816. package/dist/formatters/cli-terminal.js +0 -735
  817. package/dist/formatters/cli-terminal.js.map +0 -1
  818. package/dist/formatters/github-comment.d.ts +0 -41
  819. package/dist/formatters/github-comment.d.ts.map +0 -1
  820. package/dist/formatters/github-comment.js +0 -370
  821. package/dist/formatters/github-comment.js.map +0 -1
  822. package/dist/formatters/grouping.d.ts +0 -52
  823. package/dist/formatters/grouping.d.ts.map +0 -1
  824. package/dist/formatters/grouping.js +0 -152
  825. package/dist/formatters/grouping.js.map +0 -1
  826. package/dist/formatters/ide/claude-code.d.ts +0 -17
  827. package/dist/formatters/ide/claude-code.d.ts.map +0 -1
  828. package/dist/formatters/ide/claude-code.js +0 -94
  829. package/dist/formatters/ide/claude-code.js.map +0 -1
  830. package/dist/formatters/ide/cursor.d.ts +0 -13
  831. package/dist/formatters/ide/cursor.d.ts.map +0 -1
  832. package/dist/formatters/ide/cursor.js +0 -125
  833. package/dist/formatters/ide/cursor.js.map +0 -1
  834. package/dist/formatters/ide/index.d.ts +0 -62
  835. package/dist/formatters/ide/index.d.ts.map +0 -1
  836. package/dist/formatters/ide/index.js +0 -184
  837. package/dist/formatters/ide/index.js.map +0 -1
  838. package/dist/formatters/ide/windsurf.d.ts +0 -13
  839. package/dist/formatters/ide/windsurf.d.ts.map +0 -1
  840. package/dist/formatters/ide/windsurf.js +0 -117
  841. package/dist/formatters/ide/windsurf.js.map +0 -1
  842. package/dist/formatters/index.d.ts +0 -11
  843. package/dist/formatters/index.d.ts.map +0 -1
  844. package/dist/formatters/index.js +0 -54
  845. package/dist/formatters/index.js.map +0 -1
  846. package/dist/formatters/vscode-diagnostic.d.ts +0 -103
  847. package/dist/formatters/vscode-diagnostic.d.ts.map +0 -1
  848. package/dist/formatters/vscode-diagnostic.js +0 -151
  849. package/dist/formatters/vscode-diagnostic.js.map +0 -1
  850. package/dist/layer1/comments.d.ts +0 -11
  851. package/dist/layer1/comments.d.ts.map +0 -1
  852. package/dist/layer1/comments.js +0 -203
  853. package/dist/layer1/comments.js.map +0 -1
  854. package/dist/layer1/config-audit.d.ts +0 -11
  855. package/dist/layer1/config-audit.d.ts.map +0 -1
  856. package/dist/layer1/config-audit.js +0 -311
  857. package/dist/layer1/config-audit.js.map +0 -1
  858. package/dist/layer1/config-mcp-audit.d.ts +0 -23
  859. package/dist/layer1/config-mcp-audit.d.ts.map +0 -1
  860. package/dist/layer1/config-mcp-audit.js +0 -239
  861. package/dist/layer1/config-mcp-audit.js.map +0 -1
  862. package/dist/layer1/entropy.d.ts +0 -11
  863. package/dist/layer1/entropy.d.ts.map +0 -1
  864. package/dist/layer1/entropy.js +0 -741
  865. package/dist/layer1/entropy.js.map +0 -1
  866. package/dist/layer1/file-flags.d.ts +0 -10
  867. package/dist/layer1/file-flags.d.ts.map +0 -1
  868. package/dist/layer1/file-flags.js +0 -119
  869. package/dist/layer1/file-flags.js.map +0 -1
  870. package/dist/layer1/index.d.ts +0 -38
  871. package/dist/layer1/index.d.ts.map +0 -1
  872. package/dist/layer1/index.js +0 -170
  873. package/dist/layer1/index.js.map +0 -1
  874. package/dist/layer1/patterns.d.ts +0 -11
  875. package/dist/layer1/patterns.d.ts.map +0 -1
  876. package/dist/layer1/patterns.js +0 -512
  877. package/dist/layer1/patterns.js.map +0 -1
  878. package/dist/layer1/urls.d.ts +0 -11
  879. package/dist/layer1/urls.d.ts.map +0 -1
  880. package/dist/layer1/urls.js +0 -444
  881. package/dist/layer1/urls.js.map +0 -1
  882. package/dist/layer1/weak-crypto.d.ts +0 -10
  883. package/dist/layer1/weak-crypto.d.ts.map +0 -1
  884. package/dist/layer1/weak-crypto.js +0 -428
  885. package/dist/layer1/weak-crypto.js.map +0 -1
  886. package/dist/layer2/ai-agent-tools.d.ts +0 -22
  887. package/dist/layer2/ai-agent-tools.d.ts.map +0 -1
  888. package/dist/layer2/ai-agent-tools.js +0 -1490
  889. package/dist/layer2/ai-agent-tools.js.map +0 -1
  890. package/dist/layer2/ai-endpoint-protection.d.ts +0 -38
  891. package/dist/layer2/ai-endpoint-protection.d.ts.map +0 -1
  892. package/dist/layer2/ai-endpoint-protection.js +0 -346
  893. package/dist/layer2/ai-endpoint-protection.js.map +0 -1
  894. package/dist/layer2/ai-execution-sinks.d.ts +0 -21
  895. package/dist/layer2/ai-execution-sinks.d.ts.map +0 -1
  896. package/dist/layer2/ai-execution-sinks.js +0 -1155
  897. package/dist/layer2/ai-execution-sinks.js.map +0 -1
  898. package/dist/layer2/ai-fingerprinting.d.ts +0 -10
  899. package/dist/layer2/ai-fingerprinting.d.ts.map +0 -1
  900. package/dist/layer2/ai-fingerprinting.js +0 -650
  901. package/dist/layer2/ai-fingerprinting.js.map +0 -1
  902. package/dist/layer2/ai-mcp-security.d.ts +0 -20
  903. package/dist/layer2/ai-mcp-security.d.ts.map +0 -1
  904. package/dist/layer2/ai-mcp-security.js +0 -877
  905. package/dist/layer2/ai-mcp-security.js.map +0 -1
  906. package/dist/layer2/ai-package-hallucination.d.ts +0 -22
  907. package/dist/layer2/ai-package-hallucination.d.ts.map +0 -1
  908. package/dist/layer2/ai-package-hallucination.js +0 -828
  909. package/dist/layer2/ai-package-hallucination.js.map +0 -1
  910. package/dist/layer2/ai-prompt-hygiene.d.ts +0 -22
  911. package/dist/layer2/ai-prompt-hygiene.d.ts.map +0 -1
  912. package/dist/layer2/ai-prompt-hygiene.js +0 -1156
  913. package/dist/layer2/ai-prompt-hygiene.js.map +0 -1
  914. package/dist/layer2/ai-rag-safety.d.ts +0 -24
  915. package/dist/layer2/ai-rag-safety.d.ts.map +0 -1
  916. package/dist/layer2/ai-rag-safety.js +0 -910
  917. package/dist/layer2/ai-rag-safety.js.map +0 -1
  918. package/dist/layer2/ai-schema-validation.d.ts +0 -28
  919. package/dist/layer2/ai-schema-validation.d.ts.map +0 -1
  920. package/dist/layer2/ai-schema-validation.js +0 -375
  921. package/dist/layer2/ai-schema-validation.js.map +0 -1
  922. package/dist/layer2/auth-antipatterns.d.ts +0 -22
  923. package/dist/layer2/auth-antipatterns.d.ts.map +0 -1
  924. package/dist/layer2/auth-antipatterns.js +0 -522
  925. package/dist/layer2/auth-antipatterns.js.map +0 -1
  926. package/dist/layer2/byok-patterns.d.ts +0 -15
  927. package/dist/layer2/byok-patterns.d.ts.map +0 -1
  928. package/dist/layer2/byok-patterns.js +0 -302
  929. package/dist/layer2/byok-patterns.js.map +0 -1
  930. package/dist/layer2/dangerous-functions/child-process.d.ts +0 -16
  931. package/dist/layer2/dangerous-functions/child-process.d.ts.map +0 -1
  932. package/dist/layer2/dangerous-functions/child-process.js +0 -74
  933. package/dist/layer2/dangerous-functions/child-process.js.map +0 -1
  934. package/dist/layer2/dangerous-functions/dom-xss.d.ts +0 -34
  935. package/dist/layer2/dangerous-functions/dom-xss.d.ts.map +0 -1
  936. package/dist/layer2/dangerous-functions/dom-xss.js +0 -230
  937. package/dist/layer2/dangerous-functions/dom-xss.js.map +0 -1
  938. package/dist/layer2/dangerous-functions/index.d.ts +0 -16
  939. package/dist/layer2/dangerous-functions/index.d.ts.map +0 -1
  940. package/dist/layer2/dangerous-functions/index.js +0 -1152
  941. package/dist/layer2/dangerous-functions/index.js.map +0 -1
  942. package/dist/layer2/dangerous-functions/json-parse.d.ts +0 -31
  943. package/dist/layer2/dangerous-functions/json-parse.d.ts.map +0 -1
  944. package/dist/layer2/dangerous-functions/json-parse.js +0 -319
  945. package/dist/layer2/dangerous-functions/json-parse.js.map +0 -1
  946. package/dist/layer2/dangerous-functions/math-random.d.ts +0 -111
  947. package/dist/layer2/dangerous-functions/math-random.d.ts.map +0 -1
  948. package/dist/layer2/dangerous-functions/math-random.js +0 -684
  949. package/dist/layer2/dangerous-functions/math-random.js.map +0 -1
  950. package/dist/layer2/dangerous-functions/patterns.d.ts +0 -21
  951. package/dist/layer2/dangerous-functions/patterns.d.ts.map +0 -1
  952. package/dist/layer2/dangerous-functions/patterns.js +0 -163
  953. package/dist/layer2/dangerous-functions/patterns.js.map +0 -1
  954. package/dist/layer2/dangerous-functions/request-validation.d.ts +0 -13
  955. package/dist/layer2/dangerous-functions/request-validation.d.ts.map +0 -1
  956. package/dist/layer2/dangerous-functions/request-validation.js +0 -119
  957. package/dist/layer2/dangerous-functions/request-validation.js.map +0 -1
  958. package/dist/layer2/dangerous-functions/utils/control-flow.d.ts +0 -24
  959. package/dist/layer2/dangerous-functions/utils/control-flow.d.ts.map +0 -1
  960. package/dist/layer2/dangerous-functions/utils/control-flow.js +0 -70
  961. package/dist/layer2/dangerous-functions/utils/control-flow.js.map +0 -1
  962. package/dist/layer2/dangerous-functions/utils/helpers.d.ts +0 -31
  963. package/dist/layer2/dangerous-functions/utils/helpers.d.ts.map +0 -1
  964. package/dist/layer2/dangerous-functions/utils/helpers.js +0 -147
  965. package/dist/layer2/dangerous-functions/utils/helpers.js.map +0 -1
  966. package/dist/layer2/dangerous-functions/utils/index.d.ts +0 -9
  967. package/dist/layer2/dangerous-functions/utils/index.d.ts.map +0 -1
  968. package/dist/layer2/dangerous-functions/utils/index.js +0 -23
  969. package/dist/layer2/dangerous-functions/utils/index.js.map +0 -1
  970. package/dist/layer2/dangerous-functions/utils/schema-validation.d.ts +0 -22
  971. package/dist/layer2/dangerous-functions/utils/schema-validation.d.ts.map +0 -1
  972. package/dist/layer2/dangerous-functions/utils/schema-validation.js +0 -102
  973. package/dist/layer2/dangerous-functions/utils/schema-validation.js.map +0 -1
  974. package/dist/layer2/data-exposure.d.ts +0 -19
  975. package/dist/layer2/data-exposure.d.ts.map +0 -1
  976. package/dist/layer2/data-exposure.js +0 -255
  977. package/dist/layer2/data-exposure.js.map +0 -1
  978. package/dist/layer2/framework-checks.d.ts +0 -10
  979. package/dist/layer2/framework-checks.d.ts.map +0 -1
  980. package/dist/layer2/framework-checks.js +0 -384
  981. package/dist/layer2/framework-checks.js.map +0 -1
  982. package/dist/layer2/index.d.ts +0 -74
  983. package/dist/layer2/index.d.ts.map +0 -1
  984. package/dist/layer2/index.js +0 -544
  985. package/dist/layer2/index.js.map +0 -1
  986. package/dist/layer2/log-injection.d.ts +0 -18
  987. package/dist/layer2/log-injection.d.ts.map +0 -1
  988. package/dist/layer2/log-injection.js +0 -214
  989. package/dist/layer2/log-injection.js.map +0 -1
  990. package/dist/layer2/logic-gates.d.ts +0 -10
  991. package/dist/layer2/logic-gates.d.ts.map +0 -1
  992. package/dist/layer2/logic-gates.js +0 -220
  993. package/dist/layer2/logic-gates.js.map +0 -1
  994. package/dist/layer2/model-supply-chain.d.ts +0 -23
  995. package/dist/layer2/model-supply-chain.d.ts.map +0 -1
  996. package/dist/layer2/model-supply-chain.js +0 -444
  997. package/dist/layer2/model-supply-chain.js.map +0 -1
  998. package/dist/layer2/risky-imports.d.ts +0 -10
  999. package/dist/layer2/risky-imports.d.ts.map +0 -1
  1000. package/dist/layer2/risky-imports.js +0 -165
  1001. package/dist/layer2/risky-imports.js.map +0 -1
  1002. package/dist/layer2/security-headers.d.ts +0 -18
  1003. package/dist/layer2/security-headers.d.ts.map +0 -1
  1004. package/dist/layer2/security-headers.js +0 -187
  1005. package/dist/layer2/security-headers.js.map +0 -1
  1006. package/dist/layer2/ssrf-detection.d.ts +0 -18
  1007. package/dist/layer2/ssrf-detection.d.ts.map +0 -1
  1008. package/dist/layer2/ssrf-detection.js +0 -252
  1009. package/dist/layer2/ssrf-detection.js.map +0 -1
  1010. package/dist/layer2/variables.d.ts +0 -11
  1011. package/dist/layer2/variables.d.ts.map +0 -1
  1012. package/dist/layer2/variables.js +0 -156
  1013. package/dist/layer2/variables.js.map +0 -1
  1014. package/dist/layer2/xxe-detection.d.ts +0 -18
  1015. package/dist/layer2/xxe-detection.d.ts.map +0 -1
  1016. package/dist/layer2/xxe-detection.js +0 -242
  1017. package/dist/layer2/xxe-detection.js.map +0 -1
  1018. package/dist/layer3/anthropic/auto-dismiss.d.ts +0 -24
  1019. package/dist/layer3/anthropic/auto-dismiss.d.ts.map +0 -1
  1020. package/dist/layer3/anthropic/auto-dismiss.js +0 -199
  1021. package/dist/layer3/anthropic/auto-dismiss.js.map +0 -1
  1022. package/dist/layer3/anthropic/clients.d.ts +0 -44
  1023. package/dist/layer3/anthropic/clients.d.ts.map +0 -1
  1024. package/dist/layer3/anthropic/clients.js +0 -81
  1025. package/dist/layer3/anthropic/clients.js.map +0 -1
  1026. package/dist/layer3/anthropic/index.d.ts +0 -41
  1027. package/dist/layer3/anthropic/index.d.ts.map +0 -1
  1028. package/dist/layer3/anthropic/index.js +0 -141
  1029. package/dist/layer3/anthropic/index.js.map +0 -1
  1030. package/dist/layer3/anthropic/prompts/index.d.ts +0 -8
  1031. package/dist/layer3/anthropic/prompts/index.d.ts.map +0 -1
  1032. package/dist/layer3/anthropic/prompts/index.js +0 -16
  1033. package/dist/layer3/anthropic/prompts/index.js.map +0 -1
  1034. package/dist/layer3/anthropic/prompts/modules/ai-patterns.d.ts +0 -19
  1035. package/dist/layer3/anthropic/prompts/modules/ai-patterns.d.ts.map +0 -1
  1036. package/dist/layer3/anthropic/prompts/modules/ai-patterns.js +0 -156
  1037. package/dist/layer3/anthropic/prompts/modules/ai-patterns.js.map +0 -1
  1038. package/dist/layer3/anthropic/prompts/modules/auth-access.d.ts +0 -9
  1039. package/dist/layer3/anthropic/prompts/modules/auth-access.d.ts.map +0 -1
  1040. package/dist/layer3/anthropic/prompts/modules/auth-access.js +0 -25
  1041. package/dist/layer3/anthropic/prompts/modules/auth-access.js.map +0 -1
  1042. package/dist/layer3/anthropic/prompts/modules/common.d.ts +0 -11
  1043. package/dist/layer3/anthropic/prompts/modules/common.d.ts.map +0 -1
  1044. package/dist/layer3/anthropic/prompts/modules/common.js +0 -152
  1045. package/dist/layer3/anthropic/prompts/modules/common.js.map +0 -1
  1046. package/dist/layer3/anthropic/prompts/modules/index.d.ts +0 -54
  1047. package/dist/layer3/anthropic/prompts/modules/index.d.ts.map +0 -1
  1048. package/dist/layer3/anthropic/prompts/modules/index.js +0 -185
  1049. package/dist/layer3/anthropic/prompts/modules/index.js.map +0 -1
  1050. package/dist/layer3/anthropic/prompts/modules/owasp-classic.d.ts +0 -8
  1051. package/dist/layer3/anthropic/prompts/modules/owasp-classic.d.ts.map +0 -1
  1052. package/dist/layer3/anthropic/prompts/modules/owasp-classic.js +0 -84
  1053. package/dist/layer3/anthropic/prompts/modules/owasp-classic.js.map +0 -1
  1054. package/dist/layer3/anthropic/prompts/modules/secrets-crypto.d.ts +0 -8
  1055. package/dist/layer3/anthropic/prompts/modules/secrets-crypto.d.ts.map +0 -1
  1056. package/dist/layer3/anthropic/prompts/modules/secrets-crypto.js +0 -68
  1057. package/dist/layer3/anthropic/prompts/modules/secrets-crypto.js.map +0 -1
  1058. package/dist/layer3/anthropic/prompts/modules/xss-prompt.d.ts +0 -8
  1059. package/dist/layer3/anthropic/prompts/modules/xss-prompt.d.ts.map +0 -1
  1060. package/dist/layer3/anthropic/prompts/modules/xss-prompt.js +0 -22
  1061. package/dist/layer3/anthropic/prompts/modules/xss-prompt.js.map +0 -1
  1062. package/dist/layer3/anthropic/prompts/semantic-analysis.d.ts +0 -15
  1063. package/dist/layer3/anthropic/prompts/semantic-analysis.d.ts.map +0 -1
  1064. package/dist/layer3/anthropic/prompts/semantic-analysis.js +0 -169
  1065. package/dist/layer3/anthropic/prompts/semantic-analysis.js.map +0 -1
  1066. package/dist/layer3/anthropic/prompts/validation.d.ts +0 -18
  1067. package/dist/layer3/anthropic/prompts/validation.d.ts.map +0 -1
  1068. package/dist/layer3/anthropic/prompts/validation.js +0 -25
  1069. package/dist/layer3/anthropic/prompts/validation.js.map +0 -1
  1070. package/dist/layer3/anthropic/providers/anthropic.d.ts +0 -21
  1071. package/dist/layer3/anthropic/providers/anthropic.d.ts.map +0 -1
  1072. package/dist/layer3/anthropic/providers/anthropic.js +0 -269
  1073. package/dist/layer3/anthropic/providers/anthropic.js.map +0 -1
  1074. package/dist/layer3/anthropic/providers/index.d.ts +0 -8
  1075. package/dist/layer3/anthropic/providers/index.d.ts.map +0 -1
  1076. package/dist/layer3/anthropic/providers/index.js +0 -15
  1077. package/dist/layer3/anthropic/providers/index.js.map +0 -1
  1078. package/dist/layer3/anthropic/providers/openai.d.ts +0 -18
  1079. package/dist/layer3/anthropic/providers/openai.d.ts.map +0 -1
  1080. package/dist/layer3/anthropic/providers/openai.js +0 -343
  1081. package/dist/layer3/anthropic/providers/openai.js.map +0 -1
  1082. package/dist/layer3/anthropic/request-builder.d.ts +0 -27
  1083. package/dist/layer3/anthropic/request-builder.d.ts.map +0 -1
  1084. package/dist/layer3/anthropic/request-builder.js +0 -150
  1085. package/dist/layer3/anthropic/request-builder.js.map +0 -1
  1086. package/dist/layer3/anthropic/types.d.ts +0 -88
  1087. package/dist/layer3/anthropic/types.d.ts.map +0 -1
  1088. package/dist/layer3/anthropic/types.js +0 -38
  1089. package/dist/layer3/anthropic/types.js.map +0 -1
  1090. package/dist/layer3/anthropic/utils/context-extractor.d.ts +0 -55
  1091. package/dist/layer3/anthropic/utils/context-extractor.d.ts.map +0 -1
  1092. package/dist/layer3/anthropic/utils/context-extractor.js +0 -161
  1093. package/dist/layer3/anthropic/utils/context-extractor.js.map +0 -1
  1094. package/dist/layer3/anthropic/utils/index.d.ts +0 -11
  1095. package/dist/layer3/anthropic/utils/index.d.ts.map +0 -1
  1096. package/dist/layer3/anthropic/utils/index.js +0 -27
  1097. package/dist/layer3/anthropic/utils/index.js.map +0 -1
  1098. package/dist/layer3/anthropic/utils/path-helpers.d.ts +0 -21
  1099. package/dist/layer3/anthropic/utils/path-helpers.d.ts.map +0 -1
  1100. package/dist/layer3/anthropic/utils/path-helpers.js +0 -69
  1101. package/dist/layer3/anthropic/utils/path-helpers.js.map +0 -1
  1102. package/dist/layer3/anthropic/utils/response-parser.d.ts +0 -40
  1103. package/dist/layer3/anthropic/utils/response-parser.d.ts.map +0 -1
  1104. package/dist/layer3/anthropic/utils/response-parser.js +0 -285
  1105. package/dist/layer3/anthropic/utils/response-parser.js.map +0 -1
  1106. package/dist/layer3/anthropic/utils/retry.d.ts +0 -15
  1107. package/dist/layer3/anthropic/utils/retry.d.ts.map +0 -1
  1108. package/dist/layer3/anthropic/utils/retry.js +0 -62
  1109. package/dist/layer3/anthropic/utils/retry.js.map +0 -1
  1110. package/dist/layer3/index.d.ts +0 -27
  1111. package/dist/layer3/index.d.ts.map +0 -1
  1112. package/dist/layer3/index.js +0 -150
  1113. package/dist/layer3/index.js.map +0 -1
  1114. package/dist/layer3/osv-check.d.ts +0 -75
  1115. package/dist/layer3/osv-check.d.ts.map +0 -1
  1116. package/dist/layer3/osv-check.js +0 -308
  1117. package/dist/layer3/osv-check.js.map +0 -1
  1118. package/dist/layer3/package-check.d.ts +0 -63
  1119. package/dist/layer3/package-check.d.ts.map +0 -1
  1120. package/dist/layer3/package-check.js +0 -508
  1121. package/dist/layer3/package-check.js.map +0 -1
  1122. package/dist/model/cross-file-taint.d.ts +0 -40
  1123. package/dist/model/cross-file-taint.d.ts.map +0 -1
  1124. package/dist/model/cross-file-taint.js +0 -290
  1125. package/dist/model/cross-file-taint.js.map +0 -1
  1126. package/dist/model/function-classifier.d.ts +0 -32
  1127. package/dist/model/function-classifier.d.ts.map +0 -1
  1128. package/dist/model/function-classifier.js +0 -143
  1129. package/dist/model/function-classifier.js.map +0 -1
  1130. package/dist/model/sanitiser-detection.d.ts +0 -27
  1131. package/dist/model/sanitiser-detection.d.ts.map +0 -1
  1132. package/dist/model/sanitiser-detection.js +0 -224
  1133. package/dist/model/sanitiser-detection.js.map +0 -1
  1134. package/dist/model/sink-matcher.d.ts +0 -17
  1135. package/dist/model/sink-matcher.d.ts.map +0 -1
  1136. package/dist/model/sink-matcher.js +0 -141
  1137. package/dist/model/sink-matcher.js.map +0 -1
  1138. package/dist/model/sink-patterns.d.ts +0 -19
  1139. package/dist/model/sink-patterns.d.ts.map +0 -1
  1140. package/dist/model/sink-patterns.js +0 -88
  1141. package/dist/model/sink-patterns.js.map +0 -1
  1142. package/dist/model/source-discovery.d.ts +0 -15
  1143. package/dist/model/source-discovery.d.ts.map +0 -1
  1144. package/dist/model/source-discovery.js +0 -170
  1145. package/dist/model/source-discovery.js.map +0 -1
  1146. package/dist/model/taint-tracker.d.ts +0 -21
  1147. package/dist/model/taint-tracker.d.ts.map +0 -1
  1148. package/dist/model/taint-tracker.js +0 -281
  1149. package/dist/model/taint-tracker.js.map +0 -1
  1150. package/dist/modes/incremental.d.ts +0 -66
  1151. package/dist/modes/incremental.d.ts.map +0 -1
  1152. package/dist/modes/incremental.js +0 -200
  1153. package/dist/modes/incremental.js.map +0 -1
  1154. package/dist/rules/framework-fixes.d.ts +0 -48
  1155. package/dist/rules/framework-fixes.d.ts.map +0 -1
  1156. package/dist/rules/framework-fixes.js +0 -439
  1157. package/dist/rules/framework-fixes.js.map +0 -1
  1158. package/dist/rules/index.d.ts +0 -8
  1159. package/dist/rules/index.d.ts.map +0 -1
  1160. package/dist/rules/index.js +0 -18
  1161. package/dist/rules/index.js.map +0 -1
  1162. package/dist/rules/metadata.d.ts +0 -43
  1163. package/dist/rules/metadata.d.ts.map +0 -1
  1164. package/dist/rules/metadata.js +0 -800
  1165. package/dist/rules/metadata.js.map +0 -1
  1166. package/dist/score/auto-dismiss.d.ts +0 -28
  1167. package/dist/score/auto-dismiss.d.ts.map +0 -1
  1168. package/dist/score/auto-dismiss.js +0 -200
  1169. package/dist/score/auto-dismiss.js.map +0 -1
  1170. package/dist/suppression/config-loader.d.ts +0 -74
  1171. package/dist/suppression/config-loader.d.ts.map +0 -1
  1172. package/dist/suppression/config-loader.js +0 -424
  1173. package/dist/suppression/config-loader.js.map +0 -1
  1174. package/dist/suppression/hash.d.ts +0 -48
  1175. package/dist/suppression/hash.d.ts.map +0 -1
  1176. package/dist/suppression/hash.js +0 -88
  1177. package/dist/suppression/hash.js.map +0 -1
  1178. package/dist/suppression/index.d.ts +0 -11
  1179. package/dist/suppression/index.d.ts.map +0 -1
  1180. package/dist/suppression/index.js +0 -39
  1181. package/dist/suppression/index.js.map +0 -1
  1182. package/dist/suppression/inline-parser.d.ts +0 -39
  1183. package/dist/suppression/inline-parser.d.ts.map +0 -1
  1184. package/dist/suppression/inline-parser.js +0 -218
  1185. package/dist/suppression/inline-parser.js.map +0 -1
  1186. package/dist/suppression/manager.d.ts +0 -94
  1187. package/dist/suppression/manager.d.ts.map +0 -1
  1188. package/dist/suppression/manager.js +0 -292
  1189. package/dist/suppression/manager.js.map +0 -1
  1190. package/dist/suppression/types.d.ts +0 -151
  1191. package/dist/suppression/types.d.ts.map +0 -1
  1192. package/dist/suppression/types.js +0 -28
  1193. package/dist/suppression/types.js.map +0 -1
  1194. package/dist/types.d.ts +0 -331
  1195. package/dist/types.d.ts.map +0 -1
  1196. package/dist/types.js +0 -124
  1197. package/dist/types.js.map +0 -1
  1198. package/dist/utils/auth-helper-detector.d.ts +0 -56
  1199. package/dist/utils/auth-helper-detector.d.ts.map +0 -1
  1200. package/dist/utils/auth-helper-detector.js +0 -360
  1201. package/dist/utils/auth-helper-detector.js.map +0 -1
  1202. package/dist/utils/code-analysis.d.ts +0 -39
  1203. package/dist/utils/code-analysis.d.ts.map +0 -1
  1204. package/dist/utils/code-analysis.js +0 -159
  1205. package/dist/utils/code-analysis.js.map +0 -1
  1206. package/dist/utils/comment-analyzer.d.ts +0 -38
  1207. package/dist/utils/comment-analyzer.d.ts.map +0 -1
  1208. package/dist/utils/comment-analyzer.js +0 -218
  1209. package/dist/utils/comment-analyzer.js.map +0 -1
  1210. package/dist/utils/context-helpers.d.ts +0 -219
  1211. package/dist/utils/context-helpers.d.ts.map +0 -1
  1212. package/dist/utils/context-helpers.js +0 -886
  1213. package/dist/utils/context-helpers.js.map +0 -1
  1214. package/dist/utils/diff-detector.d.ts +0 -53
  1215. package/dist/utils/diff-detector.d.ts.map +0 -1
  1216. package/dist/utils/diff-detector.js +0 -104
  1217. package/dist/utils/diff-detector.js.map +0 -1
  1218. package/dist/utils/diff-parser.d.ts +0 -80
  1219. package/dist/utils/diff-parser.d.ts.map +0 -1
  1220. package/dist/utils/diff-parser.js +0 -202
  1221. package/dist/utils/diff-parser.js.map +0 -1
  1222. package/dist/utils/environment-context.d.ts +0 -76
  1223. package/dist/utils/environment-context.d.ts.map +0 -1
  1224. package/dist/utils/environment-context.js +0 -271
  1225. package/dist/utils/environment-context.js.map +0 -1
  1226. package/dist/utils/imported-auth-detector.d.ts +0 -37
  1227. package/dist/utils/imported-auth-detector.d.ts.map +0 -1
  1228. package/dist/utils/imported-auth-detector.js +0 -251
  1229. package/dist/utils/imported-auth-detector.js.map +0 -1
  1230. package/dist/utils/intent-detector.d.ts +0 -66
  1231. package/dist/utils/intent-detector.d.ts.map +0 -1
  1232. package/dist/utils/intent-detector.js +0 -282
  1233. package/dist/utils/intent-detector.js.map +0 -1
  1234. package/dist/utils/middleware-detector.d.ts +0 -55
  1235. package/dist/utils/middleware-detector.d.ts.map +0 -1
  1236. package/dist/utils/middleware-detector.js +0 -260
  1237. package/dist/utils/middleware-detector.js.map +0 -1
  1238. package/dist/utils/oauth-flow-detector.d.ts +0 -41
  1239. package/dist/utils/oauth-flow-detector.d.ts.map +0 -1
  1240. package/dist/utils/oauth-flow-detector.js +0 -202
  1241. package/dist/utils/oauth-flow-detector.js.map +0 -1
  1242. package/dist/utils/parsed-file.d.ts +0 -51
  1243. package/dist/utils/parsed-file.d.ts.map +0 -1
  1244. package/dist/utils/parsed-file.js +0 -95
  1245. package/dist/utils/parsed-file.js.map +0 -1
  1246. package/dist/utils/path-exclusions.d.ts +0 -55
  1247. package/dist/utils/path-exclusions.d.ts.map +0 -1
  1248. package/dist/utils/path-exclusions.js +0 -224
  1249. package/dist/utils/path-exclusions.js.map +0 -1
  1250. package/dist/utils/project-context-builder.d.ts +0 -119
  1251. package/dist/utils/project-context-builder.d.ts.map +0 -1
  1252. package/dist/utils/project-context-builder.js +0 -534
  1253. package/dist/utils/project-context-builder.js.map +0 -1
  1254. package/dist/utils/registry-clients.d.ts +0 -93
  1255. package/dist/utils/registry-clients.d.ts.map +0 -1
  1256. package/dist/utils/registry-clients.js +0 -273
  1257. package/dist/utils/registry-clients.js.map +0 -1
  1258. package/dist/utils/route-hierarchy.d.ts +0 -50
  1259. package/dist/utils/route-hierarchy.d.ts.map +0 -1
  1260. package/dist/utils/route-hierarchy.js +0 -226
  1261. package/dist/utils/route-hierarchy.js.map +0 -1
  1262. package/dist/utils/schema-semantics.d.ts +0 -45
  1263. package/dist/utils/schema-semantics.d.ts.map +0 -1
  1264. package/dist/utils/schema-semantics.js +0 -193
  1265. package/dist/utils/schema-semantics.js.map +0 -1
  1266. package/dist/utils/trpc-analyzer.d.ts +0 -78
  1267. package/dist/utils/trpc-analyzer.d.ts.map +0 -1
  1268. package/dist/utils/trpc-analyzer.js +0 -297
  1269. package/dist/utils/trpc-analyzer.js.map +0 -1
  1270. package/src/__tests__/context-engine/cross-file-taint.test.ts +0 -284
  1271. package/src/__tests__/context-engine/function-classifier.test.ts +0 -146
  1272. package/src/__tests__/context-engine/integration.test.ts +0 -320
  1273. package/src/__tests__/context-engine/sanitiser-detection.test.ts +0 -187
  1274. package/src/__tests__/context-engine/sink-matcher.test.ts +0 -251
  1275. package/src/__tests__/context-engine/source-discovery.test.ts +0 -186
  1276. package/src/__tests__/context-engine/taint-tracker.test.ts +0 -182
  1277. package/src/__tests__/snapshots/__snapshots__/anthropic-validation-refactor.test.ts.snap +0 -750
  1278. package/src/__tests__/snapshots/__snapshots__/dangerous-functions-refactor.test.ts.snap +0 -555
  1279. package/src/__tests__/snapshots/anthropic-validation-refactor.test.ts +0 -321
  1280. package/src/__tests__/snapshots/dangerous-functions-refactor.test.ts +0 -439
  1281. package/src/detect/ai-code/agent-tools.ts +0 -1662
  1282. package/src/detect/ai-code/byok-patterns.ts +0 -354
  1283. package/src/detect/ai-code/endpoint-protection.ts +0 -406
  1284. package/src/detect/ai-code/execution-sinks.ts +0 -1310
  1285. package/src/detect/ai-code/fingerprinting.ts +0 -774
  1286. package/src/detect/ai-code/mcp-security.ts +0 -937
  1287. package/src/detect/ai-code/model-supply-chain.ts +0 -535
  1288. package/src/detect/ai-code/package-hallucination.ts +0 -955
  1289. package/src/detect/ai-code/prompt-hygiene.ts +0 -1314
  1290. package/src/detect/ai-code/rag-safety.ts +0 -977
  1291. package/src/detect/ai-code/schema-validation.ts +0 -427
  1292. package/src/detect/secrets/patterns.ts +0 -561
  1293. package/src/detect/secrets/weak-crypto.ts +0 -485
  1294. package/src/detect/structural/__tests__/math-random-enhanced.test.ts +0 -405
  1295. package/src/detect/structural/auth-patterns.ts +0 -621
  1296. package/src/detect/structural/dangerous-functions/child-process.ts +0 -98
  1297. package/src/detect/structural/dangerous-functions/dom-xss.ts +0 -292
  1298. package/src/detect/structural/dangerous-functions/index.ts +0 -1556
  1299. package/src/detect/structural/dangerous-functions/json-parse.ts +0 -393
  1300. package/src/detect/structural/dangerous-functions/math-random.ts +0 -789
  1301. package/src/detect/structural/dangerous-functions/patterns.ts +0 -176
  1302. package/src/detect/structural/dangerous-functions/request-validation.ts +0 -153
  1303. package/src/detect/structural/dangerous-functions/utils/control-flow.ts +0 -35
  1304. package/src/detect/structural/dangerous-functions/utils/helpers.ts +0 -170
  1305. package/src/detect/structural/dangerous-functions/utils/index.ts +0 -25
  1306. package/src/detect/structural/dangerous-functions/utils/schema-validation.ts +0 -106
  1307. package/src/detect/structural/data-exposure.ts +0 -302
  1308. package/src/detect/structural/framework-checks.ts +0 -439
  1309. package/src/detect/structural/log-injection.ts +0 -254
  1310. package/src/detect/structural/logic-gates.ts +0 -256
  1311. package/src/detect/structural/risky-imports.ts +0 -197
  1312. package/src/detect/structural/security-headers.ts +0 -231
  1313. package/src/detect/structural/ssrf-detection.ts +0 -300
  1314. package/src/detect/structural/variables.ts +0 -177
  1315. package/src/detect/structural/xxe-detection.ts +0 -295
  1316. package/src/model/cross-file-taint.ts +0 -374
  1317. package/src/model/function-classifier.ts +0 -184
  1318. package/src/model/sanitiser-detection.ts +0 -268
  1319. package/src/model/sink-matcher.ts +0 -178
  1320. package/src/model/sink-patterns.ts +0 -109
  1321. package/src/model/source-discovery.ts +0 -209
  1322. package/src/model/taint-tracker.ts +0 -333
  1323. 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