@oculum/scanner 1.0.12 → 1.0.13

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 (961) hide show
  1. package/dist/detect/ai-code/agent-tools.d.ts +22 -0
  2. package/dist/detect/ai-code/agent-tools.d.ts.map +1 -0
  3. package/dist/detect/ai-code/agent-tools.js +1509 -0
  4. package/dist/detect/ai-code/agent-tools.js.map +1 -0
  5. package/dist/detect/ai-code/byok-patterns.d.ts +15 -0
  6. package/dist/detect/ai-code/byok-patterns.d.ts.map +1 -0
  7. package/dist/detect/ai-code/byok-patterns.js +313 -0
  8. package/dist/detect/ai-code/byok-patterns.js.map +1 -0
  9. package/dist/detect/ai-code/endpoint-protection.d.ts +38 -0
  10. package/dist/detect/ai-code/endpoint-protection.d.ts.map +1 -0
  11. package/dist/detect/ai-code/endpoint-protection.js +349 -0
  12. package/dist/detect/ai-code/endpoint-protection.js.map +1 -0
  13. package/dist/detect/ai-code/execution-sinks.d.ts +21 -0
  14. package/dist/detect/ai-code/execution-sinks.d.ts.map +1 -0
  15. package/dist/detect/ai-code/execution-sinks.js +1158 -0
  16. package/dist/detect/ai-code/execution-sinks.js.map +1 -0
  17. package/dist/detect/ai-code/fingerprinting.d.ts +10 -0
  18. package/dist/detect/ai-code/fingerprinting.d.ts.map +1 -0
  19. package/dist/detect/ai-code/fingerprinting.js +665 -0
  20. package/dist/detect/ai-code/fingerprinting.js.map +1 -0
  21. package/dist/detect/ai-code/index.d.ts +12 -0
  22. package/dist/detect/ai-code/index.d.ts.map +1 -0
  23. package/dist/detect/ai-code/index.js +26 -0
  24. package/dist/detect/ai-code/index.js.map +1 -0
  25. package/dist/detect/ai-code/mcp-security.d.ts +20 -0
  26. package/dist/detect/ai-code/mcp-security.d.ts.map +1 -0
  27. package/dist/detect/ai-code/mcp-security.js +880 -0
  28. package/dist/detect/ai-code/mcp-security.js.map +1 -0
  29. package/dist/detect/ai-code/model-supply-chain.d.ts +23 -0
  30. package/dist/detect/ai-code/model-supply-chain.d.ts.map +1 -0
  31. package/dist/detect/ai-code/model-supply-chain.js +447 -0
  32. package/dist/detect/ai-code/model-supply-chain.js.map +1 -0
  33. package/dist/detect/ai-code/package-hallucination.d.ts +22 -0
  34. package/dist/detect/ai-code/package-hallucination.d.ts.map +1 -0
  35. package/dist/detect/ai-code/package-hallucination.js +841 -0
  36. package/dist/detect/ai-code/package-hallucination.js.map +1 -0
  37. package/dist/detect/ai-code/prompt-hygiene.d.ts +22 -0
  38. package/dist/detect/ai-code/prompt-hygiene.d.ts.map +1 -0
  39. package/dist/detect/ai-code/prompt-hygiene.js +1177 -0
  40. package/dist/detect/ai-code/prompt-hygiene.js.map +1 -0
  41. package/dist/detect/ai-code/rag-safety.d.ts +24 -0
  42. package/dist/detect/ai-code/rag-safety.d.ts.map +1 -0
  43. package/dist/detect/ai-code/rag-safety.js +913 -0
  44. package/dist/detect/ai-code/rag-safety.js.map +1 -0
  45. package/dist/detect/ai-code/schema-validation.d.ts +28 -0
  46. package/dist/detect/ai-code/schema-validation.d.ts.map +1 -0
  47. package/dist/detect/ai-code/schema-validation.js +378 -0
  48. package/dist/detect/ai-code/schema-validation.js.map +1 -0
  49. package/dist/detect/config/agent-skill-injection.d.ts +27 -0
  50. package/dist/detect/config/agent-skill-injection.d.ts.map +1 -0
  51. package/dist/detect/config/agent-skill-injection.js +472 -0
  52. package/dist/detect/config/agent-skill-injection.js.map +1 -0
  53. package/dist/detect/config/comments.d.ts +11 -0
  54. package/dist/detect/config/comments.d.ts.map +1 -0
  55. package/dist/detect/config/comments.js +206 -0
  56. package/dist/detect/config/comments.js.map +1 -0
  57. package/dist/detect/config/file-flags.d.ts +10 -0
  58. package/dist/detect/config/file-flags.d.ts.map +1 -0
  59. package/dist/detect/config/file-flags.js +124 -0
  60. package/dist/detect/config/file-flags.js.map +1 -0
  61. package/dist/detect/config/index.d.ts +7 -0
  62. package/dist/detect/config/index.d.ts.map +1 -0
  63. package/dist/detect/config/index.js +17 -0
  64. package/dist/detect/config/index.js.map +1 -0
  65. package/dist/detect/config/osv-check.d.ts +75 -0
  66. package/dist/detect/config/osv-check.d.ts.map +1 -0
  67. package/dist/detect/config/osv-check.js +309 -0
  68. package/dist/detect/config/osv-check.js.map +1 -0
  69. package/dist/detect/config/package-check.d.ts +63 -0
  70. package/dist/detect/config/package-check.d.ts.map +1 -0
  71. package/dist/detect/config/package-check.js +509 -0
  72. package/dist/detect/config/package-check.js.map +1 -0
  73. package/dist/detect/config/urls.d.ts +11 -0
  74. package/dist/detect/config/urls.d.ts.map +1 -0
  75. package/dist/detect/config/urls.js +450 -0
  76. package/dist/detect/config/urls.js.map +1 -0
  77. package/dist/detect/index.d.ts +37 -0
  78. package/dist/detect/index.d.ts.map +1 -0
  79. package/dist/detect/index.js +77 -0
  80. package/dist/detect/index.js.map +1 -0
  81. package/dist/detect/secrets/config-audit.d.ts +11 -0
  82. package/dist/detect/secrets/config-audit.d.ts.map +1 -0
  83. package/dist/detect/secrets/config-audit.js +315 -0
  84. package/dist/detect/secrets/config-audit.js.map +1 -0
  85. package/dist/detect/secrets/config-mcp-audit.d.ts +23 -0
  86. package/dist/detect/secrets/config-mcp-audit.d.ts.map +1 -0
  87. package/dist/detect/secrets/config-mcp-audit.js +243 -0
  88. package/dist/detect/secrets/config-mcp-audit.js.map +1 -0
  89. package/dist/detect/secrets/entropy.d.ts +11 -0
  90. package/dist/detect/secrets/entropy.d.ts.map +1 -0
  91. package/dist/detect/secrets/entropy.js +751 -0
  92. package/dist/detect/secrets/entropy.js.map +1 -0
  93. package/dist/detect/secrets/index.d.ts +36 -0
  94. package/dist/detect/secrets/index.d.ts.map +1 -0
  95. package/dist/detect/secrets/index.js +174 -0
  96. package/dist/detect/secrets/index.js.map +1 -0
  97. package/dist/detect/secrets/patterns.d.ts +11 -0
  98. package/dist/detect/secrets/patterns.d.ts.map +1 -0
  99. package/dist/detect/secrets/patterns.js +518 -0
  100. package/dist/detect/secrets/patterns.js.map +1 -0
  101. package/dist/detect/secrets/weak-crypto.d.ts +10 -0
  102. package/dist/detect/secrets/weak-crypto.d.ts.map +1 -0
  103. package/dist/detect/secrets/weak-crypto.js +432 -0
  104. package/dist/detect/secrets/weak-crypto.js.map +1 -0
  105. package/dist/detect/structural/auth-patterns.d.ts +22 -0
  106. package/dist/detect/structural/auth-patterns.d.ts.map +1 -0
  107. package/dist/detect/structural/auth-patterns.js +533 -0
  108. package/dist/detect/structural/auth-patterns.js.map +1 -0
  109. package/dist/detect/structural/dangerous-functions/child-process.d.ts +16 -0
  110. package/dist/detect/structural/dangerous-functions/child-process.d.ts.map +1 -0
  111. package/dist/detect/structural/dangerous-functions/child-process.js +74 -0
  112. package/dist/detect/structural/dangerous-functions/child-process.js.map +1 -0
  113. package/dist/detect/structural/dangerous-functions/dom-xss.d.ts +34 -0
  114. package/dist/detect/structural/dangerous-functions/dom-xss.d.ts.map +1 -0
  115. package/dist/detect/structural/dangerous-functions/dom-xss.js +230 -0
  116. package/dist/detect/structural/dangerous-functions/dom-xss.js.map +1 -0
  117. package/dist/detect/structural/dangerous-functions/index.d.ts +16 -0
  118. package/dist/detect/structural/dangerous-functions/index.d.ts.map +1 -0
  119. package/dist/detect/structural/dangerous-functions/index.js +1193 -0
  120. package/dist/detect/structural/dangerous-functions/index.js.map +1 -0
  121. package/dist/detect/structural/dangerous-functions/json-parse.d.ts +31 -0
  122. package/dist/detect/structural/dangerous-functions/json-parse.d.ts.map +1 -0
  123. package/dist/detect/structural/dangerous-functions/json-parse.js +326 -0
  124. package/dist/detect/structural/dangerous-functions/json-parse.js.map +1 -0
  125. package/dist/detect/structural/dangerous-functions/math-random.d.ts +111 -0
  126. package/dist/detect/structural/dangerous-functions/math-random.d.ts.map +1 -0
  127. package/dist/detect/structural/dangerous-functions/math-random.js +684 -0
  128. package/dist/detect/structural/dangerous-functions/math-random.js.map +1 -0
  129. package/dist/detect/structural/dangerous-functions/patterns.d.ts +21 -0
  130. package/dist/detect/structural/dangerous-functions/patterns.d.ts.map +1 -0
  131. package/dist/detect/structural/dangerous-functions/patterns.js +163 -0
  132. package/dist/detect/structural/dangerous-functions/patterns.js.map +1 -0
  133. package/dist/detect/structural/dangerous-functions/request-validation.d.ts +13 -0
  134. package/dist/detect/structural/dangerous-functions/request-validation.d.ts.map +1 -0
  135. package/dist/detect/structural/dangerous-functions/request-validation.js +126 -0
  136. package/dist/detect/structural/dangerous-functions/request-validation.js.map +1 -0
  137. package/dist/detect/structural/dangerous-functions/utils/control-flow.d.ts +24 -0
  138. package/dist/detect/structural/dangerous-functions/utils/control-flow.d.ts.map +1 -0
  139. package/dist/detect/structural/dangerous-functions/utils/control-flow.js +70 -0
  140. package/dist/detect/structural/dangerous-functions/utils/control-flow.js.map +1 -0
  141. package/dist/detect/structural/dangerous-functions/utils/helpers.d.ts +31 -0
  142. package/dist/detect/structural/dangerous-functions/utils/helpers.d.ts.map +1 -0
  143. package/dist/detect/structural/dangerous-functions/utils/helpers.js +147 -0
  144. package/dist/detect/structural/dangerous-functions/utils/helpers.js.map +1 -0
  145. package/dist/detect/structural/dangerous-functions/utils/index.d.ts +9 -0
  146. package/dist/detect/structural/dangerous-functions/utils/index.d.ts.map +1 -0
  147. package/dist/detect/structural/dangerous-functions/utils/index.js +23 -0
  148. package/dist/detect/structural/dangerous-functions/utils/index.js.map +1 -0
  149. package/dist/detect/structural/dangerous-functions/utils/schema-validation.d.ts +22 -0
  150. package/dist/detect/structural/dangerous-functions/utils/schema-validation.d.ts.map +1 -0
  151. package/dist/detect/structural/dangerous-functions/utils/schema-validation.js +102 -0
  152. package/dist/detect/structural/dangerous-functions/utils/schema-validation.js.map +1 -0
  153. package/dist/detect/structural/data-exposure.d.ts +19 -0
  154. package/dist/detect/structural/data-exposure.d.ts.map +1 -0
  155. package/dist/detect/structural/data-exposure.js +262 -0
  156. package/dist/detect/structural/data-exposure.js.map +1 -0
  157. package/dist/detect/structural/framework-checks.d.ts +10 -0
  158. package/dist/detect/structural/framework-checks.d.ts.map +1 -0
  159. package/dist/detect/structural/framework-checks.js +389 -0
  160. package/dist/detect/structural/framework-checks.js.map +1 -0
  161. package/dist/detect/structural/index.d.ts +71 -0
  162. package/dist/detect/structural/index.d.ts.map +1 -0
  163. package/dist/detect/structural/index.js +510 -0
  164. package/dist/detect/structural/index.js.map +1 -0
  165. package/dist/detect/structural/log-injection.d.ts +18 -0
  166. package/dist/detect/structural/log-injection.d.ts.map +1 -0
  167. package/dist/detect/structural/log-injection.js +217 -0
  168. package/dist/detect/structural/log-injection.js.map +1 -0
  169. package/dist/detect/structural/logic-gates.d.ts +10 -0
  170. package/dist/detect/structural/logic-gates.d.ts.map +1 -0
  171. package/dist/detect/structural/logic-gates.js +227 -0
  172. package/dist/detect/structural/logic-gates.js.map +1 -0
  173. package/dist/detect/structural/risky-imports.d.ts +10 -0
  174. package/dist/detect/structural/risky-imports.d.ts.map +1 -0
  175. package/dist/detect/structural/risky-imports.js +168 -0
  176. package/dist/detect/structural/risky-imports.js.map +1 -0
  177. package/dist/detect/structural/security-headers.d.ts +18 -0
  178. package/dist/detect/structural/security-headers.d.ts.map +1 -0
  179. package/dist/detect/structural/security-headers.js +196 -0
  180. package/dist/detect/structural/security-headers.js.map +1 -0
  181. package/dist/detect/structural/ssrf-detection.d.ts +18 -0
  182. package/dist/detect/structural/ssrf-detection.d.ts.map +1 -0
  183. package/dist/detect/structural/ssrf-detection.js +263 -0
  184. package/dist/detect/structural/ssrf-detection.js.map +1 -0
  185. package/dist/detect/structural/variables.d.ts +11 -0
  186. package/dist/detect/structural/variables.d.ts.map +1 -0
  187. package/dist/detect/structural/variables.js +159 -0
  188. package/dist/detect/structural/variables.js.map +1 -0
  189. package/dist/detect/structural/xxe-detection.d.ts +18 -0
  190. package/dist/detect/structural/xxe-detection.d.ts.map +1 -0
  191. package/dist/detect/structural/xxe-detection.js +245 -0
  192. package/dist/detect/structural/xxe-detection.js.map +1 -0
  193. package/dist/index.d.ts +17 -64
  194. package/dist/index.d.ts.map +1 -1
  195. package/dist/index.js +49 -1034
  196. package/dist/index.js.map +1 -1
  197. package/dist/layer2/framework-checks.d.ts.map +1 -1
  198. package/dist/layer2/framework-checks.js +1 -8
  199. package/dist/layer2/framework-checks.js.map +1 -1
  200. package/dist/layer2/index.d.ts +4 -0
  201. package/dist/layer2/index.d.ts.map +1 -1
  202. package/dist/layer2/index.js +50 -1
  203. package/dist/layer2/index.js.map +1 -1
  204. package/dist/layer2/log-injection.d.ts +18 -0
  205. package/dist/layer2/log-injection.d.ts.map +1 -0
  206. package/dist/layer2/log-injection.js +214 -0
  207. package/dist/layer2/log-injection.js.map +1 -0
  208. package/dist/layer2/security-headers.d.ts +18 -0
  209. package/dist/layer2/security-headers.d.ts.map +1 -0
  210. package/dist/layer2/security-headers.js +187 -0
  211. package/dist/layer2/security-headers.js.map +1 -0
  212. package/dist/layer2/ssrf-detection.d.ts +18 -0
  213. package/dist/layer2/ssrf-detection.d.ts.map +1 -0
  214. package/dist/layer2/ssrf-detection.js +252 -0
  215. package/dist/layer2/ssrf-detection.js.map +1 -0
  216. package/dist/layer2/xxe-detection.d.ts +18 -0
  217. package/dist/layer2/xxe-detection.d.ts.map +1 -0
  218. package/dist/layer2/xxe-detection.js +242 -0
  219. package/dist/layer2/xxe-detection.js.map +1 -0
  220. package/dist/layer3/anthropic/prompts/index.d.ts +1 -1
  221. package/dist/layer3/anthropic/prompts/index.d.ts.map +1 -1
  222. package/dist/layer3/anthropic/prompts/index.js +3 -1
  223. package/dist/layer3/anthropic/prompts/index.js.map +1 -1
  224. package/dist/layer3/anthropic/prompts/modules/ai-patterns.d.ts +19 -0
  225. package/dist/layer3/anthropic/prompts/modules/ai-patterns.d.ts.map +1 -0
  226. package/dist/layer3/anthropic/prompts/modules/ai-patterns.js +156 -0
  227. package/dist/layer3/anthropic/prompts/modules/ai-patterns.js.map +1 -0
  228. package/dist/layer3/anthropic/prompts/modules/auth-access.d.ts +9 -0
  229. package/dist/layer3/anthropic/prompts/modules/auth-access.d.ts.map +1 -0
  230. package/dist/layer3/anthropic/prompts/modules/auth-access.js +25 -0
  231. package/dist/layer3/anthropic/prompts/modules/auth-access.js.map +1 -0
  232. package/dist/layer3/anthropic/prompts/modules/common.d.ts +11 -0
  233. package/dist/layer3/anthropic/prompts/modules/common.d.ts.map +1 -0
  234. package/dist/layer3/anthropic/prompts/modules/common.js +152 -0
  235. package/dist/layer3/anthropic/prompts/modules/common.js.map +1 -0
  236. package/dist/layer3/anthropic/prompts/modules/index.d.ts +54 -0
  237. package/dist/layer3/anthropic/prompts/modules/index.d.ts.map +1 -0
  238. package/dist/layer3/anthropic/prompts/modules/index.js +185 -0
  239. package/dist/layer3/anthropic/prompts/modules/index.js.map +1 -0
  240. package/dist/layer3/anthropic/prompts/modules/owasp-classic.d.ts +8 -0
  241. package/dist/layer3/anthropic/prompts/modules/owasp-classic.d.ts.map +1 -0
  242. package/dist/layer3/anthropic/prompts/modules/owasp-classic.js +84 -0
  243. package/dist/layer3/anthropic/prompts/modules/owasp-classic.js.map +1 -0
  244. package/dist/layer3/anthropic/prompts/modules/secrets-crypto.d.ts +8 -0
  245. package/dist/layer3/anthropic/prompts/modules/secrets-crypto.d.ts.map +1 -0
  246. package/dist/layer3/anthropic/prompts/modules/secrets-crypto.js +68 -0
  247. package/dist/layer3/anthropic/prompts/modules/secrets-crypto.js.map +1 -0
  248. package/dist/layer3/anthropic/prompts/modules/xss-prompt.d.ts +8 -0
  249. package/dist/layer3/anthropic/prompts/modules/xss-prompt.d.ts.map +1 -0
  250. package/dist/layer3/anthropic/prompts/modules/xss-prompt.js +22 -0
  251. package/dist/layer3/anthropic/prompts/modules/xss-prompt.js.map +1 -0
  252. package/dist/layer3/anthropic/prompts/validation.d.ts +9 -3
  253. package/dist/layer3/anthropic/prompts/validation.d.ts.map +1 -1
  254. package/dist/layer3/anthropic/prompts/validation.js +14 -410
  255. package/dist/layer3/anthropic/prompts/validation.js.map +1 -1
  256. package/dist/layer3/anthropic/providers/anthropic.d.ts.map +1 -1
  257. package/dist/layer3/anthropic/providers/anthropic.js +6 -3
  258. package/dist/layer3/anthropic/providers/anthropic.js.map +1 -1
  259. package/dist/layer3/anthropic/providers/openai.d.ts.map +1 -1
  260. package/dist/layer3/anthropic/providers/openai.js +6 -3
  261. package/dist/layer3/anthropic/providers/openai.js.map +1 -1
  262. package/dist/layer3/anthropic/request-builder.d.ts +11 -4
  263. package/dist/layer3/anthropic/request-builder.d.ts.map +1 -1
  264. package/dist/layer3/anthropic/request-builder.js +32 -16
  265. package/dist/layer3/anthropic/request-builder.js.map +1 -1
  266. package/dist/layer3/anthropic/utils/context-extractor.d.ts +55 -0
  267. package/dist/layer3/anthropic/utils/context-extractor.d.ts.map +1 -0
  268. package/dist/layer3/anthropic/utils/context-extractor.js +161 -0
  269. package/dist/layer3/anthropic/utils/context-extractor.js.map +1 -0
  270. package/dist/layer3/anthropic/utils/index.d.ts +2 -0
  271. package/dist/layer3/anthropic/utils/index.d.ts.map +1 -1
  272. package/dist/layer3/anthropic/utils/index.js +4 -1
  273. package/dist/layer3/anthropic/utils/index.js.map +1 -1
  274. package/dist/model/auth-helper-detector.d.ts +56 -0
  275. package/dist/model/auth-helper-detector.d.ts.map +1 -0
  276. package/dist/model/auth-helper-detector.js +360 -0
  277. package/dist/model/auth-helper-detector.js.map +1 -0
  278. package/dist/model/cross-file-taint.d.ts +40 -0
  279. package/dist/model/cross-file-taint.d.ts.map +1 -0
  280. package/dist/model/cross-file-taint.js +290 -0
  281. package/dist/model/cross-file-taint.js.map +1 -0
  282. package/dist/model/framework-models/django.d.ts +9 -0
  283. package/dist/model/framework-models/django.d.ts.map +1 -0
  284. package/dist/model/framework-models/django.js +82 -0
  285. package/dist/model/framework-models/django.js.map +1 -0
  286. package/dist/model/framework-models/express.d.ts +9 -0
  287. package/dist/model/framework-models/express.d.ts.map +1 -0
  288. package/dist/model/framework-models/express.js +52 -0
  289. package/dist/model/framework-models/express.js.map +1 -0
  290. package/dist/model/framework-models/index.d.ts +20 -0
  291. package/dist/model/framework-models/index.d.ts.map +1 -0
  292. package/dist/model/framework-models/index.js +102 -0
  293. package/dist/model/framework-models/index.js.map +1 -0
  294. package/dist/model/framework-models/nextjs.d.ts +9 -0
  295. package/dist/model/framework-models/nextjs.d.ts.map +1 -0
  296. package/dist/model/framework-models/nextjs.js +71 -0
  297. package/dist/model/framework-models/nextjs.js.map +1 -0
  298. package/dist/model/framework-models/prisma.d.ts +10 -0
  299. package/dist/model/framework-models/prisma.d.ts.map +1 -0
  300. package/dist/model/framework-models/prisma.js +54 -0
  301. package/dist/model/framework-models/prisma.js.map +1 -0
  302. package/dist/model/framework-models/react.d.ts +9 -0
  303. package/dist/model/framework-models/react.d.ts.map +1 -0
  304. package/dist/model/framework-models/react.js +67 -0
  305. package/dist/model/framework-models/react.js.map +1 -0
  306. package/dist/model/framework-models/sequelize.d.ts +9 -0
  307. package/dist/model/framework-models/sequelize.d.ts.map +1 -0
  308. package/dist/model/framework-models/sequelize.js +62 -0
  309. package/dist/model/framework-models/sequelize.js.map +1 -0
  310. package/dist/model/framework-models/types.d.ts +43 -0
  311. package/dist/model/framework-models/types.d.ts.map +1 -0
  312. package/dist/model/framework-models/types.js +10 -0
  313. package/dist/model/framework-models/types.js.map +1 -0
  314. package/dist/model/function-classifier.d.ts +32 -0
  315. package/dist/model/function-classifier.d.ts.map +1 -0
  316. package/dist/model/function-classifier.js +143 -0
  317. package/dist/model/function-classifier.js.map +1 -0
  318. package/dist/model/import-resolver.d.ts +45 -0
  319. package/dist/model/import-resolver.d.ts.map +1 -0
  320. package/dist/model/import-resolver.js +410 -0
  321. package/dist/model/import-resolver.js.map +1 -0
  322. package/dist/model/imported-auth-detector.d.ts +38 -0
  323. package/dist/model/imported-auth-detector.d.ts.map +1 -0
  324. package/dist/model/imported-auth-detector.js +199 -0
  325. package/dist/model/imported-auth-detector.js.map +1 -0
  326. package/dist/model/index.d.ts +63 -0
  327. package/dist/model/index.d.ts.map +1 -0
  328. package/dist/model/index.js +272 -0
  329. package/dist/model/index.js.map +1 -0
  330. package/dist/model/middleware-detector.d.ts +55 -0
  331. package/dist/model/middleware-detector.d.ts.map +1 -0
  332. package/dist/model/middleware-detector.js +382 -0
  333. package/dist/model/middleware-detector.js.map +1 -0
  334. package/dist/model/module-graph.d.ts +46 -0
  335. package/dist/model/module-graph.d.ts.map +1 -0
  336. package/dist/model/module-graph.js +187 -0
  337. package/dist/model/module-graph.js.map +1 -0
  338. package/dist/model/oauth-flow-detector.d.ts +41 -0
  339. package/dist/model/oauth-flow-detector.d.ts.map +1 -0
  340. package/dist/model/oauth-flow-detector.js +202 -0
  341. package/dist/model/oauth-flow-detector.js.map +1 -0
  342. package/dist/model/project-context.d.ts +119 -0
  343. package/dist/model/project-context.d.ts.map +1 -0
  344. package/dist/model/project-context.js +534 -0
  345. package/dist/model/project-context.js.map +1 -0
  346. package/dist/model/route-auth-resolver.d.ts +27 -0
  347. package/dist/model/route-auth-resolver.d.ts.map +1 -0
  348. package/dist/model/route-auth-resolver.js +182 -0
  349. package/dist/model/route-auth-resolver.js.map +1 -0
  350. package/dist/model/route-discovery/express.d.ts +25 -0
  351. package/dist/model/route-discovery/express.d.ts.map +1 -0
  352. package/dist/model/route-discovery/express.js +225 -0
  353. package/dist/model/route-discovery/express.js.map +1 -0
  354. package/dist/model/route-discovery/index.d.ts +21 -0
  355. package/dist/model/route-discovery/index.d.ts.map +1 -0
  356. package/dist/model/route-discovery/index.js +67 -0
  357. package/dist/model/route-discovery/index.js.map +1 -0
  358. package/dist/model/route-discovery/nextjs.d.ts +16 -0
  359. package/dist/model/route-discovery/nextjs.d.ts.map +1 -0
  360. package/dist/model/route-discovery/nextjs.js +179 -0
  361. package/dist/model/route-discovery/nextjs.js.map +1 -0
  362. package/dist/model/route-discovery/python.d.ts +16 -0
  363. package/dist/model/route-discovery/python.d.ts.map +1 -0
  364. package/dist/model/route-discovery/python.js +181 -0
  365. package/dist/model/route-discovery/python.js.map +1 -0
  366. package/dist/model/route-discovery/types.d.ts +36 -0
  367. package/dist/model/route-discovery/types.d.ts.map +1 -0
  368. package/dist/model/route-discovery/types.js +16 -0
  369. package/dist/model/route-discovery/types.js.map +1 -0
  370. package/dist/model/route-discovery/utils.d.ts +18 -0
  371. package/dist/model/route-discovery/utils.d.ts.map +1 -0
  372. package/dist/model/route-discovery/utils.js +55 -0
  373. package/dist/model/route-discovery/utils.js.map +1 -0
  374. package/dist/model/route-hierarchy.d.ts +50 -0
  375. package/dist/model/route-hierarchy.d.ts.map +1 -0
  376. package/dist/model/route-hierarchy.js +226 -0
  377. package/dist/model/route-hierarchy.js.map +1 -0
  378. package/dist/model/sanitiser-detection.d.ts +27 -0
  379. package/dist/model/sanitiser-detection.d.ts.map +1 -0
  380. package/dist/model/sanitiser-detection.js +224 -0
  381. package/dist/model/sanitiser-detection.js.map +1 -0
  382. package/dist/model/sink-matcher.d.ts +17 -0
  383. package/dist/model/sink-matcher.d.ts.map +1 -0
  384. package/dist/model/sink-matcher.js +141 -0
  385. package/dist/model/sink-matcher.js.map +1 -0
  386. package/dist/model/sink-patterns.d.ts +19 -0
  387. package/dist/model/sink-patterns.d.ts.map +1 -0
  388. package/dist/model/sink-patterns.js +88 -0
  389. package/dist/model/sink-patterns.js.map +1 -0
  390. package/dist/model/source-discovery.d.ts +15 -0
  391. package/dist/model/source-discovery.d.ts.map +1 -0
  392. package/dist/model/source-discovery.js +170 -0
  393. package/dist/model/source-discovery.js.map +1 -0
  394. package/dist/model/taint-tracker.d.ts +21 -0
  395. package/dist/model/taint-tracker.d.ts.map +1 -0
  396. package/dist/model/taint-tracker.js +281 -0
  397. package/dist/model/taint-tracker.js.map +1 -0
  398. package/dist/model/taint-types.d.ts +74 -0
  399. package/dist/model/taint-types.d.ts.map +1 -0
  400. package/dist/model/taint-types.js +9 -0
  401. package/dist/model/taint-types.js.map +1 -0
  402. package/dist/model/trpc-analyzer.d.ts +78 -0
  403. package/dist/model/trpc-analyzer.d.ts.map +1 -0
  404. package/dist/model/trpc-analyzer.js +297 -0
  405. package/dist/model/trpc-analyzer.js.map +1 -0
  406. package/dist/parse/file-classifier.d.ts +228 -0
  407. package/dist/parse/file-classifier.d.ts.map +1 -0
  408. package/dist/parse/file-classifier.js +933 -0
  409. package/dist/parse/file-classifier.js.map +1 -0
  410. package/dist/parse/path-exclusions.d.ts +55 -0
  411. package/dist/parse/path-exclusions.d.ts.map +1 -0
  412. package/dist/parse/path-exclusions.js +224 -0
  413. package/dist/parse/path-exclusions.js.map +1 -0
  414. package/dist/pipeline/config.d.ts +39 -0
  415. package/dist/pipeline/config.d.ts.map +1 -0
  416. package/dist/pipeline/config.js +46 -0
  417. package/dist/pipeline/config.js.map +1 -0
  418. package/dist/pipeline/index.d.ts +34 -0
  419. package/dist/pipeline/index.d.ts.map +1 -0
  420. package/dist/pipeline/index.js +377 -0
  421. package/dist/pipeline/index.js.map +1 -0
  422. package/dist/pipeline/modes/incremental.d.ts +66 -0
  423. package/dist/pipeline/modes/incremental.d.ts.map +1 -0
  424. package/dist/pipeline/modes/incremental.js +200 -0
  425. package/dist/pipeline/modes/incremental.js.map +1 -0
  426. package/dist/postprocess/aggregation.d.ts +14 -0
  427. package/dist/postprocess/aggregation.d.ts.map +1 -0
  428. package/dist/postprocess/aggregation.js +63 -0
  429. package/dist/postprocess/aggregation.js.map +1 -0
  430. package/dist/postprocess/contradictions.d.ts +18 -0
  431. package/dist/postprocess/contradictions.d.ts.map +1 -0
  432. package/dist/postprocess/contradictions.js +99 -0
  433. package/dist/postprocess/contradictions.js.map +1 -0
  434. package/dist/postprocess/dedup.d.ts +13 -0
  435. package/dist/postprocess/dedup.d.ts.map +1 -0
  436. package/dist/postprocess/dedup.js +58 -0
  437. package/dist/postprocess/dedup.js.map +1 -0
  438. package/dist/postprocess/filtering/context-adjustments.d.ts +23 -0
  439. package/dist/postprocess/filtering/context-adjustments.d.ts.map +1 -0
  440. package/dist/postprocess/filtering/context-adjustments.js +100 -0
  441. package/dist/postprocess/filtering/context-adjustments.js.map +1 -0
  442. package/dist/postprocess/filtering/index.d.ts +3 -0
  443. package/dist/postprocess/filtering/index.d.ts.map +1 -0
  444. package/dist/postprocess/filtering/index.js +8 -0
  445. package/dist/postprocess/filtering/index.js.map +1 -0
  446. package/dist/postprocess/filtering/pipeline.d.ts +48 -0
  447. package/dist/postprocess/filtering/pipeline.d.ts.map +1 -0
  448. package/dist/postprocess/filtering/pipeline.js +76 -0
  449. package/dist/postprocess/filtering/pipeline.js.map +1 -0
  450. package/dist/postprocess/index.d.ts +41 -0
  451. package/dist/postprocess/index.d.ts.map +1 -0
  452. package/dist/postprocess/index.js +85 -0
  453. package/dist/postprocess/index.js.map +1 -0
  454. package/dist/postprocess/suppression/config-loader.d.ts +74 -0
  455. package/dist/postprocess/suppression/config-loader.d.ts.map +1 -0
  456. package/dist/postprocess/suppression/config-loader.js +424 -0
  457. package/dist/postprocess/suppression/config-loader.js.map +1 -0
  458. package/dist/postprocess/suppression/hash.d.ts +48 -0
  459. package/dist/postprocess/suppression/hash.d.ts.map +1 -0
  460. package/dist/postprocess/suppression/hash.js +88 -0
  461. package/dist/postprocess/suppression/hash.js.map +1 -0
  462. package/dist/postprocess/suppression/index.d.ts +11 -0
  463. package/dist/postprocess/suppression/index.d.ts.map +1 -0
  464. package/dist/postprocess/suppression/index.js +39 -0
  465. package/dist/postprocess/suppression/index.js.map +1 -0
  466. package/dist/postprocess/suppression/inline-parser.d.ts +39 -0
  467. package/dist/postprocess/suppression/inline-parser.d.ts.map +1 -0
  468. package/dist/postprocess/suppression/inline-parser.js +218 -0
  469. package/dist/postprocess/suppression/inline-parser.js.map +1 -0
  470. package/dist/postprocess/suppression/manager.d.ts +94 -0
  471. package/dist/postprocess/suppression/manager.d.ts.map +1 -0
  472. package/dist/postprocess/suppression/manager.js +292 -0
  473. package/dist/postprocess/suppression/manager.js.map +1 -0
  474. package/dist/postprocess/suppression/types.d.ts +151 -0
  475. package/dist/postprocess/suppression/types.d.ts.map +1 -0
  476. package/dist/postprocess/suppression/types.js +28 -0
  477. package/dist/postprocess/suppression/types.js.map +1 -0
  478. package/dist/postprocess/validation-cap.d.ts +17 -0
  479. package/dist/postprocess/validation-cap.d.ts.map +1 -0
  480. package/dist/postprocess/validation-cap.js +64 -0
  481. package/dist/postprocess/validation-cap.js.map +1 -0
  482. package/dist/report/build-result.d.ts +33 -0
  483. package/dist/report/build-result.d.ts.map +1 -0
  484. package/dist/report/build-result.js +59 -0
  485. package/dist/report/build-result.js.map +1 -0
  486. package/dist/report/enrichment.d.ts +19 -0
  487. package/dist/report/enrichment.d.ts.map +1 -0
  488. package/dist/report/enrichment.js +44 -0
  489. package/dist/report/enrichment.js.map +1 -0
  490. package/dist/report/formatters/ai-context.d.ts +23 -0
  491. package/dist/report/formatters/ai-context.d.ts.map +1 -0
  492. package/dist/report/formatters/ai-context.js +238 -0
  493. package/dist/report/formatters/ai-context.js.map +1 -0
  494. package/dist/report/formatters/cli-terminal.d.ts +65 -0
  495. package/dist/report/formatters/cli-terminal.d.ts.map +1 -0
  496. package/dist/report/formatters/cli-terminal.js +735 -0
  497. package/dist/report/formatters/cli-terminal.js.map +1 -0
  498. package/dist/report/formatters/github-comment.d.ts +41 -0
  499. package/dist/report/formatters/github-comment.d.ts.map +1 -0
  500. package/dist/report/formatters/github-comment.js +370 -0
  501. package/dist/report/formatters/github-comment.js.map +1 -0
  502. package/dist/report/formatters/grouping.d.ts +52 -0
  503. package/dist/report/formatters/grouping.d.ts.map +1 -0
  504. package/dist/report/formatters/grouping.js +152 -0
  505. package/dist/report/formatters/grouping.js.map +1 -0
  506. package/dist/report/formatters/ide/claude-code.d.ts +17 -0
  507. package/dist/report/formatters/ide/claude-code.d.ts.map +1 -0
  508. package/dist/report/formatters/ide/claude-code.js +94 -0
  509. package/dist/report/formatters/ide/claude-code.js.map +1 -0
  510. package/dist/report/formatters/ide/cursor.d.ts +13 -0
  511. package/dist/report/formatters/ide/cursor.d.ts.map +1 -0
  512. package/dist/report/formatters/ide/cursor.js +125 -0
  513. package/dist/report/formatters/ide/cursor.js.map +1 -0
  514. package/dist/report/formatters/ide/index.d.ts +62 -0
  515. package/dist/report/formatters/ide/index.d.ts.map +1 -0
  516. package/dist/report/formatters/ide/index.js +184 -0
  517. package/dist/report/formatters/ide/index.js.map +1 -0
  518. package/dist/report/formatters/ide/windsurf.d.ts +13 -0
  519. package/dist/report/formatters/ide/windsurf.d.ts.map +1 -0
  520. package/dist/report/formatters/ide/windsurf.js +117 -0
  521. package/dist/report/formatters/ide/windsurf.js.map +1 -0
  522. package/dist/report/formatters/index.d.ts +11 -0
  523. package/dist/report/formatters/index.d.ts.map +1 -0
  524. package/dist/report/formatters/index.js +54 -0
  525. package/dist/report/formatters/index.js.map +1 -0
  526. package/dist/report/formatters/vscode-diagnostic.d.ts +103 -0
  527. package/dist/report/formatters/vscode-diagnostic.d.ts.map +1 -0
  528. package/dist/report/formatters/vscode-diagnostic.js +151 -0
  529. package/dist/report/formatters/vscode-diagnostic.js.map +1 -0
  530. package/dist/report/summary.d.ts +27 -0
  531. package/dist/report/summary.d.ts.map +1 -0
  532. package/dist/report/summary.js +57 -0
  533. package/dist/report/summary.js.map +1 -0
  534. package/dist/rules/metadata.d.ts.map +1 -1
  535. package/dist/rules/metadata.js +66 -0
  536. package/dist/rules/metadata.js.map +1 -1
  537. package/dist/score/adjustments.d.ts +22 -0
  538. package/dist/score/adjustments.d.ts.map +1 -0
  539. package/dist/score/adjustments.js +373 -0
  540. package/dist/score/adjustments.js.map +1 -0
  541. package/dist/score/auto-dismiss.d.ts +28 -0
  542. package/dist/score/auto-dismiss.d.ts.map +1 -0
  543. package/dist/score/auto-dismiss.js +200 -0
  544. package/dist/score/auto-dismiss.js.map +1 -0
  545. package/dist/score/confidence.d.ts +19 -0
  546. package/dist/score/confidence.d.ts.map +1 -0
  547. package/dist/score/confidence.js +52 -0
  548. package/dist/score/confidence.js.map +1 -0
  549. package/dist/score/index.d.ts +61 -0
  550. package/dist/score/index.d.ts.map +1 -0
  551. package/dist/score/index.js +250 -0
  552. package/dist/score/index.js.map +1 -0
  553. package/dist/score/types.d.ts +160 -0
  554. package/dist/score/types.d.ts.map +1 -0
  555. package/dist/score/types.js +14 -0
  556. package/dist/score/types.js.map +1 -0
  557. package/dist/shared/ai-context/index.d.ts +6 -0
  558. package/dist/shared/ai-context/index.d.ts.map +1 -0
  559. package/dist/shared/ai-context/index.js +13 -0
  560. package/dist/shared/ai-context/index.js.map +1 -0
  561. package/dist/shared/ai-context/manager.d.ts +67 -0
  562. package/dist/shared/ai-context/manager.d.ts.map +1 -0
  563. package/dist/shared/ai-context/manager.js +104 -0
  564. package/dist/shared/ai-context/manager.js.map +1 -0
  565. package/dist/shared/baseline/diff.d.ts +32 -0
  566. package/dist/shared/baseline/diff.d.ts.map +1 -0
  567. package/dist/shared/baseline/diff.js +119 -0
  568. package/dist/shared/baseline/diff.js.map +1 -0
  569. package/dist/shared/baseline/index.d.ts +9 -0
  570. package/dist/shared/baseline/index.d.ts.map +1 -0
  571. package/dist/shared/baseline/index.js +19 -0
  572. package/dist/shared/baseline/index.js.map +1 -0
  573. package/dist/shared/baseline/manager.d.ts +67 -0
  574. package/dist/shared/baseline/manager.d.ts.map +1 -0
  575. package/dist/shared/baseline/manager.js +180 -0
  576. package/dist/shared/baseline/manager.js.map +1 -0
  577. package/dist/shared/baseline/types.d.ts +91 -0
  578. package/dist/shared/baseline/types.d.ts.map +1 -0
  579. package/dist/shared/baseline/types.js +12 -0
  580. package/dist/shared/baseline/types.js.map +1 -0
  581. package/dist/shared/category-filter.d.ts +125 -0
  582. package/dist/shared/category-filter.d.ts.map +1 -0
  583. package/dist/shared/category-filter.js +360 -0
  584. package/dist/shared/category-filter.js.map +1 -0
  585. package/dist/shared/code-analysis.d.ts +39 -0
  586. package/dist/shared/code-analysis.d.ts.map +1 -0
  587. package/dist/shared/code-analysis.js +159 -0
  588. package/dist/shared/code-analysis.js.map +1 -0
  589. package/dist/shared/comment-analyzer.d.ts +38 -0
  590. package/dist/shared/comment-analyzer.d.ts.map +1 -0
  591. package/dist/shared/comment-analyzer.js +218 -0
  592. package/dist/shared/comment-analyzer.js.map +1 -0
  593. package/dist/shared/diff-detector.d.ts +53 -0
  594. package/dist/shared/diff-detector.d.ts.map +1 -0
  595. package/dist/shared/diff-detector.js +104 -0
  596. package/dist/shared/diff-detector.js.map +1 -0
  597. package/dist/shared/diff-parser.d.ts +80 -0
  598. package/dist/shared/diff-parser.d.ts.map +1 -0
  599. package/dist/shared/diff-parser.js +202 -0
  600. package/dist/shared/diff-parser.js.map +1 -0
  601. package/dist/shared/environment-context.d.ts +76 -0
  602. package/dist/shared/environment-context.d.ts.map +1 -0
  603. package/dist/shared/environment-context.js +271 -0
  604. package/dist/shared/environment-context.js.map +1 -0
  605. package/dist/shared/intent-detector.d.ts +66 -0
  606. package/dist/shared/intent-detector.d.ts.map +1 -0
  607. package/dist/shared/intent-detector.js +282 -0
  608. package/dist/shared/intent-detector.js.map +1 -0
  609. package/dist/shared/parsed-file.d.ts +51 -0
  610. package/dist/shared/parsed-file.d.ts.map +1 -0
  611. package/dist/shared/parsed-file.js +95 -0
  612. package/dist/shared/parsed-file.js.map +1 -0
  613. package/dist/shared/registry-clients.d.ts +93 -0
  614. package/dist/shared/registry-clients.d.ts.map +1 -0
  615. package/dist/shared/registry-clients.js +273 -0
  616. package/dist/shared/registry-clients.js.map +1 -0
  617. package/dist/shared/rules/framework-fixes.d.ts +48 -0
  618. package/dist/shared/rules/framework-fixes.d.ts.map +1 -0
  619. package/dist/shared/rules/framework-fixes.js +439 -0
  620. package/dist/shared/rules/framework-fixes.js.map +1 -0
  621. package/dist/shared/rules/index.d.ts +8 -0
  622. package/dist/shared/rules/index.d.ts.map +1 -0
  623. package/dist/shared/rules/index.js +18 -0
  624. package/dist/shared/rules/index.js.map +1 -0
  625. package/dist/shared/rules/metadata.d.ts +43 -0
  626. package/dist/shared/rules/metadata.d.ts.map +1 -0
  627. package/dist/shared/rules/metadata.js +819 -0
  628. package/dist/shared/rules/metadata.js.map +1 -0
  629. package/dist/shared/schema-semantics.d.ts +45 -0
  630. package/dist/shared/schema-semantics.d.ts.map +1 -0
  631. package/dist/shared/schema-semantics.js +193 -0
  632. package/dist/shared/schema-semantics.js.map +1 -0
  633. package/dist/shared/types.d.ts +337 -0
  634. package/dist/shared/types.d.ts.map +1 -0
  635. package/dist/shared/types.js +126 -0
  636. package/dist/shared/types.js.map +1 -0
  637. package/dist/tiers.d.ts +2 -2
  638. package/dist/tiers.d.ts.map +1 -1
  639. package/dist/tiers.js +10 -0
  640. package/dist/tiers.js.map +1 -1
  641. package/dist/types.d.ts +1 -1
  642. package/dist/types.d.ts.map +1 -1
  643. package/dist/types.js.map +1 -1
  644. package/dist/validate/clients.d.ts +44 -0
  645. package/dist/validate/clients.d.ts.map +1 -0
  646. package/dist/validate/clients.js +81 -0
  647. package/dist/validate/clients.js.map +1 -0
  648. package/dist/validate/index.d.ts +41 -0
  649. package/dist/validate/index.d.ts.map +1 -0
  650. package/dist/validate/index.js +141 -0
  651. package/dist/validate/index.js.map +1 -0
  652. package/dist/validate/prompts/index.d.ts +8 -0
  653. package/dist/validate/prompts/index.d.ts.map +1 -0
  654. package/dist/validate/prompts/index.js +16 -0
  655. package/dist/validate/prompts/index.js.map +1 -0
  656. package/dist/validate/prompts/modules/ai-patterns.d.ts +19 -0
  657. package/dist/validate/prompts/modules/ai-patterns.d.ts.map +1 -0
  658. package/dist/validate/prompts/modules/ai-patterns.js +156 -0
  659. package/dist/validate/prompts/modules/ai-patterns.js.map +1 -0
  660. package/dist/validate/prompts/modules/auth-access.d.ts +9 -0
  661. package/dist/validate/prompts/modules/auth-access.d.ts.map +1 -0
  662. package/dist/validate/prompts/modules/auth-access.js +25 -0
  663. package/dist/validate/prompts/modules/auth-access.js.map +1 -0
  664. package/dist/validate/prompts/modules/common.d.ts +11 -0
  665. package/dist/validate/prompts/modules/common.d.ts.map +1 -0
  666. package/dist/validate/prompts/modules/common.js +186 -0
  667. package/dist/validate/prompts/modules/common.js.map +1 -0
  668. package/dist/validate/prompts/modules/index.d.ts +54 -0
  669. package/dist/validate/prompts/modules/index.d.ts.map +1 -0
  670. package/dist/validate/prompts/modules/index.js +186 -0
  671. package/dist/validate/prompts/modules/index.js.map +1 -0
  672. package/dist/validate/prompts/modules/owasp-classic.d.ts +8 -0
  673. package/dist/validate/prompts/modules/owasp-classic.d.ts.map +1 -0
  674. package/dist/validate/prompts/modules/owasp-classic.js +84 -0
  675. package/dist/validate/prompts/modules/owasp-classic.js.map +1 -0
  676. package/dist/validate/prompts/modules/secrets-crypto.d.ts +8 -0
  677. package/dist/validate/prompts/modules/secrets-crypto.d.ts.map +1 -0
  678. package/dist/validate/prompts/modules/secrets-crypto.js +68 -0
  679. package/dist/validate/prompts/modules/secrets-crypto.js.map +1 -0
  680. package/dist/validate/prompts/modules/xss-prompt.d.ts +8 -0
  681. package/dist/validate/prompts/modules/xss-prompt.d.ts.map +1 -0
  682. package/dist/validate/prompts/modules/xss-prompt.js +22 -0
  683. package/dist/validate/prompts/modules/xss-prompt.js.map +1 -0
  684. package/dist/validate/prompts/semantic-analysis.d.ts +15 -0
  685. package/dist/validate/prompts/semantic-analysis.d.ts.map +1 -0
  686. package/dist/validate/prompts/semantic-analysis.js +169 -0
  687. package/dist/validate/prompts/semantic-analysis.js.map +1 -0
  688. package/dist/validate/prompts/validation.d.ts +18 -0
  689. package/dist/validate/prompts/validation.d.ts.map +1 -0
  690. package/dist/validate/prompts/validation.js +25 -0
  691. package/dist/validate/prompts/validation.js.map +1 -0
  692. package/dist/validate/providers/anthropic.d.ts +17 -0
  693. package/dist/validate/providers/anthropic.d.ts.map +1 -0
  694. package/dist/validate/providers/anthropic.js +260 -0
  695. package/dist/validate/providers/anthropic.js.map +1 -0
  696. package/dist/validate/providers/index.d.ts +8 -0
  697. package/dist/validate/providers/index.d.ts.map +1 -0
  698. package/dist/validate/providers/index.js +13 -0
  699. package/dist/validate/providers/index.js.map +1 -0
  700. package/dist/validate/providers/openai.d.ts +14 -0
  701. package/dist/validate/providers/openai.d.ts.map +1 -0
  702. package/dist/validate/providers/openai.js +336 -0
  703. package/dist/validate/providers/openai.js.map +1 -0
  704. package/dist/validate/request-builder.d.ts +61 -0
  705. package/dist/validate/request-builder.d.ts.map +1 -0
  706. package/dist/validate/request-builder.js +346 -0
  707. package/dist/validate/request-builder.js.map +1 -0
  708. package/dist/validate/types.d.ts +88 -0
  709. package/dist/validate/types.d.ts.map +1 -0
  710. package/dist/validate/types.js +38 -0
  711. package/dist/validate/types.js.map +1 -0
  712. package/dist/validate/utils/context-extractor.d.ts +55 -0
  713. package/dist/validate/utils/context-extractor.d.ts.map +1 -0
  714. package/dist/validate/utils/context-extractor.js +161 -0
  715. package/dist/validate/utils/context-extractor.js.map +1 -0
  716. package/dist/validate/utils/index.d.ts +11 -0
  717. package/dist/validate/utils/index.d.ts.map +1 -0
  718. package/dist/validate/utils/index.js +27 -0
  719. package/dist/validate/utils/index.js.map +1 -0
  720. package/dist/validate/utils/path-helpers.d.ts +21 -0
  721. package/dist/validate/utils/path-helpers.d.ts.map +1 -0
  722. package/dist/validate/utils/path-helpers.js +69 -0
  723. package/dist/validate/utils/path-helpers.js.map +1 -0
  724. package/dist/validate/utils/response-parser.d.ts +40 -0
  725. package/dist/validate/utils/response-parser.d.ts.map +1 -0
  726. package/dist/validate/utils/response-parser.js +286 -0
  727. package/dist/validate/utils/response-parser.js.map +1 -0
  728. package/dist/validate/utils/retry.d.ts +15 -0
  729. package/dist/validate/utils/retry.d.ts.map +1 -0
  730. package/dist/validate/utils/retry.js +62 -0
  731. package/dist/validate/utils/retry.js.map +1 -0
  732. package/package.json +8 -7
  733. package/src/__tests__/benchmark/fixtures/layer1/agent-skill-injection.ts +204 -0
  734. package/src/__tests__/benchmark/fixtures/layer1/index.ts +3 -0
  735. package/src/__tests__/benchmark/fixtures/layer2/index.ts +15 -0
  736. package/src/__tests__/benchmark/fixtures/layer2/log-injection.ts +147 -0
  737. package/src/__tests__/benchmark/fixtures/layer2/security-headers.ts +197 -0
  738. package/src/__tests__/benchmark/fixtures/layer2/ssrf-detection.ts +210 -0
  739. package/src/__tests__/benchmark/fixtures/layer2/xxe-detection.ts +195 -0
  740. package/src/__tests__/benchmark/run-depth-validation.ts +3 -3
  741. package/src/__tests__/benchmark/run-real-world-test.ts +4 -4
  742. package/src/__tests__/benchmark/types.ts +1 -1
  743. package/src/__tests__/benchmark/utils/test-runner.ts +3 -3
  744. package/src/__tests__/category-filter.test.ts +2 -2
  745. package/src/__tests__/context-engine/cross-file-taint.test.ts +284 -0
  746. package/src/__tests__/context-engine/framework-models.test.ts +457 -0
  747. package/src/__tests__/context-engine/function-classifier.test.ts +146 -0
  748. package/src/__tests__/context-engine/import-resolver.test.ts +328 -0
  749. package/src/__tests__/context-engine/integration.test.ts +320 -0
  750. package/src/__tests__/context-engine/module-graph.test.ts +159 -0
  751. package/src/__tests__/context-engine/route-discovery/auth-resolver.test.ts +353 -0
  752. package/src/__tests__/context-engine/route-discovery/express.test.ts +150 -0
  753. package/src/__tests__/context-engine/route-discovery/nextjs.test.ts +138 -0
  754. package/src/__tests__/context-engine/route-discovery/python.test.ts +95 -0
  755. package/src/__tests__/context-engine/sanitiser-detection.test.ts +187 -0
  756. package/src/__tests__/context-engine/sink-matcher.test.ts +251 -0
  757. package/src/__tests__/context-engine/source-discovery.test.ts +186 -0
  758. package/src/__tests__/context-engine/taint-tracker.test.ts +182 -0
  759. package/src/__tests__/regression/agent-skill-benign.test.ts +174 -0
  760. package/src/__tests__/regression/known-false-positives.test.ts +312 -4
  761. package/src/__tests__/score/adjustments.test.ts +385 -0
  762. package/src/__tests__/score/confidence.test.ts +283 -0
  763. package/src/__tests__/score/framework-scoring.test.ts +275 -0
  764. package/src/__tests__/score/route-scoring.test.ts +156 -0
  765. package/src/__tests__/score/scoring-integration.test.ts +165 -0
  766. package/src/__tests__/score/taint-adjustments.test.ts +244 -0
  767. package/src/__tests__/snapshots/__snapshots__/anthropic-validation-refactor.test.ts.snap +37 -49
  768. package/src/__tests__/snapshots/__snapshots__/dangerous-functions-refactor.test.ts.snap +52 -0
  769. package/src/__tests__/snapshots/__snapshots__/scan-depth.test.ts.snap +3 -3
  770. package/src/__tests__/snapshots/anthropic-validation-refactor.test.ts +2 -2
  771. package/src/__tests__/snapshots/dangerous-functions-refactor.test.ts +1 -1
  772. package/src/__tests__/snapshots/scan-depth.test.ts +3 -3
  773. package/src/__tests__/validate/route-annotations.test.ts +138 -0
  774. package/src/__tests__/validation/analyze-results.ts +1 -1
  775. package/src/__tests__/validation/extract-for-triage.ts +1 -1
  776. package/src/__tests__/validation/fp-deep-analysis.ts +1 -1
  777. package/src/{layer2/ai-agent-tools.ts → detect/ai-code/agent-tools.ts} +23 -3
  778. package/src/{layer2 → detect/ai-code}/byok-patterns.ts +17 -5
  779. package/src/{layer2/ai-endpoint-protection.ts → detect/ai-code/endpoint-protection.ts} +8 -4
  780. package/src/{layer2/ai-execution-sinks.ts → detect/ai-code/execution-sinks.ts} +8 -4
  781. package/src/{layer2/ai-fingerprinting.ts → detect/ai-code/fingerprinting.ts} +20 -4
  782. package/src/detect/ai-code/index.ts +11 -0
  783. package/src/{layer2/ai-mcp-security.ts → detect/ai-code/mcp-security.ts} +7 -3
  784. package/src/{layer2 → detect/ai-code}/model-supply-chain.ts +7 -3
  785. package/src/{layer2/ai-package-hallucination.ts → detect/ai-code/package-hallucination.ts} +18 -3
  786. package/src/{layer2/ai-prompt-hygiene.ts → detect/ai-code/prompt-hygiene.ts} +25 -3
  787. package/src/{layer2/ai-rag-safety.ts → detect/ai-code/rag-safety.ts} +7 -3
  788. package/src/{layer2/ai-schema-validation.ts → detect/ai-code/schema-validation.ts} +7 -3
  789. package/src/detect/config/agent-skill-injection.ts +551 -0
  790. package/src/{layer1 → detect/config}/comments.ts +6 -2
  791. package/src/{layer1 → detect/config}/file-flags.ts +9 -3
  792. package/src/detect/config/index.ts +6 -0
  793. package/src/{layer3 → detect/config}/osv-check.ts +3 -2
  794. package/src/{layer3 → detect/config}/package-check.ts +3 -2
  795. package/src/{layer1 → detect/config}/urls.ts +12 -5
  796. package/src/detect/index.ts +131 -0
  797. package/src/{layer1 → detect/secrets}/config-audit.ts +7 -2
  798. package/src/{layer1 → detect/secrets}/config-mcp-audit.ts +8 -3
  799. package/src/{layer1 → detect/secrets}/entropy.ts +23 -11
  800. package/src/{layer1 → detect/secrets}/index.ts +31 -30
  801. package/src/{layer1 → detect/secrets}/patterns.ts +10 -3
  802. package/src/{layer1 → detect/secrets}/weak-crypto.ts +7 -2
  803. package/src/{layer2/auth-antipatterns.ts → detect/structural/auth-patterns.ts} +23 -11
  804. package/src/{layer2 → detect/structural}/dangerous-functions/dom-xss.ts +1 -1
  805. package/src/{layer2 → detect/structural}/dangerous-functions/index.ts +47 -24
  806. package/src/{layer2 → detect/structural}/dangerous-functions/json-parse.ts +10 -2
  807. package/src/{layer2 → detect/structural}/dangerous-functions/math-random.ts +2 -2
  808. package/src/{layer2 → detect/structural}/dangerous-functions/patterns.ts +1 -1
  809. package/src/{layer2 → detect/structural}/dangerous-functions/request-validation.ts +10 -2
  810. package/src/{layer2 → detect/structural}/dangerous-functions/utils/control-flow.ts +2 -2
  811. package/src/{layer2 → detect/structural}/data-exposure.ts +11 -3
  812. package/src/{layer2 → detect/structural}/framework-checks.ts +10 -11
  813. package/src/{layer2 → detect/structural}/index.ts +80 -77
  814. package/src/detect/structural/log-injection.ts +254 -0
  815. package/src/{layer2 → detect/structural}/logic-gates.ts +13 -5
  816. package/src/{layer2 → detect/structural}/risky-imports.ts +7 -3
  817. package/src/detect/structural/security-headers.ts +231 -0
  818. package/src/detect/structural/ssrf-detection.ts +300 -0
  819. package/src/{layer2 → detect/structural}/variables.ts +7 -3
  820. package/src/detect/structural/xxe-detection.ts +295 -0
  821. package/src/index.ts +39 -1291
  822. package/src/{utils → model}/auth-helper-detector.ts +1 -1
  823. package/src/model/cross-file-taint.ts +374 -0
  824. package/src/model/framework-models/django.ts +82 -0
  825. package/src/model/framework-models/express.ts +54 -0
  826. package/src/model/framework-models/index.ts +116 -0
  827. package/src/model/framework-models/nextjs.ts +69 -0
  828. package/src/model/framework-models/prisma.ts +57 -0
  829. package/src/model/framework-models/react.ts +63 -0
  830. package/src/model/framework-models/sequelize.ts +63 -0
  831. package/src/model/framework-models/types.ts +46 -0
  832. package/src/model/function-classifier.ts +184 -0
  833. package/src/model/import-resolver.ts +453 -0
  834. package/src/{utils → model}/imported-auth-detector.ts +21 -85
  835. package/src/model/index.ts +353 -0
  836. package/src/{utils → model}/middleware-detector.ts +156 -17
  837. package/src/model/module-graph.ts +254 -0
  838. package/src/{utils → model}/oauth-flow-detector.ts +1 -1
  839. package/src/{utils/project-context-builder.ts → model/project-context.ts} +1 -1
  840. package/src/model/route-auth-resolver.ts +216 -0
  841. package/src/model/route-discovery/express.ts +251 -0
  842. package/src/model/route-discovery/index.ts +83 -0
  843. package/src/model/route-discovery/nextjs.ts +216 -0
  844. package/src/model/route-discovery/python.ts +214 -0
  845. package/src/model/route-discovery/types.ts +48 -0
  846. package/src/model/route-discovery/utils.ts +54 -0
  847. package/src/model/sanitiser-detection.ts +268 -0
  848. package/src/model/sink-matcher.ts +178 -0
  849. package/src/model/sink-patterns.ts +109 -0
  850. package/src/model/source-discovery.ts +209 -0
  851. package/src/model/taint-tracker.ts +333 -0
  852. package/src/model/taint-types.ts +149 -0
  853. package/src/{utils → model}/trpc-analyzer.ts +1 -1
  854. package/src/{utils/context-helpers.ts → parse/file-classifier.ts} +54 -0
  855. package/src/{utils → parse}/path-exclusions.ts +1 -1
  856. package/src/pipeline/config.ts +81 -0
  857. package/src/pipeline/index.ts +437 -0
  858. package/src/{modes → pipeline/modes}/incremental.ts +5 -5
  859. package/src/postprocess/aggregation.ts +74 -0
  860. package/src/postprocess/contradictions.ts +128 -0
  861. package/src/postprocess/dedup.ts +62 -0
  862. package/src/{filtering → postprocess/filtering}/__tests__/pipeline.test.ts +1 -1
  863. package/src/{filtering → postprocess/filtering}/context-adjustments.ts +2 -2
  864. package/src/{filtering → postprocess/filtering}/pipeline.ts +2 -2
  865. package/src/postprocess/index.ts +118 -0
  866. package/src/{suppression → postprocess/suppression}/config-loader.ts +1 -1
  867. package/src/{suppression → postprocess/suppression}/hash.ts +1 -1
  868. package/src/{suppression → postprocess/suppression}/inline-parser.ts +1 -1
  869. package/src/{suppression → postprocess/suppression}/manager.ts +1 -1
  870. package/src/{suppression → postprocess/suppression}/types.ts +2 -2
  871. package/src/postprocess/validation-cap.ts +66 -0
  872. package/src/report/build-result.ts +94 -0
  873. package/src/report/enrichment.ts +52 -0
  874. package/src/{formatters → report/formatters}/ai-context.ts +1 -1
  875. package/src/{formatters → report/formatters}/cli-terminal.ts +11 -11
  876. package/src/{formatters → report/formatters}/github-comment.ts +1 -1
  877. package/src/{formatters → report/formatters}/grouping.ts +8 -8
  878. package/src/{formatters → report/formatters}/ide/claude-code.ts +1 -1
  879. package/src/{formatters → report/formatters}/ide/cursor.ts +1 -1
  880. package/src/{formatters → report/formatters}/ide/windsurf.ts +1 -1
  881. package/src/{formatters → report/formatters}/vscode-diagnostic.ts +1 -1
  882. package/src/report/summary.ts +70 -0
  883. package/src/score/adjustments.ts +387 -0
  884. package/src/{layer3/anthropic → score}/auto-dismiss.ts +15 -14
  885. package/src/score/confidence.ts +66 -0
  886. package/src/score/index.ts +316 -0
  887. package/src/score/types.ts +187 -0
  888. package/src/{baseline → shared/baseline}/__tests__/diff.test.ts +2 -2
  889. package/src/{baseline → shared/baseline}/diff.ts +1 -1
  890. package/src/{baseline → shared/baseline}/manager.ts +1 -1
  891. package/src/{category-filter.ts → shared/category-filter.ts} +1 -1
  892. package/src/{utils → shared}/code-analysis.ts +1 -1
  893. package/src/{rules → shared/rules}/__tests__/metadata.test.ts +7 -0
  894. package/src/{rules → shared/rules}/framework-fixes.ts +1 -1
  895. package/src/{rules → shared/rules}/metadata.ts +94 -0
  896. package/src/{types.ts → shared/types.ts} +22 -5
  897. package/src/tiers.ts +18 -1
  898. package/src/validate/__tests__/context-extractor.test.ts +191 -0
  899. package/src/validate/__tests__/prompt-assembly.test.ts +233 -0
  900. package/src/validate/__tests__/request-builder.test.ts +347 -0
  901. package/src/{layer3/anthropic → validate}/index.ts +8 -7
  902. package/src/{layer3/anthropic → validate}/prompts/index.ts +2 -0
  903. package/src/validate/prompts/modules/ai-patterns.ts +153 -0
  904. package/src/validate/prompts/modules/auth-access.ts +22 -0
  905. package/src/validate/prompts/modules/common.ts +183 -0
  906. package/src/validate/prompts/modules/index.ts +204 -0
  907. package/src/validate/prompts/modules/owasp-classic.ts +81 -0
  908. package/src/validate/prompts/modules/secrets-crypto.ts +65 -0
  909. package/src/validate/prompts/modules/xss-prompt.ts +19 -0
  910. package/src/validate/prompts/validation.ts +20 -0
  911. package/src/{layer3/anthropic → validate}/providers/anthropic.ts +28 -27
  912. package/src/validate/providers/index.ts +8 -0
  913. package/src/{layer3/anthropic → validate}/providers/openai.ts +30 -25
  914. package/src/validate/request-builder.ts +448 -0
  915. package/src/{layer3/anthropic → validate}/types.ts +1 -1
  916. package/src/validate/utils/context-extractor.ts +220 -0
  917. package/src/{layer3/anthropic → validate}/utils/index.ts +10 -0
  918. package/src/{layer3/anthropic → validate}/utils/response-parser.ts +2 -1
  919. package/src/layer3/anthropic/prompts/validation.ts +0 -419
  920. package/src/layer3/anthropic/providers/index.ts +0 -8
  921. package/src/layer3/anthropic/request-builder.ts +0 -150
  922. package/src/layer3/index.ts +0 -168
  923. /package/src/{layer3 → detect/config}/__tests__/osv-check.test.ts +0 -0
  924. /package/src/{layer2 → detect/structural}/__tests__/math-random-enhanced.test.ts +0 -0
  925. /package/src/{layer2 → detect/structural}/dangerous-functions/child-process.ts +0 -0
  926. /package/src/{layer2 → detect/structural}/dangerous-functions/utils/helpers.ts +0 -0
  927. /package/src/{layer2 → detect/structural}/dangerous-functions/utils/index.ts +0 -0
  928. /package/src/{layer2 → detect/structural}/dangerous-functions/utils/schema-validation.ts +0 -0
  929. /package/src/{utils → model}/route-hierarchy.ts +0 -0
  930. /package/src/{filtering → postprocess/filtering}/index.ts +0 -0
  931. /package/src/{suppression → postprocess/suppression}/__tests__/config-loader.test.ts +0 -0
  932. /package/src/{suppression → postprocess/suppression}/__tests__/hash.test.ts +0 -0
  933. /package/src/{suppression → postprocess/suppression}/__tests__/inline-parser.test.ts +0 -0
  934. /package/src/{suppression → postprocess/suppression}/__tests__/manager.test.ts +0 -0
  935. /package/src/{suppression → postprocess/suppression}/index.ts +0 -0
  936. /package/src/{formatters → report/formatters}/__tests__/ai-context.test.ts +0 -0
  937. /package/src/{formatters → report/formatters}/ide/__tests__/ide.test.ts +0 -0
  938. /package/src/{formatters → report/formatters}/ide/index.ts +0 -0
  939. /package/src/{formatters → report/formatters}/index.ts +0 -0
  940. /package/src/{utils → shared}/__tests__/code-analysis.test.ts +0 -0
  941. /package/src/{utils → shared}/__tests__/parsed-file.test.ts +0 -0
  942. /package/src/{ai-context → shared/ai-context}/__tests__/manager.test.ts +0 -0
  943. /package/src/{ai-context → shared/ai-context}/index.ts +0 -0
  944. /package/src/{ai-context → shared/ai-context}/manager.ts +0 -0
  945. /package/src/{baseline → shared/baseline}/__tests__/manager.test.ts +0 -0
  946. /package/src/{baseline → shared/baseline}/index.ts +0 -0
  947. /package/src/{baseline → shared/baseline}/types.ts +0 -0
  948. /package/src/{utils → shared}/comment-analyzer.ts +0 -0
  949. /package/src/{utils → shared}/diff-detector.ts +0 -0
  950. /package/src/{utils → shared}/diff-parser.ts +0 -0
  951. /package/src/{utils → shared}/environment-context.ts +0 -0
  952. /package/src/{utils → shared}/intent-detector.ts +0 -0
  953. /package/src/{utils → shared}/parsed-file.ts +0 -0
  954. /package/src/{utils → shared}/registry-clients.ts +0 -0
  955. /package/src/{rules → shared/rules}/__tests__/framework-fixes.test.ts +0 -0
  956. /package/src/{rules → shared/rules}/index.ts +0 -0
  957. /package/src/{utils → shared}/schema-semantics.ts +0 -0
  958. /package/src/{layer3/anthropic → validate}/clients.ts +0 -0
  959. /package/src/{layer3/anthropic → validate}/prompts/semantic-analysis.ts +0 -0
  960. /package/src/{layer3/anthropic → validate}/utils/path-helpers.ts +0 -0
  961. /package/src/{layer3/anthropic → validate}/utils/retry.ts +0 -0
@@ -0,0 +1,1509 @@
1
+ "use strict";
2
+ /**
3
+ * Layer 2: AI Agent Tool Permission Detection
4
+ * Detects overly permissive agent tools and missing authorization checks
5
+ *
6
+ * Covers B4: Agent/tool orchestration logic
7
+ *
8
+ * Issues detected:
9
+ * - Tools with unrestricted file system access
10
+ * - Tools with unrestricted network access
11
+ * - Tools with shell/code execution capability
12
+ * - Tools without user/tenant context verification
13
+ * - Database tools without proper scoping
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.detectAIAgentTools = detectAIAgentTools;
17
+ const file_classifier_1 = require("../../parse/file-classifier");
18
+ const BASE_CONFIDENCE = 0.50;
19
+ // ============================================================================
20
+ // Agent/Tool Context Detection
21
+ // ============================================================================
22
+ /**
23
+ * Check if file contains agent or tool definitions
24
+ */
25
+ function isAgentOrToolFile(filePath, content) {
26
+ // File path indicators
27
+ const agentPathPatterns = [
28
+ /\/(agents?|tools?|functions?|actions?)\//i,
29
+ /\/(mcp|langchain|llamaindex|autogen)\//i,
30
+ /(agent|tool|function|action).*\.(ts|js|py)$/i,
31
+ ];
32
+ if (agentPathPatterns.some(p => p.test(filePath))) {
33
+ return true;
34
+ }
35
+ // Content patterns indicating tool/agent definitions
36
+ const toolDefinitionPatterns = [
37
+ /@tool/i, // Python decorator
38
+ /def\s+\w+_tool\s*\(/i, // Python tool function
39
+ /defineTool\s*\(/i, // JS/TS tool definition
40
+ /createTool\s*\(/i, // Tool creation
41
+ /\.registerTool\s*\(/i, // Tool registration
42
+ /\.addTool\s*\(/i, // Adding tool to agent
43
+ /tools\s*:\s*\[/i, // Tools array
44
+ /FunctionTool|StructuredTool/i, // LangChain tools
45
+ /tool_choice|function_call/i, // OpenAI function calling
46
+ /Tool\s*\(\s*\{/i, // Tool configuration object
47
+ /type:\s*['"`]function['"`]/i, // OpenAI function type
48
+ /mcpServer|McpServer/i, // MCP server
49
+ ];
50
+ return toolDefinitionPatterns.some(p => p.test(content));
51
+ }
52
+ /**
53
+ * Find tool definition boundaries (start and end lines)
54
+ */
55
+ function findToolDefinitionContext(content, lineNumber, windowSize = 30) {
56
+ const lines = content.split('\n');
57
+ const startLine = Math.max(0, lineNumber - windowSize);
58
+ const endLine = Math.min(lines.length, lineNumber + windowSize);
59
+ return {
60
+ context: lines.slice(startLine, endLine).join('\n'),
61
+ startLine,
62
+ endLine,
63
+ };
64
+ }
65
+ // ============================================================================
66
+ // Authorization Detection
67
+ // ============================================================================
68
+ /**
69
+ * Check if user context is verified in tool
70
+ */
71
+ function hasUserContextVerification(context) {
72
+ const userContextPatterns = [
73
+ /user[_.]?id/i,
74
+ /userId/i,
75
+ /currentUser/i,
76
+ /req\.user/i,
77
+ /request\.user/i,
78
+ /session\.user/i,
79
+ /getUser\s*\(/i,
80
+ /getCurrentUser\s*\(/i,
81
+ /authenticatedUser/i,
82
+ /ctx\.user/i,
83
+ /context\.user/i,
84
+ ];
85
+ return userContextPatterns.some(p => p.test(context));
86
+ }
87
+ /**
88
+ * Check if tenant/organization context is verified
89
+ */
90
+ function hasTenantContextVerification(context) {
91
+ const tenantContextPatterns = [
92
+ /tenant[_.]?id/i,
93
+ /tenantId/i,
94
+ /org[_.]?id/i,
95
+ /orgId/i,
96
+ /organization[_.]?id/i,
97
+ /workspace[_.]?id/i,
98
+ /workspaceId/i,
99
+ /team[_.]?id/i,
100
+ /teamId/i,
101
+ /account[_.]?id/i,
102
+ /accountId/i,
103
+ ];
104
+ return tenantContextPatterns.some(p => p.test(context));
105
+ }
106
+ /**
107
+ * Check if this is an MCP file with proper security controls
108
+ * MCP files with sanitization and authorization should be downgraded
109
+ */
110
+ function isMCPFileWithSafePatterns(content, filePath) {
111
+ // Check if this is an MCP file
112
+ const mcpPatterns = [
113
+ /McpServer/i,
114
+ /@modelcontextprotocol/i,
115
+ /server\.tool\s*\(/i,
116
+ /@server\.tool/i,
117
+ /\/mcp\//i,
118
+ ];
119
+ if (!mcpPatterns.some(p => p.test(content) || p.test(filePath))) {
120
+ return false;
121
+ }
122
+ // Check for content sanitization patterns
123
+ const sanitizationPatterns = [
124
+ /sanitize|DOMPurify|purify/i,
125
+ /escapeHtml|escape_html/i,
126
+ /validateSchema|schema\.parse|safeParse/i,
127
+ /ALLOWED_TAGS/i,
128
+ /filterHtml|cleanHtml/i,
129
+ ];
130
+ // Check for authorization patterns
131
+ const authorizationPatterns = [
132
+ /if\s*\([^)]*ownerId\s*[!=]==?/i,
133
+ /if\s*\([^)]*userId\s*[!=]==?/i,
134
+ /if\s*\([^)]*tenantId\s*[!=]==?/i,
135
+ /throw.*Error.*(?:auth|Forbidden|Unauthorized)/i,
136
+ /Not\s*authorized/i,
137
+ /checkPermission|hasPermission|isAuthorized/i,
138
+ ];
139
+ const hasSanitization = sanitizationPatterns.some(p => p.test(content));
140
+ const hasAuthorization = authorizationPatterns.some(p => p.test(content));
141
+ // MCP file with BOTH sanitization AND authorization is safe
142
+ return hasSanitization && hasAuthorization;
143
+ }
144
+ /**
145
+ * Patterns indicating strong/verified restrictions (actual implementation)
146
+ */
147
+ const STRONG_RESTRICTION_PATTERNS = [
148
+ // Sandboxing libraries and environments
149
+ /\bvm2\b/i,
150
+ /\bisolated-vm\b/i,
151
+ /\bquickjs\b/i,
152
+ /\bsandboxed\b/i,
153
+ /\bRestrictedPython\b/i,
154
+ /\bnsjail\b/i,
155
+ /\bfirejail\b/i,
156
+ /\bgvisor\b/i,
157
+ // Explicit path/resource restrictions with arrays
158
+ /allowed(?:Paths|Files|Dirs|Hosts|Urls|Commands)\s*[=:]\s*\[/i,
159
+ /(?:white|allow)list\s*[=:]\s*\[/i,
160
+ /(?:blocked|denied|forbidden)(?:Paths|Hosts|Commands)\s*[=:]\s*\[/i,
161
+ // Path validation functions
162
+ /validatePath\s*\(/i,
163
+ /isAllowedPath\s*\(/i,
164
+ /checkPathAccess\s*\(/i,
165
+ /resolvePath.*allowed/i,
166
+ /path\.resolve.*includes/i,
167
+ // Sandbox configuration objects
168
+ /sandbox\s*[=:]\s*(?:true|\{)/i,
169
+ /readonly\s*[=:]\s*true/i,
170
+ /readOnly\s*[=:]\s*true/i,
171
+ // Container/isolation patterns
172
+ /\b(?:docker|podman)\s+run\b.*--read-only/i,
173
+ /seccomp/i,
174
+ /capabilities\s*[=:]\s*\[\s*\]/i, // Empty capabilities = restricted
175
+ // Permission checking code
176
+ /if\s*\(\s*!?\s*(?:allowed|permitted|authorized)/i,
177
+ /(?:check|verify|validate)(?:Access|Permission|Capability)\s*\(/i,
178
+ ];
179
+ /**
180
+ * Patterns indicating weak/unverified restriction mentions (comments, TODOs)
181
+ */
182
+ const WEAK_RESTRICTION_PATTERNS = [
183
+ // Comments mentioning restrictions without implementation
184
+ /\/\/.*(?:sandbox|restrict|allowlist|whitelist|todo)/i,
185
+ /\/\*.*(?:sandbox|restrict|allowlist|whitelist|todo).*\*\//i,
186
+ /#.*(?:sandbox|restrict|allowlist|whitelist|todo)/i,
187
+ // TODOs and FIXMEs
188
+ /TODO.*(?:add|implement|enable).*(?:sandbox|restrict|allowlist)/i,
189
+ /FIXME.*(?:sandbox|restrict|security)/i,
190
+ // Variable names without assignment
191
+ /const\s+(?:sandbox|allowlist|whitelist)\s*;/i,
192
+ ];
193
+ /**
194
+ * Check if tool has strong/verified access restrictions
195
+ * These are actual implementations, not just mentions
196
+ */
197
+ function hasStrongRestrictions(context) {
198
+ // Check for strong patterns
199
+ const hasStrong = STRONG_RESTRICTION_PATTERNS.some(p => p.test(context));
200
+ if (!hasStrong)
201
+ return false;
202
+ // Verify it's not just a weak mention
203
+ const isWeak = WEAK_RESTRICTION_PATTERNS.some(p => p.test(context));
204
+ return !isWeak;
205
+ }
206
+ /**
207
+ * Check if tool has any access restrictions/allowlists (including weak mentions)
208
+ */
209
+ function hasAccessRestrictions(context) {
210
+ const restrictionPatterns = [
211
+ /allowedPaths/i,
212
+ /allowedFiles/i,
213
+ /allowedDirs/i,
214
+ /allowedHosts/i,
215
+ /allowedUrls/i,
216
+ /allowedCommands/i,
217
+ /allowedOperations/i,
218
+ /whitelist/i,
219
+ /allowlist/i,
220
+ /permissions?:/i,
221
+ /capabilities:/i,
222
+ /restrictions?:/i,
223
+ /constraints?:/i,
224
+ /sandbox/i,
225
+ /readonly/i,
226
+ /readOnly/i,
227
+ ];
228
+ return restrictionPatterns.some(p => p.test(context));
229
+ }
230
+ const OVERPERMISSIVE_TOOL_PATTERNS = [
231
+ // ========== Filesystem Access Tools ==========
232
+ {
233
+ name: 'Unrestricted file read tool',
234
+ pattern: /(?:@tool|defineTool|createTool|Tool\s*\()[^)]*(?:read|get).*file|(?:fs|filesystem).*(?:read|get)/gi,
235
+ riskType: 'filesystem',
236
+ baseSeverity: 'high',
237
+ description: 'Tool provides file system read access. Without restrictions, agents can access any file the process can read.',
238
+ suggestedFix: 'Add allowedPaths restriction. Example: { allowedPaths: ["/data/user-uploads"] }. Validate paths stay within allowed directories.',
239
+ requiresRestrictions: true,
240
+ },
241
+ {
242
+ name: 'Unrestricted file write tool',
243
+ pattern: /(?:@tool|defineTool|createTool|Tool\s*\()[^)]*(?:write|create|save).*file|(?:fs|filesystem).*(?:write|create)/gi,
244
+ riskType: 'filesystem',
245
+ baseSeverity: 'high',
246
+ description: 'Tool provides file system write access. Agents could overwrite critical files or create malicious files.',
247
+ suggestedFix: 'Restrict to specific directories. Validate file extensions. Implement size limits. Consider using signed URLs instead of direct file access.',
248
+ requiresRestrictions: true,
249
+ },
250
+ {
251
+ name: 'File deletion tool',
252
+ pattern: /(?:@tool|defineTool|createTool|Tool\s*\()[^)]*(?:delete|remove).*file|(?:fs|filesystem).*(?:delete|unlink|remove)/gi,
253
+ riskType: 'filesystem',
254
+ baseSeverity: 'high',
255
+ description: 'Tool provides file deletion capability. High risk of data loss if misused.',
256
+ suggestedFix: 'Implement soft-delete instead of hard delete. Require confirmation. Restrict to user-owned files only.',
257
+ requiresRestrictions: true,
258
+ requiresUserContext: true,
259
+ },
260
+ // ========== Network Access Tools ==========
261
+ {
262
+ name: 'Unrestricted HTTP/fetch tool',
263
+ pattern: /(?:@tool|defineTool|createTool|Tool\s*\()[^)]*(?:http|fetch|request|api)|tool.*(?:fetch|request)\s*\(/gi,
264
+ riskType: 'network',
265
+ baseSeverity: 'medium',
266
+ description: 'Tool provides network/HTTP access. Without restrictions, agents could make requests to internal services (SSRF) or exfiltrate data.',
267
+ suggestedFix: 'Add allowedHosts configuration. Block internal/private IP ranges. Implement request signing for sensitive operations.',
268
+ requiresRestrictions: true,
269
+ },
270
+ {
271
+ name: 'Web scraping tool',
272
+ pattern: /(?:@tool|defineTool|createTool|Tool\s*\()[^)]*(?:scrape|crawl|browse)/gi,
273
+ riskType: 'network',
274
+ baseSeverity: 'medium',
275
+ description: 'Tool provides web scraping capability. Could be used for SSRF or accessing internal resources.',
276
+ suggestedFix: 'Restrict to allowed domains. Block internal IP ranges. Implement rate limiting.',
277
+ requiresRestrictions: true,
278
+ },
279
+ // ========== Code Execution Tools ==========
280
+ {
281
+ name: 'Code execution tool',
282
+ pattern: /(?:@tool|defineTool|createTool|Tool\s*\()[^)]*(?:execute|run|eval).*(?:code|script)|tool.*(?:eval|exec)\s*\(/gi,
283
+ riskType: 'code_execution',
284
+ baseSeverity: 'critical',
285
+ description: 'Tool provides code execution capability. This is extremely dangerous without sandboxing.',
286
+ suggestedFix: 'Use vm2, isolated-vm, or similar sandboxing. Implement timeout and memory limits. Restrict available APIs/modules.',
287
+ requiresRestrictions: true,
288
+ },
289
+ {
290
+ name: 'Python interpreter tool',
291
+ pattern: /(?:@tool|defineTool|createTool|Tool\s*\()[^)]*python.*(?:exec|run|interpret)|PythonREPL|python_repl/gi,
292
+ riskType: 'code_execution',
293
+ baseSeverity: 'critical',
294
+ description: 'Tool provides Python execution capability. Can execute arbitrary system commands.',
295
+ suggestedFix: 'Use RestrictedPython or sandboxed environments. Block dangerous modules (os, subprocess, socket). Implement resource limits.',
296
+ requiresRestrictions: true,
297
+ },
298
+ // ========== Shell/Command Tools ==========
299
+ {
300
+ name: 'Shell command tool',
301
+ pattern: /(?:@tool|defineTool|createTool|Tool\s*\()[^)]*(?:shell|command|terminal|bash)|ShellTool|BashTool/gi,
302
+ riskType: 'shell',
303
+ baseSeverity: 'critical',
304
+ description: 'Tool provides shell command execution. Allows arbitrary system commands.',
305
+ suggestedFix: 'Implement strict command allowlisting. Use parameterized commands (execFile, not exec). Consider removing this capability entirely.',
306
+ requiresRestrictions: true,
307
+ },
308
+ {
309
+ name: 'System command tool',
310
+ pattern: /(?:@tool|defineTool|createTool)[^)]*(?:system|exec|spawn|subprocess)/gi,
311
+ riskType: 'shell',
312
+ baseSeverity: 'critical',
313
+ description: 'Tool with system command execution capability.',
314
+ suggestedFix: 'Restrict to specific commands via allowlist. Validate all arguments. Log all command executions.',
315
+ requiresRestrictions: true,
316
+ },
317
+ // ========== Database Tools ==========
318
+ {
319
+ name: 'Database query tool',
320
+ pattern: /(?:@tool|defineTool|createTool|Tool\s*\()[^)]*(?:query|sql|database)|tool.*(?:query|execute)\s*\(/gi,
321
+ riskType: 'database',
322
+ baseSeverity: 'high',
323
+ description: 'Tool provides database query access. Without scoping, agents could access any data.',
324
+ suggestedFix: 'Always scope queries to current user/tenant. Use row-level security (RLS). Implement read-only mode for most operations.',
325
+ requiresUserContext: true,
326
+ requiresTenantContext: true,
327
+ },
328
+ {
329
+ name: 'Raw SQL tool',
330
+ pattern: /(?:@tool|defineTool|createTool)[^)]*(?:raw.*sql|execute.*sql)/gi,
331
+ riskType: 'database',
332
+ baseSeverity: 'critical',
333
+ description: 'Tool allows raw SQL execution. High risk of SQL injection and unauthorized data access.',
334
+ suggestedFix: 'Use parameterized queries only. Implement query validation. Consider using an ORM instead of raw SQL.',
335
+ requiresUserContext: true,
336
+ requiresTenantContext: true,
337
+ },
338
+ // ========== M5: MCP Server Tools ==========
339
+ {
340
+ name: 'MCP server tool registration',
341
+ pattern: /(?:McpServer|Server)\s*\([^)]*\).*(?:setRequestHandler|tool|registerTool)|server\.tool\s*\(/gi,
342
+ riskType: 'code_execution',
343
+ baseSeverity: 'high',
344
+ description: 'MCP (Model Context Protocol) server registering tools. Verify tool capabilities are appropriately restricted.',
345
+ suggestedFix: 'Add capability restrictions to MCP server. Implement allowlists for file paths, network hosts, and commands.',
346
+ requiresRestrictions: true,
347
+ },
348
+ {
349
+ name: 'MCP tool with shell access',
350
+ pattern: /server\.tool\s*\([^)]*(?:name:\s*['"`](?:run|exec|shell|command)[^)]*|(?:exec|spawn|shell)\s*\()/gi,
351
+ riskType: 'shell',
352
+ baseSeverity: 'critical',
353
+ description: 'MCP tool with shell command execution capability. Extremely dangerous without restrictions.',
354
+ suggestedFix: 'Use allowlist of permitted commands. Never allow arbitrary command execution. Consider read-only alternatives.',
355
+ requiresRestrictions: true,
356
+ },
357
+ {
358
+ name: 'MCP file system tool',
359
+ pattern: /server\.tool\s*\([^)]*(?:name:\s*['"`](?:read|write|create|delete|list).*(?:file|dir)[^)]*|fs\.|readFile|writeFile)/gi,
360
+ riskType: 'filesystem',
361
+ baseSeverity: 'high',
362
+ description: 'MCP tool with file system access. Agents could access or modify arbitrary files.',
363
+ suggestedFix: 'Restrict to specific directories with allowedPaths. Implement path validation. Consider read-only access.',
364
+ requiresRestrictions: true,
365
+ },
366
+ // ========== M5: Vercel AI SDK Tools ==========
367
+ {
368
+ name: 'Vercel AI SDK tool definition',
369
+ pattern: /tool\s*\(\s*\{[^}]*(?:execute|parameters)/gi,
370
+ riskType: 'code_execution',
371
+ baseSeverity: 'medium',
372
+ description: 'Vercel AI SDK tool definition. Review the execute function for dangerous operations.',
373
+ suggestedFix: 'Validate tool parameters against expected schema. Implement proper access controls within execute function.',
374
+ requiresUserContext: true,
375
+ },
376
+ {
377
+ name: 'AI SDK tool with dangerous execute',
378
+ pattern: /tool\s*\(\s*\{[^}]*execute\s*:\s*async[^}]*(?:exec|spawn|eval|fs\.|fetch\s*\()[^}]*\}/gi,
379
+ riskType: 'code_execution',
380
+ baseSeverity: 'high',
381
+ description: 'Vercel AI SDK tool with potentially dangerous execute function (shell, eval, fs, or network access).',
382
+ suggestedFix: 'Add validation and restrictions in execute function. Implement allowlists for external operations.',
383
+ requiresRestrictions: true,
384
+ },
385
+ {
386
+ name: 'StreamableUI tool action',
387
+ pattern: /createStreamableUI.*tool.*\{.*action/gi,
388
+ riskType: 'code_execution',
389
+ baseSeverity: 'medium',
390
+ description: 'Streamable UI tool with server action. Ensure proper authorization before state mutations.',
391
+ suggestedFix: 'Verify user authentication and authorization before executing actions. Validate all inputs.',
392
+ requiresUserContext: true,
393
+ },
394
+ ];
395
+ /**
396
+ * Check if agent has proper iteration limits
397
+ */
398
+ function hasIterationLimits(context) {
399
+ const limitPatterns = [
400
+ /maxIterations\s*[:=]\s*\d{1,2}\b/i, // 1-99
401
+ /max_iterations\s*[:=]\s*\d{1,2}\b/i,
402
+ /iteration_limit\s*[:=]\s*\d{1,2}\b/i,
403
+ /max_steps\s*[:=]\s*\d{1,2}\b/i,
404
+ ];
405
+ return limitPatterns.some(p => p.test(context));
406
+ }
407
+ /**
408
+ * Check if agent has timeout configured
409
+ */
410
+ function hasTimeoutConfigured(context) {
411
+ const timeoutPatterns = [
412
+ /timeout\s*[:=]\s*[1-9]\d*/i, // Positive number
413
+ /max_execution_time\s*[:=]\s*[1-9]/i,
414
+ /execution_timeout\s*[:=]\s*[1-9]/i,
415
+ ];
416
+ return timeoutPatterns.some(p => p.test(context));
417
+ }
418
+ /**
419
+ * Check if human-in-the-loop is enabled
420
+ */
421
+ function hasHumanInLoop(context) {
422
+ const humanPatterns = [
423
+ /humanInLoop\s*[:=]\s*true/i,
424
+ /human_in_loop\s*[:=]\s*True/i,
425
+ /requireApproval\s*[:=]\s*true/i,
426
+ /require_approval\s*[:=]\s*True/i,
427
+ /human_input_mode\s*[:=]\s*['"`](?:ALWAYS|TERMINATE)['"`]/i,
428
+ /confirm_before\s*[:=]\s*true/i,
429
+ ];
430
+ return humanPatterns.some(p => p.test(context));
431
+ }
432
+ /**
433
+ * Check if Docker is configured for code execution
434
+ */
435
+ function hasDockerConfigured(context) {
436
+ const dockerPatterns = [
437
+ /use_docker\s*[:=]\s*True/i,
438
+ /docker\s*[:=]\s*true/i,
439
+ /container\s*[:=]\s*true/i,
440
+ /sandboxed\s*[:=]\s*true/i,
441
+ ];
442
+ return dockerPatterns.some(p => p.test(context));
443
+ }
444
+ /**
445
+ * Check if budget/cost limits are configured
446
+ */
447
+ function hasBudgetLimits(context) {
448
+ const budgetPatterns = [
449
+ /budgetLimit|budget_limit/i,
450
+ /costLimit|cost_limit/i,
451
+ /max_cost|maxCost/i,
452
+ /spending_limit/i,
453
+ /token_limit|tokenLimit/i,
454
+ ];
455
+ return budgetPatterns.some(p => p.test(context));
456
+ }
457
+ /**
458
+ * Phase 5: LLM Output Flow Patterns
459
+ * Detect when LLM-generated content flows into dangerous operations
460
+ */
461
+ const LLM_OUTPUT_FLOW_PATTERNS = [
462
+ // ========== LLM Output in Tool Names/Paths ==========
463
+ {
464
+ name: 'LLM output used as tool name',
465
+ pattern: /(?:tools?\[|getTools?\s*\(|callTool\s*\(|invokeTool\s*\(|executeTool\s*\()\s*(?:response|result|output|completion|message|content|llm|ai|model|gpt|claude)\.(?:content|text|tool|toolName|function|name|choice)/gi,
466
+ baseSeverity: 'critical',
467
+ description: 'LLM output used directly as tool name for invocation. An adversarial prompt could cause the agent to call arbitrary tools, bypassing intended restrictions.',
468
+ suggestedFix: 'Validate tool names against a static allowlist: const ALLOWED_TOOLS = [\'read\', \'write\'] as const; if (!ALLOWED_TOOLS.includes(toolName)) throw new Error("Invalid tool")',
469
+ framework: 'generic',
470
+ },
471
+ {
472
+ name: 'LLM output in file path',
473
+ pattern: /(?:fs|file|path|fsp)\.(?:readFile|writeFile|unlink|rm|mkdir|readdir|access|stat|copyFile|rename)\s*\(\s*(?:response|result|output|completion|message|content|llm|ai|model)\.(?:path|filePath|file|filename|directory|dir)/gi,
474
+ baseSeverity: 'critical',
475
+ description: 'LLM output used directly as file path. Path traversal or arbitrary file access could occur via prompt injection.',
476
+ suggestedFix: 'Validate paths against allowed directories: if (!path.startsWith(ALLOWED_BASE_DIR)) throw new Error("Invalid path"). Use path.resolve() and verify the result stays within bounds.',
477
+ framework: 'generic',
478
+ },
479
+ {
480
+ name: 'LLM output in shell command',
481
+ pattern: /(?:exec|spawn|execFile|execSync|spawnSync)\s*\(\s*(?:response|result|output|completion|message|content|llm|ai|model)\.(?:command|cmd|script|code|executable|program)/gi,
482
+ baseSeverity: 'critical',
483
+ description: 'LLM output used directly as shell command. Remote code execution via prompt injection.',
484
+ suggestedFix: 'Never use LLM output in shell commands. If necessary, use a strict allowlist of permitted commands and validate arguments.',
485
+ framework: 'generic',
486
+ },
487
+ {
488
+ name: 'LLM output in URL/endpoint',
489
+ pattern: /(?:fetch|axios|http|request|got)\s*\(\s*(?:response|result|output|completion|message|content|llm|ai|model)\.(?:url|endpoint|href|uri|link|host)/gi,
490
+ baseSeverity: 'high',
491
+ description: 'LLM output used directly as URL or endpoint. SSRF risk via prompt injection.',
492
+ suggestedFix: 'Validate URLs against allowed hosts. Use URL allowlists and block internal IP ranges.',
493
+ framework: 'generic',
494
+ },
495
+ {
496
+ name: 'LLM response destructured into tool call',
497
+ pattern: /(?:const|let|var)\s*\{\s*(?:tool|toolName|function|functionName|action|method)\s*\}\s*=\s*(?:response|result|output|completion|message|llm|ai|model)/gi,
498
+ baseSeverity: 'high',
499
+ description: 'Tool name destructured from LLM response. This pattern suggests dynamic tool selection based on LLM output.',
500
+ suggestedFix: 'Validate extracted tool names against a static allowlist before invocation.',
501
+ framework: 'generic',
502
+ },
503
+ {
504
+ name: 'Dynamic property access with LLM output',
505
+ pattern: /(?:tools|handlers|actions|functions|methods)\s*\[\s*(?:response|result|output|completion|message|content|llm|ai)(?:\.|(?:\s*\[['"`]?(?:tool|name|function|action)))/gi,
506
+ baseSeverity: 'high',
507
+ description: 'Dynamic object property access using LLM output. Could access unintended tools or methods.',
508
+ suggestedFix: 'Use explicit tool dispatch with allowlist validation: if (toolName in SAFE_TOOLS) { SAFE_TOOLS[toolName]() }',
509
+ framework: 'generic',
510
+ },
511
+ ];
512
+ /**
513
+ * Phase 5: Tool Permission Accumulation Patterns
514
+ * Detect unbounded tool registration and permission growth
515
+ */
516
+ const TOOL_ACCUMULATION_PATTERNS = [
517
+ // ========== Unbounded Tool Registration ==========
518
+ {
519
+ name: 'Unbounded tool registration',
520
+ pattern: /(?:agent|tools?|registry)\.(?:registerTool|addTool|push|add|set)\s*\(\s*(?:user|request|req|input|body|data|param)\.(?:tool|function|action|capability)/gi,
521
+ baseSeverity: 'high',
522
+ description: 'Tools registered dynamically from user input without bounds. Users could accumulate unlimited capabilities over time.',
523
+ suggestedFix: 'Use a static allowlist: const ALLOWED_TOOLS = [...] and validate against it. Implement tool count limits.',
524
+ framework: 'generic',
525
+ },
526
+ {
527
+ name: 'Tool array push without limit check',
528
+ pattern: /tools\.push\s*\([^)]+\)(?![\s\S]{0,50}(?:length\s*[<>]|limit|max|ALLOWED|whitelist|allowlist))/gi,
529
+ baseSeverity: 'medium',
530
+ description: 'Tools added to array without checking count limits. Tool list could grow unboundedly.',
531
+ suggestedFix: 'Add limit check: if (tools.length >= MAX_TOOLS) throw new Error("Tool limit reached")',
532
+ framework: 'generic',
533
+ },
534
+ {
535
+ name: 'Dynamic tool loading from user config',
536
+ pattern: /(?:require|import|loadModule|dynamicImport)\s*\(\s*(?:user|request|req|input|body|config)\.(?:tool|module|plugin|extension)/gi,
537
+ baseSeverity: 'critical',
538
+ description: 'Tool modules loaded dynamically from user-controlled paths. Could load arbitrary code.',
539
+ suggestedFix: 'Use a static module registry. Validate module paths against an allowlist.',
540
+ framework: 'generic',
541
+ },
542
+ {
543
+ name: 'Permission grant without authorization check',
544
+ pattern: /(?:grant|add|enable)(?:Permission|Capability|Access)\s*\(\s*[^)]*\)(?![\s\S]{0,30}(?:if|auth|permission|role|admin|isAdmin))/gi,
545
+ baseSeverity: 'high',
546
+ description: 'Permissions granted without visible authorization check. Users could escalate their own privileges.',
547
+ suggestedFix: 'Add authorization check: if (!user.hasRole("admin")) throw new Error("Unauthorized")',
548
+ framework: 'generic',
549
+ },
550
+ {
551
+ name: 'Tool inheritance without restriction',
552
+ pattern: /(?:inherit|extend|merge)(?:Tools|Capabilities|Permissions)\s*\(\s*(?:parent|base|source)\.tools/gi,
553
+ baseSeverity: 'medium',
554
+ description: 'Agent inherits tools from parent without filtering. Could inherit more permissions than intended.',
555
+ suggestedFix: 'Explicitly list inherited tools instead of blanket inheritance. Use allowlist for permitted inherited capabilities.',
556
+ framework: 'generic',
557
+ },
558
+ ];
559
+ /**
560
+ * Phase 5: Database Write Scoping Patterns
561
+ * Detect database writes that may lack proper user scoping
562
+ */
563
+ const DB_WRITE_SCOPING_PATTERNS = [
564
+ // ========== Database Writes Without User Scoping ==========
565
+ {
566
+ name: 'DB insert without userId',
567
+ pattern: /(?:db|database|prisma|knex|sequelize|mongoose|supabase|drizzle)\.(?:insert|create|save|add)\s*\(\s*\{(?![^}]*(?:userId|user_id|ownerId|owner_id|createdBy|created_by|authorId|author_id))[^}]*(?:content|data|text|body|message)\s*:/gi,
568
+ baseSeverity: 'high',
569
+ description: 'Database insert with content field but no user ID. AI-generated content may not be properly attributed to user.',
570
+ suggestedFix: 'Add user context: db.insert({ content: aiGenerated, userId: ctx.user.id })',
571
+ framework: 'generic',
572
+ },
573
+ {
574
+ name: 'DB insert with AI content unscopedp',
575
+ pattern: /(?:db|database|prisma|knex|sequelize|mongoose|supabase|drizzle)\.(?:insert|create)\s*\(\s*\{[^}]*:\s*(?:response|result|output|completion|message|ai|llm|model)\.(?:content|text|data|output|result)/gi,
576
+ baseSeverity: 'high',
577
+ description: 'AI-generated content inserted into database. Ensure proper user scoping and content validation.',
578
+ suggestedFix: 'Add user context and validate content: db.insert({ content: validated, userId: ctx.user.id, createdAt: Date.now() })',
579
+ framework: 'generic',
580
+ },
581
+ {
582
+ name: 'Bulk write without tenant filter',
583
+ pattern: /(?:db|database|prisma|knex|sequelize|mongoose|supabase|drizzle)\.(?:insertMany|createMany|bulkCreate|bulkInsert)\s*\([^)]*\)(?![\s\S]{0,50}(?:tenantId|tenant_id|orgId|org_id|organizationId))/gi,
584
+ baseSeverity: 'medium',
585
+ description: 'Bulk database write without visible tenant scoping. Multi-tenant data isolation may be at risk.',
586
+ suggestedFix: 'Add tenant filter to all bulk operations: records.map(r => ({ ...r, tenantId: ctx.tenant.id }))',
587
+ framework: 'generic',
588
+ },
589
+ {
590
+ name: 'Update without ownership check',
591
+ pattern: /(?:db|database|prisma|knex|sequelize|mongoose|supabase|drizzle)\.(?:update|updateOne|updateMany)\s*\(\s*\{[^}]*id\s*:/gi,
592
+ baseSeverity: 'medium',
593
+ description: 'Database update by ID without visible ownership verification. Agent could modify other users\' data.',
594
+ suggestedFix: 'Add ownership check: db.update({ where: { id, userId: ctx.user.id }, data: { ... } })',
595
+ framework: 'generic',
596
+ },
597
+ {
598
+ name: 'Delete without user scoping',
599
+ pattern: /(?:db|database|prisma|knex|sequelize|mongoose|supabase|drizzle)\.(?:delete|deleteOne|deleteMany|destroy|remove)\s*\(\s*\{[^}]*id\s*:/gi,
600
+ baseSeverity: 'high',
601
+ description: 'Database delete by ID without user scoping. Agent could delete other users\' data.',
602
+ suggestedFix: 'Add user scoping: db.delete({ where: { id, userId: ctx.user.id } })',
603
+ framework: 'generic',
604
+ },
605
+ ];
606
+ /**
607
+ * Phase 6 Task 1: Tool Parameter Injection Patterns
608
+ * Detect LLM output flowing to tool parameters (not just tool names)
609
+ */
610
+ const TOOL_PARAMETER_INJECTION_PATTERNS = [
611
+ // LLM output in tool parameters
612
+ {
613
+ name: 'LLM output in tool parameters',
614
+ pattern: /tool\s*\(\s*\{[^}]*:\s*(response|output|result|content|message|llmOutput|aiResponse|completion)(\.\w+)*\s*[,}]/gi,
615
+ baseSeverity: 'high',
616
+ description: 'Tool parameters derived from unvalidated LLM output can be manipulated via prompt injection. Attackers could modify tool behavior through crafted responses.',
617
+ suggestedFix: 'Validate and sanitize LLM output before passing as tool parameters. Use schema validation (zod, yup) to ensure expected structure.',
618
+ framework: 'generic',
619
+ },
620
+ // Tool args assigned directly from LLM output
621
+ {
622
+ name: 'Tool args from LLM output',
623
+ pattern: /\bargs\s*=\s*(response|output|result|content|message|llmOutput|aiResponse|completion)(\.\w+)*/gi,
624
+ baseSeverity: 'high',
625
+ description: 'Tool arguments assigned directly from LLM output enable parameter injection. Malicious prompts could inject unexpected arguments.',
626
+ suggestedFix: 'Use schema validation (zod, yup) on LLM output before passing to tools: const validatedArgs = toolArgsSchema.parse(llmOutput)',
627
+ framework: 'generic',
628
+ },
629
+ // Spread LLM output into tool call
630
+ {
631
+ name: 'LLM output spread into tool call',
632
+ pattern: /(?:executeTool|callTool|invokeTool|runTool)\s*\([^)]*\.\.\.(?:response|output|result|content|llmOutput|aiResponse)/gi,
633
+ baseSeverity: 'critical',
634
+ description: 'LLM output spread directly into tool invocation. All LLM-provided fields pass through unvalidated.',
635
+ suggestedFix: 'Destructure and validate specific fields: const { field1, field2 } = schema.parse(llmOutput); executeTool({ field1, field2 })',
636
+ framework: 'generic',
637
+ },
638
+ // Dynamic property access for tool params
639
+ {
640
+ name: 'Dynamic tool param from LLM',
641
+ pattern: /toolParams?\s*\[\s*(response|output|result|llmOutput|aiResponse)\./gi,
642
+ baseSeverity: 'high',
643
+ description: 'Tool parameter accessed dynamically from LLM output. Could access unintended parameters.',
644
+ suggestedFix: 'Use explicit parameter extraction with validation: const param = validateParam(llmOutput.expectedField)',
645
+ framework: 'generic',
646
+ },
647
+ // JSON.parse of LLM output for tool params
648
+ {
649
+ name: 'JSON parsed LLM output as tool params',
650
+ pattern: /JSON\.parse\s*\(\s*(response|output|result|content|llmOutput|aiResponse|completion)(?:\.\w+)?\s*\)[^;]*(?:tool|execute|invoke|call)/gi,
651
+ baseSeverity: 'high',
652
+ description: 'LLM output JSON-parsed and used as tool parameters. Parsed structure could contain malicious fields.',
653
+ suggestedFix: 'Validate parsed JSON against expected schema: const params = toolParamsSchema.parse(JSON.parse(llmOutput))',
654
+ framework: 'generic',
655
+ },
656
+ ];
657
+ /**
658
+ * Phase 6 Task 2: Tool Error Message Injection Patterns
659
+ * Detect raw error exposure to LLM that could leak system information or enable injection
660
+ */
661
+ const TOOL_ERROR_INJECTION_PATTERNS = [
662
+ // Raw error message in tool response
663
+ {
664
+ name: 'Raw error in tool response',
665
+ pattern: /catch\s*\([^)]*\)\s*\{[^}]*(return|resolve)\s*\([^)]*error\.(message|stack|toString)/gi,
666
+ baseSeverity: 'medium',
667
+ description: 'Raw error messages returned to LLM could leak system information (paths, credentials, internal state) or be used for prompt injection attacks.',
668
+ suggestedFix: 'Return sanitized, generic error messages to LLM. Log detailed errors server-side: catch (e) { logger.error(e); return { error: "Operation failed" } }',
669
+ framework: 'generic',
670
+ },
671
+ // Error object in tool return
672
+ {
673
+ name: 'Error object in tool return',
674
+ pattern: /return\s*\{[^}]*error\s*:\s*(?:e|err|error)(?:\s*,|\s*\})/gi,
675
+ baseSeverity: 'medium',
676
+ description: 'Error object returned directly to LLM. Full error objects may contain sensitive stack traces or internal details.',
677
+ suggestedFix: 'Return only error message or generic status: return { error: "Failed to process request", code: "OPERATION_FAILED" }',
678
+ framework: 'generic',
679
+ },
680
+ // Stack trace in response
681
+ {
682
+ name: 'Stack trace in tool response',
683
+ pattern: /return\s*\{[^}]*(?:stack|stackTrace|trace)\s*:\s*(?:e|err|error)\./gi,
684
+ baseSeverity: 'high',
685
+ description: 'Stack trace returned to LLM. Stack traces expose internal code paths, file structures, and potentially sensitive data.',
686
+ suggestedFix: 'Never return stack traces to LLM. Log them server-side for debugging: logger.error({ stack: e.stack }); return { error: "Internal error" }',
687
+ framework: 'generic',
688
+ },
689
+ // Exception details in resolve/reject
690
+ {
691
+ name: 'Exception details in promise resolution',
692
+ pattern: /(?:resolve|reject)\s*\(\s*\{[^}]*(?:exception|error|e)\s*:\s*(?:e|err|error)(?:\.message|\.stack)?/gi,
693
+ baseSeverity: 'medium',
694
+ description: 'Exception details passed in promise resolution. Error information flows to LLM context.',
695
+ suggestedFix: 'Sanitize error information before resolving: resolve({ success: false, error: sanitizeError(e) })',
696
+ framework: 'generic',
697
+ },
698
+ // String interpolation with error
699
+ {
700
+ name: 'Error interpolated in response string',
701
+ pattern: /return\s*[`'"].*\$\{(?:e|err|error)(?:\.message|\.stack)?\}.*[`'"]/gi,
702
+ baseSeverity: 'medium',
703
+ description: 'Error details interpolated into response string. Raw error text could contain sensitive information.',
704
+ suggestedFix: 'Use generic error messages: return `Operation failed: ${getGenericErrorMessage(e.code)}`',
705
+ framework: 'generic',
706
+ },
707
+ ];
708
+ /**
709
+ * Phase 5: Recursive Agent Patterns
710
+ * Detect unbounded agent recursion and self-spawning patterns
711
+ */
712
+ const RECURSIVE_AGENT_PATTERNS = [
713
+ // ========== Unbounded Agent Recursion ==========
714
+ {
715
+ name: 'Recursive agent call without depth limit',
716
+ pattern: /(?:async\s+)?function\s+(?:run|execute|process|handle)?Agent\s*\([^)]*\)\s*\{[\s\S]{0,200}(?:run|execute|process|handle)?Agent\s*\((?![^)]*depth|[^)]*level|[^)]*recursion)/gi,
717
+ baseSeverity: 'high',
718
+ description: 'Agent function calls itself without visible depth parameter. Could recurse indefinitely.',
719
+ suggestedFix: 'Add depth limit: async function runAgent(task, depth = 0) { if (depth > MAX_DEPTH) throw new Error("Max depth"); await runAgent(subtask, depth + 1) }',
720
+ framework: 'generic',
721
+ },
722
+ {
723
+ name: 'Agent spawns sub-agent without limit',
724
+ pattern: /(?:spawn|create|launch|start)(?:Agent|Worker|Task)\s*\([^)]*\)(?![\s\S]{0,50}(?:depth|level|count|limit|max|MAX))/gi,
725
+ baseSeverity: 'medium',
726
+ description: 'Sub-agent spawned without visible depth or count limit. Could lead to unbounded agent proliferation.',
727
+ suggestedFix: 'Track agent depth/count: if (agentCount >= MAX_AGENTS || depth > MAX_DEPTH) throw new Error("Agent limit reached")',
728
+ framework: 'generic',
729
+ },
730
+ {
731
+ name: 'Recursive task processing without bounds',
732
+ pattern: /(?:result|response|output)\.(?:subtasks?|children|next|followUp)\s*\.(?:forEach|map|for)\s*\([^)]*(?:process|run|execute)(?:Task|Agent)/gi,
733
+ baseSeverity: 'high',
734
+ description: 'Tasks processed recursively based on agent output. Agent could generate unlimited subtasks.',
735
+ suggestedFix: 'Limit subtask count: const subtasks = result.subtasks.slice(0, MAX_SUBTASKS). Track total processed tasks.',
736
+ framework: 'generic',
737
+ },
738
+ {
739
+ name: 'Self-improvement loop without termination',
740
+ pattern: /while\s*\([^)]*(?:improve|optimize|refine|enhance)[^)]*\)\s*\{[\s\S]{0,100}(?:agent|model|llm)/gi,
741
+ baseSeverity: 'high',
742
+ description: 'Agent self-improvement loop without clear termination. Could run indefinitely.',
743
+ suggestedFix: 'Add termination conditions: while (iterations < MAX_ITERATIONS && !satisfactory) { ... iterations++ }',
744
+ framework: 'generic',
745
+ },
746
+ {
747
+ name: 'CrewAI agent delegation without depth',
748
+ pattern: /\.delegate\s*\(\s*[^)]*\)(?![\s\S]{0,30}(?:max_delegation|delegation_limit|depth))/gi,
749
+ baseSeverity: 'medium',
750
+ description: 'CrewAI agent delegation without depth limit. Agents could delegate indefinitely to each other.',
751
+ suggestedFix: 'Set delegation limits in agent config: Agent(..., max_delegation_depth=3)',
752
+ framework: 'crewai',
753
+ },
754
+ {
755
+ name: 'LangGraph recursive edge without limit',
756
+ pattern: /\.add_edge\s*\([^)]*,\s*(?:SAME_NODE|self|current_node)/gi,
757
+ baseSeverity: 'medium',
758
+ description: 'LangGraph edge points back to same node without visible limit. Could create infinite loops.',
759
+ suggestedFix: 'Add iteration tracking and conditional edges with max_iterations check.',
760
+ framework: 'langchain',
761
+ },
762
+ ];
763
+ /**
764
+ * Excessive agency patterns for unbounded agent autonomy
765
+ */
766
+ const EXCESSIVE_AGENCY_PATTERNS = [
767
+ // ========== Generic Unbounded Loops ==========
768
+ {
769
+ name: 'Unbounded agent loop',
770
+ pattern: /while\s*\(\s*(?:true|1|True)\s*\)[\s\S]{0,100}(?:agent|step|run|execute|iterate)/gi,
771
+ baseSeverity: 'high',
772
+ description: 'Agent runs in an unbounded loop without explicit termination condition. This can lead to infinite execution, resource exhaustion, or runaway costs.',
773
+ suggestedFix: 'Add maxIterations limit: while (iterations < maxIterations) { ... }. Consider adding timeout and cost limits.',
774
+ framework: 'generic',
775
+ },
776
+ {
777
+ name: 'No iteration limit configured',
778
+ pattern: /maxIterations\s*[:=]\s*(?:-1|null|undefined|None|Infinity|float\s*\(\s*['"`]inf)/gi,
779
+ baseSeverity: 'high',
780
+ description: 'Agent configured with no iteration limit. This allows unbounded execution which can consume excessive resources.',
781
+ suggestedFix: 'Set a reasonable iteration limit: maxIterations: 10 (adjust based on your use case).',
782
+ framework: 'generic',
783
+ },
784
+ {
785
+ name: 'No timeout configured',
786
+ pattern: /timeout\s*[:=]\s*(?:-1|0|null|undefined|None|false|False)/gi,
787
+ baseSeverity: 'medium',
788
+ description: 'Agent timeout is disabled or set to zero. Long-running agents can hang indefinitely.',
789
+ suggestedFix: 'Configure a reasonable timeout: timeout: 300000 (5 minutes). Adjust based on expected execution time.',
790
+ framework: 'generic',
791
+ },
792
+ {
793
+ name: 'Auto-approve without human oversight',
794
+ pattern: /(?:autoApprove|auto_approve)\s*[:=]\s*(?:true|True)/gi,
795
+ baseSeverity: 'high',
796
+ description: 'Agent auto-approves actions without human review. Combined with destructive capabilities, this is dangerous.',
797
+ suggestedFix: 'Enable human-in-the-loop for sensitive operations: autoApprove: false, or implement approval workflows for destructive actions.',
798
+ framework: 'generic',
799
+ },
800
+ {
801
+ name: 'Human-in-loop disabled',
802
+ pattern: /(?:humanInLoop|human_in_loop)\s*[:=]\s*(?:false|False)/gi,
803
+ baseSeverity: 'medium',
804
+ description: 'Human oversight is explicitly disabled. The agent can take actions without human review.',
805
+ suggestedFix: 'Enable human-in-the-loop for sensitive operations: humanInLoop: true. Add confirmation prompts for destructive actions.',
806
+ framework: 'generic',
807
+ },
808
+ // ========== CrewAI Specific ==========
809
+ {
810
+ name: 'CrewAI unsafe code execution mode',
811
+ pattern: /code_execution_mode\s*[:=]\s*['"`]unsafe['"`]/gi,
812
+ baseSeverity: 'critical',
813
+ description: 'CrewAI agent configured with unsafe code execution mode. This allows arbitrary code execution without sandboxing.',
814
+ suggestedFix: 'Use safe mode: code_execution_mode="safe". This runs code in a restricted environment.',
815
+ framework: 'crewai',
816
+ },
817
+ {
818
+ name: 'CrewAI code execution without Docker',
819
+ pattern: /allow_code_execution\s*[:=]\s*True(?![\s\S]{0,50}use_docker\s*[:=]\s*True)/gi,
820
+ baseSeverity: 'high',
821
+ description: 'CrewAI agent allows code execution without Docker containerization. Code runs directly on the host system.',
822
+ suggestedFix: 'Enable Docker for code execution: Agent(..., allow_code_execution=True, code_execution_config={"use_docker": True})',
823
+ framework: 'crewai',
824
+ },
825
+ // ========== AutoGen Specific ==========
826
+ {
827
+ name: 'AutoGen use_docker=False',
828
+ pattern: /(?:code_execution_config|LocalCommandLineCodeExecutor)\s*[\s\S]{0,50}use_docker\s*[:=]\s*False/gi,
829
+ baseSeverity: 'critical',
830
+ description: 'AutoGen code execution configured without Docker. Code executes directly on the host, enabling full system access.',
831
+ suggestedFix: 'Use Docker: code_execution_config={"use_docker": True}. Or use DockerCommandLineCodeExecutor for sandboxed execution.',
832
+ framework: 'autogen',
833
+ },
834
+ {
835
+ name: 'AutoGen NEVER human input mode',
836
+ pattern: /human_input_mode\s*[:=]\s*['"`]NEVER['"`]/gi,
837
+ baseSeverity: 'high',
838
+ description: 'AutoGen agent configured to never request human input. Agent can execute indefinitely without human oversight.',
839
+ suggestedFix: 'Use "ALWAYS" or "TERMINATE" for human_input_mode. "TERMINATE" allows agent to complete but requests input on termination.',
840
+ framework: 'autogen',
841
+ },
842
+ {
843
+ name: 'AutoGen UserProxyAgent without reply limit',
844
+ pattern: /UserProxyAgent\s*\((?![^)]*max_consecutive_auto_reply)[^)]*\)/gi,
845
+ baseSeverity: 'medium',
846
+ description: 'AutoGen UserProxyAgent without max_consecutive_auto_reply limit. Agent can auto-reply indefinitely.',
847
+ suggestedFix: 'Add reply limit: UserProxyAgent(..., max_consecutive_auto_reply=10). Adjust limit based on expected conversation length.',
848
+ framework: 'autogen',
849
+ },
850
+ // ========== LangChain Specific ==========
851
+ {
852
+ name: 'LangChain AgentExecutor without limits',
853
+ pattern: /AgentExecutor\s*\([^)]*(?!max_iterations)[^)]*\)/gi,
854
+ baseSeverity: 'medium',
855
+ description: 'LangChain AgentExecutor without max_iterations. Agent can loop indefinitely on complex tasks.',
856
+ suggestedFix: 'Set iteration limit: AgentExecutor(..., max_iterations=15). Add early_stopping_method="generate" to gracefully stop.',
857
+ framework: 'langchain',
858
+ },
859
+ // ========== Overpermissioned Agents ==========
860
+ {
861
+ name: 'Agent with excessive tools',
862
+ pattern: /tools\s*[:=]\s*\[(?:[^\]]*,){10,}[^\]]*\]/gi,
863
+ baseSeverity: 'medium',
864
+ description: 'Agent configured with more than 10 tools. Overpermissioned agents have larger attack surface if compromised via prompt injection.',
865
+ suggestedFix: 'Follow principle of least privilege. Split into specialized agents with focused tool sets. Remove unused tools.',
866
+ framework: 'generic',
867
+ },
868
+ ];
869
+ /**
870
+ * Patterns for missing authorization in tools
871
+ */
872
+ const MISSING_AUTH_PATTERNS = [
873
+ {
874
+ name: 'Tool without user context',
875
+ pattern: /(?:@tool|defineTool|createTool|\.registerTool|\.addTool)\s*\([^)]*(?:async\s+)?(?:function|\().*(?:create|update|delete|modify|write|send)/gi,
876
+ riskType: 'database',
877
+ baseSeverity: 'medium',
878
+ description: 'Tool performs write operations but may not verify user context. Actions could be performed as wrong user.',
879
+ suggestedFix: 'Pass userId as required parameter. Verify user owns/can access the resource before modification.',
880
+ requiresUserContext: true,
881
+ },
882
+ ];
883
+ // ============================================================================
884
+ // Main Detection Function
885
+ // ============================================================================
886
+ /**
887
+ * Main detection function for AI agent tool permission issues
888
+ */
889
+ function detectAIAgentTools(content, filePath, options) {
890
+ const vulnerabilities = [];
891
+ // Skip non-applicable files
892
+ if ((0, file_classifier_1.isScannerOrFixtureFile)(filePath))
893
+ return vulnerabilities;
894
+ // Only scan files that appear to have agent/tool definitions
895
+ if (!isAgentOrToolFile(filePath, content)) {
896
+ return vulnerabilities;
897
+ }
898
+ const lines = options?.parsed?.lines ?? content.split('\n');
899
+ const isTestFile = (0, file_classifier_1.isTestOrMockFile)(filePath);
900
+ const isExample = (0, file_classifier_1.isExampleDirectory)(filePath);
901
+ const isLibrary = (0, file_classifier_1.isLibraryCode)(filePath);
902
+ // Scan for overly permissive tool patterns
903
+ for (const pattern of OVERPERMISSIVE_TOOL_PATTERNS) {
904
+ const regex = new RegExp(pattern.pattern.source, pattern.pattern.flags);
905
+ let match;
906
+ while ((match = regex.exec(content)) !== null) {
907
+ const lineNumber = content.substring(0, match.index).split('\n').length;
908
+ const lineContent = lines[lineNumber - 1]?.trim() || '';
909
+ // Skip comments
910
+ if ((0, file_classifier_1.isComment)(lineContent))
911
+ continue;
912
+ // Get tool context
913
+ const { context } = findToolDefinitionContext(content, lineNumber);
914
+ // Check for mitigations (strong vs weak)
915
+ const hasStrong = hasStrongRestrictions(context);
916
+ const hasWeak = hasAccessRestrictions(context);
917
+ const hasUserContext = hasUserContextVerification(context);
918
+ const hasTenantContext = hasTenantContextVerification(context);
919
+ // Determine if issue is fully mitigated
920
+ let isMitigated = true;
921
+ let hasPartialMitigation = false;
922
+ const missingMitigations = [];
923
+ if (pattern.requiresRestrictions) {
924
+ if (hasStrong) {
925
+ // Strong restrictions = fully mitigated for this requirement
926
+ }
927
+ else if (hasWeak) {
928
+ // Weak restrictions = partial mitigation
929
+ hasPartialMitigation = true;
930
+ missingMitigations.push('verified access restrictions (found mentions but not implementation)');
931
+ isMitigated = false;
932
+ }
933
+ else {
934
+ isMitigated = false;
935
+ missingMitigations.push('access restrictions');
936
+ }
937
+ }
938
+ if (pattern.requiresUserContext && !hasUserContext) {
939
+ isMitigated = false;
940
+ missingMitigations.push('user context verification');
941
+ }
942
+ if (pattern.requiresTenantContext && !hasTenantContext) {
943
+ isMitigated = false;
944
+ missingMitigations.push('tenant/org context verification');
945
+ }
946
+ // Skip if all required mitigations are present with strong verification
947
+ if (isMitigated)
948
+ continue;
949
+ // Calculate severity
950
+ let severity = pattern.baseSeverity;
951
+ const isMCPSafe = isMCPFileWithSafePatterns(content, filePath);
952
+ if (isTestFile) {
953
+ severity = 'info';
954
+ }
955
+ else if (isExample) {
956
+ // Example/demo code - downgrade to info
957
+ severity = 'info';
958
+ }
959
+ else if (isLibrary) {
960
+ // Library code - tool definitions are intentionally flexible
961
+ // Consumers add restrictions when they use the tools
962
+ severity = 'info';
963
+ }
964
+ else if (isMCPSafe) {
965
+ // MCP file with proper security controls (sanitization + authorization)
966
+ severity = 'info';
967
+ }
968
+ else if (hasPartialMitigation || hasUserContext || hasTenantContext) {
969
+ // Partial mitigation - downgrade
970
+ if (severity === 'critical')
971
+ severity = 'high';
972
+ else if (severity === 'high')
973
+ severity = 'medium';
974
+ }
975
+ // Build description
976
+ let description = pattern.description;
977
+ if (missingMitigations.length > 0) {
978
+ description += ` Missing: ${missingMitigations.join(', ')}.`;
979
+ }
980
+ if (isTestFile) {
981
+ description += ' (In test file.)';
982
+ }
983
+ else if (isExample) {
984
+ description += ' (In example/demo directory - not production code.)';
985
+ }
986
+ else if (isLibrary) {
987
+ description += ' (Library code - tool definitions are generic; consumers add restrictions.)';
988
+ }
989
+ else if (isMCPSafe) {
990
+ description += ' (MCP file with sanitization and authorization controls detected.)';
991
+ }
992
+ vulnerabilities.push({
993
+ id: `ai-tool-${filePath}-${lineNumber}-${pattern.riskType}`,
994
+ filePath,
995
+ lineNumber,
996
+ lineContent,
997
+ severity,
998
+ category: 'ai_overpermissive_tool',
999
+ title: pattern.name,
1000
+ description,
1001
+ suggestedFix: pattern.suggestedFix,
1002
+ confidence: 'medium',
1003
+ layer: 2,
1004
+ source: 'ai_code',
1005
+ requiresAIValidation: true, // Always validate - context dependent
1006
+ baseConfidence: BASE_CONFIDENCE,
1007
+ });
1008
+ }
1009
+ }
1010
+ // Scan for missing authorization patterns
1011
+ for (const pattern of MISSING_AUTH_PATTERNS) {
1012
+ const regex = new RegExp(pattern.pattern.source, pattern.pattern.flags);
1013
+ let match;
1014
+ while ((match = regex.exec(content)) !== null) {
1015
+ const lineNumber = content.substring(0, match.index).split('\n').length;
1016
+ const lineContent = lines[lineNumber - 1]?.trim() || '';
1017
+ // Skip comments
1018
+ if ((0, file_classifier_1.isComment)(lineContent))
1019
+ continue;
1020
+ // Get tool context
1021
+ const { context } = findToolDefinitionContext(content, lineNumber);
1022
+ // Check if user context is verified
1023
+ const hasUserContext = hasUserContextVerification(context);
1024
+ // Skip if user context is present
1025
+ if (hasUserContext)
1026
+ continue;
1027
+ let severity = pattern.baseSeverity;
1028
+ let description = pattern.description;
1029
+ if (isTestFile) {
1030
+ severity = 'info';
1031
+ description += ' (In test file.)';
1032
+ }
1033
+ vulnerabilities.push({
1034
+ id: `ai-tool-auth-${filePath}-${lineNumber}`,
1035
+ filePath,
1036
+ lineNumber,
1037
+ lineContent,
1038
+ severity,
1039
+ category: 'ai_overpermissive_tool',
1040
+ title: pattern.name,
1041
+ description,
1042
+ suggestedFix: pattern.suggestedFix,
1043
+ confidence: 'low', // Lower confidence - needs context
1044
+ layer: 2,
1045
+ source: 'ai_code',
1046
+ requiresAIValidation: true,
1047
+ baseConfidence: BASE_CONFIDENCE,
1048
+ });
1049
+ }
1050
+ }
1051
+ // Scan for excessive agency patterns (Phase 2)
1052
+ for (const pattern of EXCESSIVE_AGENCY_PATTERNS) {
1053
+ const regex = new RegExp(pattern.pattern.source, pattern.pattern.flags);
1054
+ let match;
1055
+ while ((match = regex.exec(content)) !== null) {
1056
+ const lineNumber = content.substring(0, match.index).split('\n').length;
1057
+ const lineContent = lines[lineNumber - 1]?.trim() || '';
1058
+ // Skip comments
1059
+ if ((0, file_classifier_1.isComment)(lineContent))
1060
+ continue;
1061
+ // Get surrounding context for mitigation checks
1062
+ const { context } = findToolDefinitionContext(content, lineNumber);
1063
+ // Check for mitigations
1064
+ let isMitigated = false;
1065
+ let isPartiallyMitigated = false;
1066
+ let description = pattern.description;
1067
+ // Check iteration limits
1068
+ if (hasIterationLimits(context)) {
1069
+ isPartiallyMitigated = true;
1070
+ description += ' (Iteration limits detected nearby.)';
1071
+ }
1072
+ // Check timeout configuration
1073
+ if (hasTimeoutConfigured(context)) {
1074
+ isPartiallyMitigated = true;
1075
+ description += ' (Timeout configured.)';
1076
+ }
1077
+ // Check human-in-the-loop
1078
+ if (hasHumanInLoop(context)) {
1079
+ isPartiallyMitigated = true;
1080
+ description += ' (Human-in-loop enabled.)';
1081
+ }
1082
+ // Check Docker for code execution patterns
1083
+ if (pattern.framework === 'crewai' || pattern.framework === 'autogen') {
1084
+ if (hasDockerConfigured(context)) {
1085
+ isMitigated = true;
1086
+ description += ' (Docker containerization detected.)';
1087
+ }
1088
+ }
1089
+ // Check budget limits
1090
+ if (hasBudgetLimits(context)) {
1091
+ isPartiallyMitigated = true;
1092
+ description += ' (Budget limits configured.)';
1093
+ }
1094
+ // Calculate severity
1095
+ let severity = pattern.baseSeverity;
1096
+ const isMCPSafe = isMCPFileWithSafePatterns(content, filePath);
1097
+ if (isMitigated) {
1098
+ severity = 'info';
1099
+ }
1100
+ else if (isTestFile) {
1101
+ severity = 'info';
1102
+ description += ' (In test file.)';
1103
+ }
1104
+ else if (isExample) {
1105
+ severity = 'info';
1106
+ description += ' (In example/demo directory.)';
1107
+ }
1108
+ else if (isLibrary) {
1109
+ severity = 'info';
1110
+ description += ' (Library code.)';
1111
+ }
1112
+ else if (isPartiallyMitigated) {
1113
+ // Downgrade if partial mitigations present
1114
+ if (severity === 'critical')
1115
+ severity = 'high';
1116
+ else if (severity === 'high')
1117
+ severity = 'medium';
1118
+ else if (severity === 'medium')
1119
+ severity = 'low';
1120
+ }
1121
+ // Skip fully mitigated or info-level in non-agent files
1122
+ if (isMitigated && severity === 'info')
1123
+ continue;
1124
+ vulnerabilities.push({
1125
+ id: `ai-agency-${filePath}-${lineNumber}-${pattern.name.replace(/\s+/g, '-')}`,
1126
+ filePath,
1127
+ lineNumber,
1128
+ lineContent,
1129
+ severity,
1130
+ category: 'ai_excessive_agency',
1131
+ title: pattern.name,
1132
+ description,
1133
+ suggestedFix: pattern.suggestedFix,
1134
+ confidence: severity === 'info' ? 'low' : 'medium',
1135
+ layer: 2,
1136
+ source: 'ai_code',
1137
+ requiresAIValidation: severity !== 'info' && severity !== 'low',
1138
+ baseConfidence: BASE_CONFIDENCE,
1139
+ });
1140
+ }
1141
+ }
1142
+ // Phase 5: Scan for LLM output flow patterns (Task 1)
1143
+ for (const pattern of LLM_OUTPUT_FLOW_PATTERNS) {
1144
+ const regex = new RegExp(pattern.pattern.source, pattern.pattern.flags);
1145
+ let match;
1146
+ while ((match = regex.exec(content)) !== null) {
1147
+ const lineNumber = content.substring(0, match.index).split('\n').length;
1148
+ const lineContent = lines[lineNumber - 1]?.trim() || '';
1149
+ // Skip comments
1150
+ if ((0, file_classifier_1.isComment)(lineContent))
1151
+ continue;
1152
+ // Get surrounding context
1153
+ const { context } = findToolDefinitionContext(content, lineNumber);
1154
+ // Check for validation/allowlist mitigations
1155
+ const hasValidation = /(?:allowlist|whitelist|ALLOWED_|validTools|VALID_TOOLS|allowedTools|validateTool|isValidTool|includes|has)\s*\(/i.test(context);
1156
+ const hasAllowlistCheck = /if\s*\(\s*!?\s*(?:ALLOWED|VALID|SAFE|permitted).*(?:includes|has|indexOf)/i.test(context);
1157
+ let description = pattern.description;
1158
+ let severity = pattern.baseSeverity;
1159
+ if (hasValidation || hasAllowlistCheck) {
1160
+ severity = severity === 'critical' ? 'medium' : 'low';
1161
+ description += ' (Validation/allowlist detected nearby - verify it covers this case.)';
1162
+ }
1163
+ if (isTestFile) {
1164
+ severity = 'info';
1165
+ description += ' (In test file.)';
1166
+ }
1167
+ else if (isExample) {
1168
+ severity = 'info';
1169
+ description += ' (In example/demo directory.)';
1170
+ }
1171
+ else if (isLibrary) {
1172
+ severity = 'info';
1173
+ description += ' (Library code.)';
1174
+ }
1175
+ vulnerabilities.push({
1176
+ id: `ai-llm-flow-${filePath}-${lineNumber}-${pattern.name.replace(/\s+/g, '-')}`,
1177
+ filePath,
1178
+ lineNumber,
1179
+ lineContent,
1180
+ severity,
1181
+ category: 'ai_excessive_agency',
1182
+ title: pattern.name,
1183
+ description,
1184
+ suggestedFix: pattern.suggestedFix,
1185
+ confidence: severity === 'critical' ? 'high' : 'medium',
1186
+ layer: 2,
1187
+ source: 'ai_code',
1188
+ requiresAIValidation: severity !== 'info',
1189
+ baseConfidence: BASE_CONFIDENCE,
1190
+ });
1191
+ }
1192
+ }
1193
+ // Phase 5: Scan for tool permission accumulation patterns (Task 2)
1194
+ for (const pattern of TOOL_ACCUMULATION_PATTERNS) {
1195
+ const regex = new RegExp(pattern.pattern.source, pattern.pattern.flags);
1196
+ let match;
1197
+ while ((match = regex.exec(content)) !== null) {
1198
+ const lineNumber = content.substring(0, match.index).split('\n').length;
1199
+ const lineContent = lines[lineNumber - 1]?.trim() || '';
1200
+ // Skip comments
1201
+ if ((0, file_classifier_1.isComment)(lineContent))
1202
+ continue;
1203
+ // Skip UI array building patterns (not actual AI tool registration)
1204
+ if (pattern.name === 'Tool array push without limit check') {
1205
+ // Check if this is in a selector or UI configuration builder
1206
+ const isUIPattern =
1207
+ // In selectors (zustand/redux pattern)
1208
+ /selectors?\.ts$/i.test(filePath) ||
1209
+ // In store configuration
1210
+ /store\/.*\/selectors/i.test(filePath) ||
1211
+ // Building manifest/config arrays
1212
+ /manifest\s*:/i.test(lineContent) ||
1213
+ /identifier\s*:/i.test(lineContent) ||
1214
+ // Map/forEach building UI arrays
1215
+ /\.map\s*\([^)]*=>\s*\{[\s\S]{0,100}tools\.push/i.test(content.substring(Math.max(0, match.index - 200), match.index + 100));
1216
+ if (isUIPattern) {
1217
+ continue; // Skip - this is building a UI configuration array
1218
+ }
1219
+ }
1220
+ // Get surrounding context
1221
+ const { context } = findToolDefinitionContext(content, lineNumber);
1222
+ // Check for limits and authorization
1223
+ const hasLimits = /(?:max|limit|MAX_|LIMIT_|\.length\s*[<>])/i.test(context);
1224
+ const hasAuthCheck = /(?:if\s*\(.*(?:auth|permission|role|isAdmin|canRegister)|throw.*(?:Unauthorized|Forbidden))/i.test(context);
1225
+ let description = pattern.description;
1226
+ let severity = pattern.baseSeverity;
1227
+ if (hasLimits) {
1228
+ severity = severity === 'critical' ? 'high' : severity === 'high' ? 'medium' : 'low';
1229
+ description += ' (Limit check detected nearby.)';
1230
+ }
1231
+ if (hasAuthCheck) {
1232
+ severity = severity === 'critical' ? 'high' : severity === 'high' ? 'medium' : 'low';
1233
+ description += ' (Authorization check detected.)';
1234
+ }
1235
+ if (isTestFile) {
1236
+ severity = 'info';
1237
+ description += ' (In test file.)';
1238
+ }
1239
+ else if (isExample) {
1240
+ severity = 'info';
1241
+ description += ' (In example/demo directory.)';
1242
+ }
1243
+ else if (isLibrary) {
1244
+ severity = 'info';
1245
+ description += ' (Library code.)';
1246
+ }
1247
+ vulnerabilities.push({
1248
+ id: `ai-tool-accum-${filePath}-${lineNumber}-${pattern.name.replace(/\s+/g, '-')}`,
1249
+ filePath,
1250
+ lineNumber,
1251
+ lineContent,
1252
+ severity,
1253
+ category: 'ai_excessive_agency',
1254
+ title: pattern.name,
1255
+ description,
1256
+ suggestedFix: pattern.suggestedFix,
1257
+ confidence: 'medium',
1258
+ layer: 2,
1259
+ source: 'ai_code',
1260
+ requiresAIValidation: severity !== 'info' && severity !== 'low',
1261
+ baseConfidence: BASE_CONFIDENCE,
1262
+ });
1263
+ }
1264
+ }
1265
+ // Phase 5: Scan for database write scoping patterns (Task 3)
1266
+ for (const pattern of DB_WRITE_SCOPING_PATTERNS) {
1267
+ const regex = new RegExp(pattern.pattern.source, pattern.pattern.flags);
1268
+ let match;
1269
+ while ((match = regex.exec(content)) !== null) {
1270
+ const lineNumber = content.substring(0, match.index).split('\n').length;
1271
+ const lineContent = lines[lineNumber - 1]?.trim() || '';
1272
+ // Skip comments
1273
+ if ((0, file_classifier_1.isComment)(lineContent))
1274
+ continue;
1275
+ // Get surrounding context
1276
+ const { context } = findToolDefinitionContext(content, lineNumber);
1277
+ // Check for user/tenant scoping
1278
+ const hasUserScoping = hasUserContextVerification(context);
1279
+ const hasTenantScoping = hasTenantContextVerification(context);
1280
+ // Skip if properly scoped
1281
+ if (hasUserScoping && hasTenantScoping)
1282
+ continue;
1283
+ let description = pattern.description;
1284
+ let severity = pattern.baseSeverity;
1285
+ if (hasUserScoping || hasTenantScoping) {
1286
+ severity = severity === 'high' ? 'medium' : 'low';
1287
+ description += hasUserScoping ? ' (User context detected.)' : ' (Tenant context detected.)';
1288
+ }
1289
+ if (isTestFile) {
1290
+ severity = 'info';
1291
+ description += ' (In test file.)';
1292
+ }
1293
+ else if (isExample) {
1294
+ severity = 'info';
1295
+ description += ' (In example/demo directory.)';
1296
+ }
1297
+ else if (isLibrary) {
1298
+ severity = 'info';
1299
+ description += ' (Library code.)';
1300
+ }
1301
+ vulnerabilities.push({
1302
+ id: `ai-db-scoping-${filePath}-${lineNumber}-${pattern.name.replace(/\s+/g, '-')}`,
1303
+ filePath,
1304
+ lineNumber,
1305
+ lineContent,
1306
+ severity,
1307
+ category: 'ai_excessive_agency',
1308
+ title: pattern.name,
1309
+ description,
1310
+ suggestedFix: pattern.suggestedFix,
1311
+ confidence: 'medium',
1312
+ layer: 2,
1313
+ source: 'ai_code',
1314
+ requiresAIValidation: severity !== 'info',
1315
+ baseConfidence: BASE_CONFIDENCE,
1316
+ });
1317
+ }
1318
+ }
1319
+ // Phase 5: Scan for recursive agent patterns (Task 4)
1320
+ for (const pattern of RECURSIVE_AGENT_PATTERNS) {
1321
+ const regex = new RegExp(pattern.pattern.source, pattern.pattern.flags);
1322
+ let match;
1323
+ while ((match = regex.exec(content)) !== null) {
1324
+ const lineNumber = content.substring(0, match.index).split('\n').length;
1325
+ const lineContent = lines[lineNumber - 1]?.trim() || '';
1326
+ // Skip comments
1327
+ if ((0, file_classifier_1.isComment)(lineContent))
1328
+ continue;
1329
+ // Skip CRUD/data operations that are NOT AI agent spawning
1330
+ // These are false positives in apps where "agent" means "chat assistant configuration"
1331
+ if (pattern.name === 'Agent spawns sub-agent without limit') {
1332
+ const crudPatterns = [
1333
+ // Service/SDK method calls - database CRUD for agent configurations
1334
+ /(?:service|Service|sdk|SDK|store|Store|runtime|Runtime)\.(?:create|get|update|delete)Agent/i,
1335
+ /\.agents\.createAgent/i, // sdk.agents.createAgent
1336
+ /agentService\.createAgent/i,
1337
+ /agentState\.createAgent/i,
1338
+ /marketSDK\.agents\.createAgent/i,
1339
+ // React event handlers creating UI entities
1340
+ /onClick\s*=\s*\{\s*\(\s*\)\s*=>\s*createAgent/i,
1341
+ // Store action patterns
1342
+ /await\s+(?:state|store)\w*\.createAgent/i,
1343
+ // Builder/Runtime patterns for UI
1344
+ /agentBuilder(?:Runtime)?\.createAgent/i,
1345
+ /groupAgentBuilderRuntime\.createAgent/i,
1346
+ ];
1347
+ if (crudPatterns.some(p => p.test(lineContent))) {
1348
+ continue; // Skip - this is a data CRUD operation, not AI agent spawning
1349
+ }
1350
+ }
1351
+ // Get surrounding context
1352
+ const { context } = findToolDefinitionContext(content, lineNumber);
1353
+ // Check for depth/count limits
1354
+ const hasDepthLimit = /(?:depth|level|recursion)\s*[<>]|MAX_DEPTH|maxDepth|max_depth/i.test(context);
1355
+ const hasCountLimit = /(?:count|iterations?)\s*[<>]|MAX_(?:AGENTS|TASKS|ITERATIONS)/i.test(context);
1356
+ let description = pattern.description;
1357
+ let severity = pattern.baseSeverity;
1358
+ if (hasDepthLimit || hasCountLimit) {
1359
+ severity = severity === 'high' ? 'medium' : 'low';
1360
+ description += hasDepthLimit ? ' (Depth limit detected.)' : ' (Count limit detected.)';
1361
+ }
1362
+ // Check for iteration/timeout limits
1363
+ if (hasIterationLimits(context) || hasTimeoutConfigured(context)) {
1364
+ severity = severity === 'high' ? 'medium' : severity === 'medium' ? 'low' : severity;
1365
+ description += ' (Iteration/timeout limits configured.)';
1366
+ }
1367
+ if (isTestFile) {
1368
+ severity = 'info';
1369
+ description += ' (In test file.)';
1370
+ }
1371
+ else if (isExample) {
1372
+ severity = 'info';
1373
+ description += ' (In example/demo directory.)';
1374
+ }
1375
+ else if (isLibrary) {
1376
+ severity = 'info';
1377
+ description += ' (Library code.)';
1378
+ }
1379
+ vulnerabilities.push({
1380
+ id: `ai-recursive-${filePath}-${lineNumber}-${pattern.name.replace(/\s+/g, '-')}`,
1381
+ filePath,
1382
+ lineNumber,
1383
+ lineContent,
1384
+ severity,
1385
+ category: 'ai_excessive_agency',
1386
+ title: pattern.name,
1387
+ description,
1388
+ suggestedFix: pattern.suggestedFix,
1389
+ confidence: 'medium',
1390
+ layer: 2,
1391
+ source: 'ai_code',
1392
+ requiresAIValidation: severity !== 'info' && severity !== 'low',
1393
+ baseConfidence: BASE_CONFIDENCE,
1394
+ });
1395
+ }
1396
+ }
1397
+ // Phase 6: Scan for tool parameter injection patterns (Task 1)
1398
+ for (const pattern of TOOL_PARAMETER_INJECTION_PATTERNS) {
1399
+ const regex = new RegExp(pattern.pattern.source, pattern.pattern.flags);
1400
+ let match;
1401
+ while ((match = regex.exec(content)) !== null) {
1402
+ const lineNumber = content.substring(0, match.index).split('\n').length;
1403
+ const lineContent = lines[lineNumber - 1]?.trim() || '';
1404
+ // Skip comments
1405
+ if ((0, file_classifier_1.isComment)(lineContent))
1406
+ continue;
1407
+ // Get surrounding context
1408
+ const { context } = findToolDefinitionContext(content, lineNumber);
1409
+ // Check for validation/schema patterns
1410
+ const hasValidation = /(?:zod|yup|joi|schema|validate|safeParse|\.parse\(|validateSchema)/i.test(context);
1411
+ const hasSanitization = /(?:sanitize|clean|escape|filter|strip)/i.test(context);
1412
+ let description = pattern.description;
1413
+ let severity = pattern.baseSeverity;
1414
+ if (hasValidation) {
1415
+ severity = 'low';
1416
+ description += ' (Schema validation detected nearby - verify it covers LLM output.)';
1417
+ }
1418
+ else if (hasSanitization) {
1419
+ severity = severity === 'critical' ? 'high' : severity === 'high' ? 'medium' : 'low';
1420
+ description += ' (Sanitization detected nearby.)';
1421
+ }
1422
+ if (isTestFile) {
1423
+ severity = 'info';
1424
+ description += ' (In test file.)';
1425
+ }
1426
+ else if (isExample) {
1427
+ severity = 'info';
1428
+ description += ' (In example/demo directory.)';
1429
+ }
1430
+ else if (isLibrary) {
1431
+ severity = 'info';
1432
+ description += ' (Library code.)';
1433
+ }
1434
+ vulnerabilities.push({
1435
+ id: `ai-tool-param-injection-${filePath}-${lineNumber}-${pattern.name.replace(/\s+/g, '-')}`,
1436
+ filePath,
1437
+ lineNumber,
1438
+ lineContent,
1439
+ severity,
1440
+ category: 'ai_excessive_agency',
1441
+ title: pattern.name,
1442
+ description,
1443
+ suggestedFix: pattern.suggestedFix,
1444
+ confidence: severity === 'critical' ? 'high' : 'medium',
1445
+ layer: 2,
1446
+ source: 'ai_code',
1447
+ requiresAIValidation: severity !== 'info' && severity !== 'low',
1448
+ baseConfidence: BASE_CONFIDENCE,
1449
+ });
1450
+ }
1451
+ }
1452
+ // Phase 6: Scan for tool error message injection patterns (Task 2)
1453
+ for (const pattern of TOOL_ERROR_INJECTION_PATTERNS) {
1454
+ const regex = new RegExp(pattern.pattern.source, pattern.pattern.flags);
1455
+ let match;
1456
+ while ((match = regex.exec(content)) !== null) {
1457
+ const lineNumber = content.substring(0, match.index).split('\n').length;
1458
+ const lineContent = lines[lineNumber - 1]?.trim() || '';
1459
+ // Skip comments
1460
+ if ((0, file_classifier_1.isComment)(lineContent))
1461
+ continue;
1462
+ // Get surrounding context
1463
+ const { context } = findToolDefinitionContext(content, lineNumber);
1464
+ // Check for error sanitization patterns
1465
+ const hasSanitizedError = /(?:sanitizeError|genericError|safeError|errorMessage\s*=\s*['"`])/i.test(context);
1466
+ const hasLogging = /(?:logger|console)\.\w+\s*\([^)]*(?:error|err|e)\)/i.test(context);
1467
+ let description = pattern.description;
1468
+ let severity = pattern.baseSeverity;
1469
+ if (hasSanitizedError) {
1470
+ severity = 'info';
1471
+ description += ' (Error sanitization detected.)';
1472
+ }
1473
+ else if (hasLogging) {
1474
+ severity = severity === 'high' ? 'medium' : 'low';
1475
+ description += ' (Server-side logging detected - verify error is sanitized in response.)';
1476
+ }
1477
+ if (isTestFile) {
1478
+ severity = 'info';
1479
+ description += ' (In test file.)';
1480
+ }
1481
+ else if (isExample) {
1482
+ severity = 'info';
1483
+ description += ' (In example/demo directory.)';
1484
+ }
1485
+ else if (isLibrary) {
1486
+ severity = 'info';
1487
+ description += ' (Library code.)';
1488
+ }
1489
+ vulnerabilities.push({
1490
+ id: `ai-tool-error-injection-${filePath}-${lineNumber}-${pattern.name.replace(/\s+/g, '-')}`,
1491
+ filePath,
1492
+ lineNumber,
1493
+ lineContent,
1494
+ severity,
1495
+ category: 'ai_excessive_agency',
1496
+ title: pattern.name,
1497
+ description,
1498
+ suggestedFix: pattern.suggestedFix,
1499
+ confidence: 'medium',
1500
+ layer: 2,
1501
+ source: 'ai_code',
1502
+ requiresAIValidation: severity !== 'info' && severity !== 'low',
1503
+ baseConfidence: BASE_CONFIDENCE,
1504
+ });
1505
+ }
1506
+ }
1507
+ return vulnerabilities;
1508
+ }
1509
+ //# sourceMappingURL=agent-tools.js.map