@oculum/scanner 1.0.9 → 1.0.11

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 (365) hide show
  1. package/dist/baseline/diff.d.ts +32 -0
  2. package/dist/baseline/diff.d.ts.map +1 -0
  3. package/dist/baseline/diff.js +119 -0
  4. package/dist/baseline/diff.js.map +1 -0
  5. package/dist/baseline/index.d.ts +9 -0
  6. package/dist/baseline/index.d.ts.map +1 -0
  7. package/dist/baseline/index.js +19 -0
  8. package/dist/baseline/index.js.map +1 -0
  9. package/dist/baseline/manager.d.ts +67 -0
  10. package/dist/baseline/manager.d.ts.map +1 -0
  11. package/dist/baseline/manager.js +180 -0
  12. package/dist/baseline/manager.js.map +1 -0
  13. package/dist/baseline/types.d.ts +91 -0
  14. package/dist/baseline/types.d.ts.map +1 -0
  15. package/dist/baseline/types.js +12 -0
  16. package/dist/baseline/types.js.map +1 -0
  17. package/dist/formatters/cli-terminal.d.ts +38 -0
  18. package/dist/formatters/cli-terminal.d.ts.map +1 -1
  19. package/dist/formatters/cli-terminal.js +365 -42
  20. package/dist/formatters/cli-terminal.js.map +1 -1
  21. package/dist/formatters/github-comment.d.ts +1 -1
  22. package/dist/formatters/github-comment.d.ts.map +1 -1
  23. package/dist/formatters/github-comment.js +75 -11
  24. package/dist/formatters/github-comment.js.map +1 -1
  25. package/dist/formatters/index.d.ts +1 -1
  26. package/dist/formatters/index.d.ts.map +1 -1
  27. package/dist/formatters/index.js +4 -1
  28. package/dist/formatters/index.js.map +1 -1
  29. package/dist/index.d.ts +7 -0
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +155 -16
  32. package/dist/index.js.map +1 -1
  33. package/dist/layer1/config-audit.d.ts.map +1 -1
  34. package/dist/layer1/config-audit.js +20 -3
  35. package/dist/layer1/config-audit.js.map +1 -1
  36. package/dist/layer1/config-mcp-audit.d.ts +20 -0
  37. package/dist/layer1/config-mcp-audit.d.ts.map +1 -0
  38. package/dist/layer1/config-mcp-audit.js +239 -0
  39. package/dist/layer1/config-mcp-audit.js.map +1 -0
  40. package/dist/layer1/index.d.ts +1 -0
  41. package/dist/layer1/index.d.ts.map +1 -1
  42. package/dist/layer1/index.js +9 -1
  43. package/dist/layer1/index.js.map +1 -1
  44. package/dist/layer2/ai-agent-tools.d.ts.map +1 -1
  45. package/dist/layer2/ai-agent-tools.js +303 -0
  46. package/dist/layer2/ai-agent-tools.js.map +1 -1
  47. package/dist/layer2/ai-endpoint-protection.d.ts.map +1 -1
  48. package/dist/layer2/ai-endpoint-protection.js +17 -3
  49. package/dist/layer2/ai-endpoint-protection.js.map +1 -1
  50. package/dist/layer2/ai-execution-sinks.d.ts.map +1 -1
  51. package/dist/layer2/ai-execution-sinks.js +462 -12
  52. package/dist/layer2/ai-execution-sinks.js.map +1 -1
  53. package/dist/layer2/ai-fingerprinting.d.ts.map +1 -1
  54. package/dist/layer2/ai-fingerprinting.js +3 -0
  55. package/dist/layer2/ai-fingerprinting.js.map +1 -1
  56. package/dist/layer2/ai-mcp-security.d.ts +17 -0
  57. package/dist/layer2/ai-mcp-security.d.ts.map +1 -0
  58. package/dist/layer2/ai-mcp-security.js +679 -0
  59. package/dist/layer2/ai-mcp-security.js.map +1 -0
  60. package/dist/layer2/ai-package-hallucination.d.ts +19 -0
  61. package/dist/layer2/ai-package-hallucination.d.ts.map +1 -0
  62. package/dist/layer2/ai-package-hallucination.js +696 -0
  63. package/dist/layer2/ai-package-hallucination.js.map +1 -0
  64. package/dist/layer2/ai-prompt-hygiene.d.ts.map +1 -1
  65. package/dist/layer2/ai-prompt-hygiene.js +495 -9
  66. package/dist/layer2/ai-prompt-hygiene.js.map +1 -1
  67. package/dist/layer2/ai-rag-safety.d.ts.map +1 -1
  68. package/dist/layer2/ai-rag-safety.js +372 -1
  69. package/dist/layer2/ai-rag-safety.js.map +1 -1
  70. package/dist/layer2/auth-antipatterns.d.ts.map +1 -1
  71. package/dist/layer2/auth-antipatterns.js +4 -0
  72. package/dist/layer2/auth-antipatterns.js.map +1 -1
  73. package/dist/layer2/byok-patterns.d.ts.map +1 -1
  74. package/dist/layer2/byok-patterns.js +3 -0
  75. package/dist/layer2/byok-patterns.js.map +1 -1
  76. package/dist/layer2/dangerous-functions/child-process.d.ts +16 -0
  77. package/dist/layer2/dangerous-functions/child-process.d.ts.map +1 -0
  78. package/dist/layer2/dangerous-functions/child-process.js +74 -0
  79. package/dist/layer2/dangerous-functions/child-process.js.map +1 -0
  80. package/dist/layer2/dangerous-functions/dom-xss.d.ts +29 -0
  81. package/dist/layer2/dangerous-functions/dom-xss.d.ts.map +1 -0
  82. package/dist/layer2/dangerous-functions/dom-xss.js +179 -0
  83. package/dist/layer2/dangerous-functions/dom-xss.js.map +1 -0
  84. package/dist/layer2/dangerous-functions/index.d.ts +13 -0
  85. package/dist/layer2/dangerous-functions/index.d.ts.map +1 -0
  86. package/dist/layer2/dangerous-functions/index.js +621 -0
  87. package/dist/layer2/dangerous-functions/index.js.map +1 -0
  88. package/dist/layer2/dangerous-functions/json-parse.d.ts +31 -0
  89. package/dist/layer2/dangerous-functions/json-parse.d.ts.map +1 -0
  90. package/dist/layer2/dangerous-functions/json-parse.js +319 -0
  91. package/dist/layer2/dangerous-functions/json-parse.js.map +1 -0
  92. package/dist/layer2/dangerous-functions/math-random.d.ts +61 -0
  93. package/dist/layer2/dangerous-functions/math-random.d.ts.map +1 -0
  94. package/dist/layer2/dangerous-functions/math-random.js +459 -0
  95. package/dist/layer2/dangerous-functions/math-random.js.map +1 -0
  96. package/dist/layer2/dangerous-functions/patterns.d.ts +21 -0
  97. package/dist/layer2/dangerous-functions/patterns.d.ts.map +1 -0
  98. package/dist/layer2/dangerous-functions/patterns.js +161 -0
  99. package/dist/layer2/dangerous-functions/patterns.js.map +1 -0
  100. package/dist/layer2/dangerous-functions/request-validation.d.ts +13 -0
  101. package/dist/layer2/dangerous-functions/request-validation.d.ts.map +1 -0
  102. package/dist/layer2/dangerous-functions/request-validation.js +119 -0
  103. package/dist/layer2/dangerous-functions/request-validation.js.map +1 -0
  104. package/dist/layer2/dangerous-functions/utils/control-flow.d.ts +23 -0
  105. package/dist/layer2/dangerous-functions/utils/control-flow.d.ts.map +1 -0
  106. package/dist/layer2/dangerous-functions/utils/control-flow.js +149 -0
  107. package/dist/layer2/dangerous-functions/utils/control-flow.js.map +1 -0
  108. package/dist/layer2/dangerous-functions/utils/helpers.d.ts +31 -0
  109. package/dist/layer2/dangerous-functions/utils/helpers.d.ts.map +1 -0
  110. package/dist/layer2/dangerous-functions/utils/helpers.js +124 -0
  111. package/dist/layer2/dangerous-functions/utils/helpers.js.map +1 -0
  112. package/dist/layer2/dangerous-functions/utils/index.d.ts +9 -0
  113. package/dist/layer2/dangerous-functions/utils/index.d.ts.map +1 -0
  114. package/dist/layer2/dangerous-functions/utils/index.js +23 -0
  115. package/dist/layer2/dangerous-functions/utils/index.js.map +1 -0
  116. package/dist/layer2/dangerous-functions/utils/schema-validation.d.ts +22 -0
  117. package/dist/layer2/dangerous-functions/utils/schema-validation.d.ts.map +1 -0
  118. package/dist/layer2/dangerous-functions/utils/schema-validation.js +89 -0
  119. package/dist/layer2/dangerous-functions/utils/schema-validation.js.map +1 -0
  120. package/dist/layer2/data-exposure.d.ts.map +1 -1
  121. package/dist/layer2/data-exposure.js +3 -0
  122. package/dist/layer2/data-exposure.js.map +1 -1
  123. package/dist/layer2/framework-checks.d.ts.map +1 -1
  124. package/dist/layer2/framework-checks.js +3 -0
  125. package/dist/layer2/framework-checks.js.map +1 -1
  126. package/dist/layer2/index.d.ts +3 -0
  127. package/dist/layer2/index.d.ts.map +1 -1
  128. package/dist/layer2/index.js +61 -2
  129. package/dist/layer2/index.js.map +1 -1
  130. package/dist/layer2/logic-gates.d.ts.map +1 -1
  131. package/dist/layer2/logic-gates.js +4 -0
  132. package/dist/layer2/logic-gates.js.map +1 -1
  133. package/dist/layer2/model-supply-chain.d.ts +20 -0
  134. package/dist/layer2/model-supply-chain.d.ts.map +1 -0
  135. package/dist/layer2/model-supply-chain.js +376 -0
  136. package/dist/layer2/model-supply-chain.js.map +1 -0
  137. package/dist/layer2/risky-imports.d.ts.map +1 -1
  138. package/dist/layer2/risky-imports.js +4 -0
  139. package/dist/layer2/risky-imports.js.map +1 -1
  140. package/dist/layer2/variables.d.ts.map +1 -1
  141. package/dist/layer2/variables.js +4 -0
  142. package/dist/layer2/variables.js.map +1 -1
  143. package/dist/layer3/anthropic/auto-dismiss.d.ts +24 -0
  144. package/dist/layer3/anthropic/auto-dismiss.d.ts.map +1 -0
  145. package/dist/layer3/anthropic/auto-dismiss.js +188 -0
  146. package/dist/layer3/anthropic/auto-dismiss.js.map +1 -0
  147. package/dist/layer3/anthropic/clients.d.ts +44 -0
  148. package/dist/layer3/anthropic/clients.d.ts.map +1 -0
  149. package/dist/layer3/anthropic/clients.js +81 -0
  150. package/dist/layer3/anthropic/clients.js.map +1 -0
  151. package/dist/layer3/anthropic/index.d.ts +41 -0
  152. package/dist/layer3/anthropic/index.d.ts.map +1 -0
  153. package/dist/layer3/anthropic/index.js +141 -0
  154. package/dist/layer3/anthropic/index.js.map +1 -0
  155. package/dist/layer3/anthropic/prompts/index.d.ts +8 -0
  156. package/dist/layer3/anthropic/prompts/index.d.ts.map +1 -0
  157. package/dist/layer3/anthropic/prompts/index.js +14 -0
  158. package/dist/layer3/anthropic/prompts/index.js.map +1 -0
  159. package/dist/layer3/anthropic/prompts/semantic-analysis.d.ts +15 -0
  160. package/dist/layer3/anthropic/prompts/semantic-analysis.d.ts.map +1 -0
  161. package/dist/layer3/anthropic/prompts/semantic-analysis.js +169 -0
  162. package/dist/layer3/anthropic/prompts/semantic-analysis.js.map +1 -0
  163. package/dist/layer3/anthropic/prompts/validation.d.ts +12 -0
  164. package/dist/layer3/anthropic/prompts/validation.d.ts.map +1 -0
  165. package/dist/layer3/anthropic/prompts/validation.js +421 -0
  166. package/dist/layer3/anthropic/prompts/validation.js.map +1 -0
  167. package/dist/layer3/anthropic/providers/anthropic.d.ts +21 -0
  168. package/dist/layer3/anthropic/providers/anthropic.d.ts.map +1 -0
  169. package/dist/layer3/anthropic/providers/anthropic.js +266 -0
  170. package/dist/layer3/anthropic/providers/anthropic.js.map +1 -0
  171. package/dist/layer3/anthropic/providers/index.d.ts +8 -0
  172. package/dist/layer3/anthropic/providers/index.d.ts.map +1 -0
  173. package/dist/layer3/anthropic/providers/index.js +15 -0
  174. package/dist/layer3/anthropic/providers/index.js.map +1 -0
  175. package/dist/layer3/anthropic/providers/openai.d.ts +18 -0
  176. package/dist/layer3/anthropic/providers/openai.d.ts.map +1 -0
  177. package/dist/layer3/anthropic/providers/openai.js +340 -0
  178. package/dist/layer3/anthropic/providers/openai.js.map +1 -0
  179. package/dist/layer3/anthropic/request-builder.d.ts +20 -0
  180. package/dist/layer3/anthropic/request-builder.d.ts.map +1 -0
  181. package/dist/layer3/anthropic/request-builder.js +134 -0
  182. package/dist/layer3/anthropic/request-builder.js.map +1 -0
  183. package/dist/layer3/anthropic/types.d.ts +88 -0
  184. package/dist/layer3/anthropic/types.d.ts.map +1 -0
  185. package/dist/layer3/anthropic/types.js +38 -0
  186. package/dist/layer3/anthropic/types.js.map +1 -0
  187. package/dist/layer3/anthropic/utils/index.d.ts +9 -0
  188. package/dist/layer3/anthropic/utils/index.d.ts.map +1 -0
  189. package/dist/layer3/anthropic/utils/index.js +24 -0
  190. package/dist/layer3/anthropic/utils/index.js.map +1 -0
  191. package/dist/layer3/anthropic/utils/path-helpers.d.ts +21 -0
  192. package/dist/layer3/anthropic/utils/path-helpers.d.ts.map +1 -0
  193. package/dist/layer3/anthropic/utils/path-helpers.js +69 -0
  194. package/dist/layer3/anthropic/utils/path-helpers.js.map +1 -0
  195. package/dist/layer3/anthropic/utils/response-parser.d.ts +40 -0
  196. package/dist/layer3/anthropic/utils/response-parser.d.ts.map +1 -0
  197. package/dist/layer3/anthropic/utils/response-parser.js +285 -0
  198. package/dist/layer3/anthropic/utils/response-parser.js.map +1 -0
  199. package/dist/layer3/anthropic/utils/retry.d.ts +15 -0
  200. package/dist/layer3/anthropic/utils/retry.d.ts.map +1 -0
  201. package/dist/layer3/anthropic/utils/retry.js +62 -0
  202. package/dist/layer3/anthropic/utils/retry.js.map +1 -0
  203. package/dist/layer3/index.d.ts +1 -0
  204. package/dist/layer3/index.d.ts.map +1 -1
  205. package/dist/layer3/index.js +16 -6
  206. package/dist/layer3/index.js.map +1 -1
  207. package/dist/layer3/osv-check.d.ts +75 -0
  208. package/dist/layer3/osv-check.d.ts.map +1 -0
  209. package/dist/layer3/osv-check.js +308 -0
  210. package/dist/layer3/osv-check.js.map +1 -0
  211. package/dist/rules/framework-fixes.d.ts +48 -0
  212. package/dist/rules/framework-fixes.d.ts.map +1 -0
  213. package/dist/rules/framework-fixes.js +439 -0
  214. package/dist/rules/framework-fixes.js.map +1 -0
  215. package/dist/rules/index.d.ts +8 -0
  216. package/dist/rules/index.d.ts.map +1 -0
  217. package/dist/rules/index.js +18 -0
  218. package/dist/rules/index.js.map +1 -0
  219. package/dist/rules/metadata.d.ts +43 -0
  220. package/dist/rules/metadata.d.ts.map +1 -0
  221. package/dist/rules/metadata.js +734 -0
  222. package/dist/rules/metadata.js.map +1 -0
  223. package/dist/suppression/config-loader.d.ts +74 -0
  224. package/dist/suppression/config-loader.d.ts.map +1 -0
  225. package/dist/suppression/config-loader.js +424 -0
  226. package/dist/suppression/config-loader.js.map +1 -0
  227. package/dist/suppression/hash.d.ts +48 -0
  228. package/dist/suppression/hash.d.ts.map +1 -0
  229. package/dist/suppression/hash.js +88 -0
  230. package/dist/suppression/hash.js.map +1 -0
  231. package/dist/suppression/index.d.ts +11 -0
  232. package/dist/suppression/index.d.ts.map +1 -0
  233. package/dist/suppression/index.js +39 -0
  234. package/dist/suppression/index.js.map +1 -0
  235. package/dist/suppression/inline-parser.d.ts +39 -0
  236. package/dist/suppression/inline-parser.d.ts.map +1 -0
  237. package/dist/suppression/inline-parser.js +218 -0
  238. package/dist/suppression/inline-parser.js.map +1 -0
  239. package/dist/suppression/manager.d.ts +94 -0
  240. package/dist/suppression/manager.d.ts.map +1 -0
  241. package/dist/suppression/manager.js +292 -0
  242. package/dist/suppression/manager.js.map +1 -0
  243. package/dist/suppression/types.d.ts +151 -0
  244. package/dist/suppression/types.d.ts.map +1 -0
  245. package/dist/suppression/types.js +28 -0
  246. package/dist/suppression/types.js.map +1 -0
  247. package/dist/tiers.d.ts +1 -1
  248. package/dist/tiers.d.ts.map +1 -1
  249. package/dist/tiers.js +27 -0
  250. package/dist/tiers.js.map +1 -1
  251. package/dist/types.d.ts +62 -1
  252. package/dist/types.d.ts.map +1 -1
  253. package/dist/types.js.map +1 -1
  254. package/dist/utils/context-helpers.d.ts +4 -0
  255. package/dist/utils/context-helpers.d.ts.map +1 -1
  256. package/dist/utils/context-helpers.js +13 -9
  257. package/dist/utils/context-helpers.js.map +1 -1
  258. package/package.json +4 -2
  259. package/src/__tests__/benchmark/fixtures/layer1/mcp-config-audit.json +31 -0
  260. package/src/__tests__/benchmark/fixtures/layer2/ai-execution-sinks.ts +1489 -82
  261. package/src/__tests__/benchmark/fixtures/layer2/ai-mcp-security.ts +495 -0
  262. package/src/__tests__/benchmark/fixtures/layer2/ai-package-hallucination.ts +255 -0
  263. package/src/__tests__/benchmark/fixtures/layer2/ai-prompt-hygiene.ts +300 -1
  264. package/src/__tests__/benchmark/fixtures/layer2/ai-rag-safety.ts +139 -0
  265. package/src/__tests__/benchmark/fixtures/layer2/byok-patterns.ts +7 -0
  266. package/src/__tests__/benchmark/fixtures/layer2/data-exposure.ts +63 -0
  267. package/src/__tests__/benchmark/fixtures/layer2/excessive-agency.ts +221 -0
  268. package/src/__tests__/benchmark/fixtures/layer2/index.ts +18 -0
  269. package/src/__tests__/benchmark/fixtures/layer2/model-supply-chain.ts +204 -0
  270. package/src/__tests__/benchmark/fixtures/layer2/phase1-enhancements.ts +157 -0
  271. package/src/__tests__/snapshots/__snapshots__/anthropic-validation-refactor.test.ts.snap +758 -0
  272. package/src/__tests__/snapshots/__snapshots__/dangerous-functions-refactor.test.ts.snap +503 -0
  273. package/src/__tests__/snapshots/anthropic-validation-refactor.test.ts +321 -0
  274. package/src/__tests__/snapshots/dangerous-functions-refactor.test.ts +439 -0
  275. package/src/baseline/__tests__/diff.test.ts +261 -0
  276. package/src/baseline/__tests__/manager.test.ts +225 -0
  277. package/src/baseline/diff.ts +135 -0
  278. package/src/baseline/index.ts +29 -0
  279. package/src/baseline/manager.ts +230 -0
  280. package/src/baseline/types.ts +97 -0
  281. package/src/formatters/cli-terminal.ts +444 -41
  282. package/src/formatters/github-comment.ts +79 -11
  283. package/src/formatters/index.ts +4 -0
  284. package/src/index.ts +197 -14
  285. package/src/layer1/config-audit.ts +24 -3
  286. package/src/layer1/config-mcp-audit.ts +276 -0
  287. package/src/layer1/index.ts +16 -6
  288. package/src/layer2/ai-agent-tools.ts +336 -0
  289. package/src/layer2/ai-endpoint-protection.ts +16 -3
  290. package/src/layer2/ai-execution-sinks.ts +516 -12
  291. package/src/layer2/ai-fingerprinting.ts +5 -1
  292. package/src/layer2/ai-mcp-security.ts +730 -0
  293. package/src/layer2/ai-package-hallucination.ts +791 -0
  294. package/src/layer2/ai-prompt-hygiene.ts +547 -9
  295. package/src/layer2/ai-rag-safety.ts +382 -3
  296. package/src/layer2/auth-antipatterns.ts +5 -0
  297. package/src/layer2/byok-patterns.ts +5 -1
  298. package/src/layer2/dangerous-functions/child-process.ts +98 -0
  299. package/src/layer2/dangerous-functions/dom-xss.ts +220 -0
  300. package/src/layer2/dangerous-functions/index.ts +949 -0
  301. package/src/layer2/dangerous-functions/json-parse.ts +385 -0
  302. package/src/layer2/dangerous-functions/math-random.ts +537 -0
  303. package/src/layer2/dangerous-functions/patterns.ts +174 -0
  304. package/src/layer2/dangerous-functions/request-validation.ts +145 -0
  305. package/src/layer2/dangerous-functions/utils/control-flow.ts +162 -0
  306. package/src/layer2/dangerous-functions/utils/helpers.ts +170 -0
  307. package/src/layer2/dangerous-functions/utils/index.ts +25 -0
  308. package/src/layer2/dangerous-functions/utils/schema-validation.ts +91 -0
  309. package/src/layer2/data-exposure.ts +5 -1
  310. package/src/layer2/framework-checks.ts +5 -0
  311. package/src/layer2/index.ts +63 -1
  312. package/src/layer2/logic-gates.ts +5 -0
  313. package/src/layer2/model-supply-chain.ts +456 -0
  314. package/src/layer2/risky-imports.ts +5 -0
  315. package/src/layer2/variables.ts +5 -0
  316. package/src/layer3/__tests__/osv-check.test.ts +384 -0
  317. package/src/layer3/anthropic/auto-dismiss.ts +212 -0
  318. package/src/layer3/anthropic/clients.ts +84 -0
  319. package/src/layer3/anthropic/index.ts +170 -0
  320. package/src/layer3/anthropic/prompts/index.ts +14 -0
  321. package/src/layer3/anthropic/prompts/semantic-analysis.ts +173 -0
  322. package/src/layer3/anthropic/prompts/validation.ts +419 -0
  323. package/src/layer3/anthropic/providers/anthropic.ts +310 -0
  324. package/src/layer3/anthropic/providers/index.ts +8 -0
  325. package/src/layer3/anthropic/providers/openai.ts +384 -0
  326. package/src/layer3/anthropic/request-builder.ts +150 -0
  327. package/src/layer3/anthropic/types.ts +148 -0
  328. package/src/layer3/anthropic/utils/index.ts +26 -0
  329. package/src/layer3/anthropic/utils/path-helpers.ts +68 -0
  330. package/src/layer3/anthropic/utils/response-parser.ts +322 -0
  331. package/src/layer3/anthropic/utils/retry.ts +75 -0
  332. package/src/layer3/index.ts +18 -5
  333. package/src/layer3/osv-check.ts +420 -0
  334. package/src/rules/__tests__/framework-fixes.test.ts +689 -0
  335. package/src/rules/__tests__/metadata.test.ts +218 -0
  336. package/src/rules/framework-fixes.ts +470 -0
  337. package/src/rules/index.ts +21 -0
  338. package/src/rules/metadata.ts +831 -0
  339. package/src/suppression/__tests__/config-loader.test.ts +382 -0
  340. package/src/suppression/__tests__/hash.test.ts +166 -0
  341. package/src/suppression/__tests__/inline-parser.test.ts +212 -0
  342. package/src/suppression/__tests__/manager.test.ts +415 -0
  343. package/src/suppression/config-loader.ts +462 -0
  344. package/src/suppression/hash.ts +95 -0
  345. package/src/suppression/index.ts +51 -0
  346. package/src/suppression/inline-parser.ts +273 -0
  347. package/src/suppression/manager.ts +379 -0
  348. package/src/suppression/types.ts +174 -0
  349. package/src/tiers.ts +36 -0
  350. package/src/types.ts +90 -0
  351. package/src/utils/context-helpers.ts +13 -9
  352. package/dist/layer2/dangerous-functions.d.ts +0 -7
  353. package/dist/layer2/dangerous-functions.d.ts.map +0 -1
  354. package/dist/layer2/dangerous-functions.js +0 -1701
  355. package/dist/layer2/dangerous-functions.js.map +0 -1
  356. package/dist/layer3/anthropic.d.ts +0 -87
  357. package/dist/layer3/anthropic.d.ts.map +0 -1
  358. package/dist/layer3/anthropic.js +0 -1948
  359. package/dist/layer3/anthropic.js.map +0 -1
  360. package/dist/layer3/openai.d.ts +0 -25
  361. package/dist/layer3/openai.d.ts.map +0 -1
  362. package/dist/layer3/openai.js +0 -238
  363. package/dist/layer3/openai.js.map +0 -1
  364. package/src/layer2/dangerous-functions.ts +0 -1940
  365. package/src/layer3/anthropic.ts +0 -2257
@@ -0,0 +1,170 @@
1
+ /**
2
+ * Layer 3: AI Semantic Analysis
3
+ *
4
+ * Uses Claude to perform deep security analysis including:
5
+ * - Taint analysis (data flow from sources to sinks)
6
+ * - Business logic flaw detection
7
+ * - Missing authorization checks
8
+ * - Cryptography validation
9
+ * - Data exposure detection
10
+ * - Framework-specific deep analysis
11
+ *
12
+ * Also provides high-context validation for Layer 1/2 findings.
13
+ */
14
+
15
+ import type { Vulnerability, ScanFile } from '../../types'
16
+ import type { ProjectContext } from '../../utils/project-context-builder'
17
+ import { buildProjectContext } from '../../utils/project-context-builder'
18
+ import type { ValidationStats, AIValidationResult, Layer3Context, AIFinding } from './types'
19
+ import { createInitialStats } from './types'
20
+ import { getAnthropicClient } from './clients'
21
+ import { parseAIResponse, getLineContent, validateSeverity, validateCategory } from './utils/response-parser'
22
+ import { buildAuthContextForPrompt, SECURITY_ANALYSIS_PROMPT } from './prompts/semantic-analysis'
23
+ import { validateWithOpenAI } from './providers/openai'
24
+ import { validateWithAnthropic } from './providers/anthropic'
25
+
26
+ // Re-export types and functions for backward compatibility
27
+ export type { ValidationStats, AIValidationResult, Layer3Context } from './types'
28
+ export { applyAutoDismissRules } from './auto-dismiss'
29
+
30
+ // ============================================================================
31
+ // Layer 3: Deep AI Analysis
32
+ // ============================================================================
33
+
34
+ /**
35
+ * Analyze a single file using AI for deep security analysis (Layer 3)
36
+ */
37
+ export async function analyzeWithAI(
38
+ file: ScanFile,
39
+ context?: Layer3Context
40
+ ): Promise<Vulnerability[]> {
41
+ const client = getAnthropicClient()
42
+
43
+ // Prepare the code with line numbers for reference
44
+ const numberedCode = file.content
45
+ .split('\n')
46
+ .map((line, i) => `${i + 1}: ${line}`)
47
+ .join('\n')
48
+
49
+ // Build auth context for the prompt
50
+ const authContext = buildAuthContextForPrompt(context)
51
+
52
+ const userMessage = `Analyze this ${file.language} file for security vulnerabilities:
53
+
54
+ File: ${file.path}${authContext}
55
+
56
+ \`\`\`${file.language}
57
+ ${numberedCode}
58
+ \`\`\`
59
+
60
+ Return ONLY a JSON array of findings.`
61
+
62
+ try {
63
+ const response = await client.messages.create({
64
+ model: 'claude-3-5-haiku-20241022',
65
+ max_tokens: 4096,
66
+ system: SECURITY_ANALYSIS_PROMPT,
67
+ messages: [
68
+ {
69
+ role: 'user',
70
+ content: userMessage,
71
+ },
72
+ ],
73
+ })
74
+
75
+ // Extract text content from response
76
+ const textContent = response.content.find((block: { type: string }) => block.type === 'text')
77
+ if (!textContent || textContent.type !== 'text') {
78
+ console.error('No text content in AI response')
79
+ return []
80
+ }
81
+
82
+ // Parse the JSON response
83
+ const findings = parseAIResponse(textContent.text)
84
+
85
+ // Convert to Vulnerability format
86
+ return findings.map((finding, index) => ({
87
+ id: `ai-${file.path}-${finding.lineNumber}-${index}`,
88
+ filePath: file.path,
89
+ lineNumber: finding.lineNumber,
90
+ lineContent: getLineContent(file.content, finding.lineNumber),
91
+ severity: finding.severity,
92
+ category: finding.category,
93
+ title: finding.title,
94
+ description: finding.description,
95
+ suggestedFix: finding.suggestedFix,
96
+ confidence: 'high' as const,
97
+ layer: 3 as const,
98
+ }))
99
+ } catch (error) {
100
+ console.error('AI analysis error:', error)
101
+ return []
102
+ }
103
+ }
104
+
105
+ /**
106
+ * Batch analyze multiple files using AI (Layer 3)
107
+ * Processes files in batches to avoid rate limits
108
+ */
109
+ export async function batchAnalyzeWithAI(
110
+ files: ScanFile[],
111
+ context?: Layer3Context,
112
+ maxConcurrent: number = 3
113
+ ): Promise<Vulnerability[]> {
114
+ const vulnerabilities: Vulnerability[] = []
115
+
116
+ // Process files in batches to avoid rate limits
117
+ for (let i = 0; i < files.length; i += maxConcurrent) {
118
+ const batch = files.slice(i, i + maxConcurrent)
119
+ const results = await Promise.all(
120
+ batch.map(file => analyzeWithAI(file, context).catch(err => {
121
+ console.error(`AI analysis failed for ${file.path}:`, err)
122
+ return []
123
+ }))
124
+ )
125
+ vulnerabilities.push(...results.flat())
126
+
127
+ // Small delay between batches to avoid rate limits
128
+ if (i + maxConcurrent < files.length) {
129
+ await new Promise(resolve => setTimeout(resolve, 500))
130
+ }
131
+ }
132
+
133
+ return vulnerabilities
134
+ }
135
+
136
+ // ============================================================================
137
+ // Layer 2.5: High-Context Validation
138
+ // ============================================================================
139
+
140
+ /**
141
+ * Validate Layer 1/2 findings using AI with HIGH-CONTEXT validation
142
+ *
143
+ * Key improvements over previous version:
144
+ * 1. Sends FULL FILE CONTENT (not just snippets) for better context
145
+ * 2. Includes PROJECT CONTEXT (auth patterns, data access, etc.)
146
+ * 3. Uses generalised rules from Section 3 of the security model
147
+ */
148
+ export async function validateFindingsWithAI(
149
+ findings: Vulnerability[],
150
+ files: ScanFile[],
151
+ projectContext?: ProjectContext,
152
+ onProgress?: (progress: { filesProcessed: number; totalFiles: number; status: string }) => void
153
+ ): Promise<AIValidationResult> {
154
+ // Initialize stats tracking
155
+ const stats: ValidationStats = createInitialStats(findings.length)
156
+
157
+ if (findings.length === 0) {
158
+ return { vulnerabilities: [], stats }
159
+ }
160
+
161
+ // Check for provider override (GPT-5-mini is default for 47% cost savings)
162
+ const aiProvider = process.env.AI_PROVIDER || 'openai'
163
+ if (aiProvider === 'anthropic') {
164
+ console.log('[AI Validation] Using Anthropic provider (Claude 3.5 Haiku)')
165
+ return validateWithAnthropic(findings, files, projectContext, stats, onProgress)
166
+ } else {
167
+ console.log('[AI Validation] Using OpenAI provider (GPT-5-mini)')
168
+ return validateWithOpenAI(findings, files, projectContext, stats)
169
+ }
170
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Prompts Index
3
+ *
4
+ * Re-exports all prompt templates and helpers.
5
+ */
6
+
7
+ export {
8
+ SECURITY_ANALYSIS_PROMPT,
9
+ buildAuthContextForPrompt,
10
+ } from './semantic-analysis'
11
+
12
+ export {
13
+ HIGH_CONTEXT_VALIDATION_PROMPT,
14
+ } from './validation'
@@ -0,0 +1,173 @@
1
+ /**
2
+ * Security Analysis Prompt (Layer 3)
3
+ *
4
+ * System prompt for deep semantic security analysis using AI.
5
+ */
6
+
7
+ import type { Layer3Context } from '../types'
8
+
9
+ // ============================================================================
10
+ // Security Analysis Prompt
11
+ // ============================================================================
12
+
13
+ /**
14
+ * System prompt for security analysis
15
+ */
16
+ export const SECURITY_ANALYSIS_PROMPT = `You are an expert security code reviewer. Analyze the provided code for security vulnerabilities.
17
+
18
+ Focus on these specific vulnerability types:
19
+
20
+ 1. **Taint Analysis (Data Flow)**
21
+ - Track user input from sources (req.query, req.params, req.body, searchParams, URL parameters)
22
+ - To dangerous sinks (eval, dangerouslySetInnerHTML, exec, SQL queries, file operations)
23
+ - Flag any path where untrusted data reaches a dangerous function without sanitization
24
+
25
+ 2. **SQL Injection**
26
+ - String concatenation in SQL queries
27
+ - Template literals with user input in queries
28
+ - Missing parameterized queries
29
+
30
+ 3. **XSS (Cross-Site Scripting)**
31
+ - User input rendered without escaping
32
+ - dangerouslySetInnerHTML with user data
33
+ - innerHTML assignments
34
+ - NOTE: React/Next.js JSX automatically escapes content, so {variable} in JSX is NOT XSS
35
+
36
+ 4. **Command Injection**
37
+ - exec, spawn, execSync with user input
38
+ - Shell command construction with variables
39
+
40
+ 5. **Missing Authorization**
41
+ - API routes that modify data without auth checks
42
+ - Database writes in GET handlers
43
+ - Missing permission checks before sensitive operations
44
+
45
+ 6. **Insecure Deserialization**
46
+ - JSON.parse on untrusted data without validation
47
+ - eval of serialized data
48
+
49
+ 7. **Cryptography Validation**
50
+ - Weak algorithms: MD5 (for security), SHA1 (for security), DES, RC4
51
+ - Insecure random: Math.random() for tokens/keys/secrets
52
+ - Hardcoded encryption keys or IVs (not from env vars)
53
+ - ECB mode usage (patterns indicate cipher mode)
54
+ - Low iteration counts for PBKDF2 (< 10000)
55
+ - Short key lengths (< 256 bits for symmetric)
56
+ - Missing salt for password hashing
57
+ - createCipher() instead of createCipheriv()
58
+
59
+ 8. **Data Exposure Detection**
60
+ - Logging sensitive data: console.log with passwords, tokens, secrets, API keys
61
+ - Stack traces exposed to clients: err.stack in response
62
+ - Returning entire user objects (may include password hash)
63
+ - Debug endpoints left in code: /debug, /test, /_internal routes
64
+ - Verbose error messages exposing internal details
65
+ - Sensitive data in error responses
66
+
67
+ 9. **Framework-Specific Security**
68
+
69
+ **Next.js:**
70
+ - Server actions ('use server') without authentication
71
+ - Client components ('use client') accessing non-NEXT_PUBLIC_ env vars
72
+ - Middleware that returns NextResponse.next() without auth checks
73
+ - getServerSideProps without session validation
74
+ - Exposed API routes without rate limiting
75
+
76
+ **React:**
77
+ - Sensitive data stored in useState (visible in devtools)
78
+ - dangerouslySetInnerHTML with props/state
79
+ - useEffect making authenticated API calls without token validation
80
+
81
+ **Express:**
82
+ - Missing helmet() middleware for security headers
83
+ - CORS with origin: "*" in production
84
+ - Missing body-parser limits (DoS risk)
85
+ - Trust proxy without verification
86
+ - Error handlers exposing stack traces
87
+
88
+ IMPORTANT - DO NOT FLAG THESE AS VULNERABILITIES (common false positives):
89
+
90
+ **Framework Patterns (Safe by Design):**
91
+ - Next.js middleware using request.url for redirects (standard pattern)
92
+ - React/Next.js JSX rendering variables like {user.name} (auto-escaped by React)
93
+ - Supabase/Firebase client creation with NEXT_PUBLIC_ environment variables
94
+ - Using headers().get('host') in Next.js server actions
95
+
96
+ **Data Handling (Low Risk):**
97
+ - JSON.parse on data from YOUR OWN database (the app wrote it, it's trusted). Do NOT report this as a vulnerability. At most, you may mention an info-level robustness note if there is no error handling, but generally you should omit it.
98
+ - JSON.parse on localStorage data (same-origin, XSS is a separate issue). This is also not a security vulnerability. At most, you may suggest an info-level robustness improvement, and usually it is not worth mentioning.
99
+ - Passing user's own data to external APIs (user embedding their own content).
100
+ - Error messages that use error.message in catch blocks or are returned to the client as a generic error string are standard error handling. Treat them as LOW/INFO hardening at most, and DO NOT mark them as medium/high unless the message clearly includes credentials, secrets, or full stack traces.
101
+ - Generic configuration or feature messages like "OpenAI API key not configured" or "service disabled" are operational information, not security vulnerabilities. Treat them as info at most, or ignore them.
102
+
103
+ **Authentication Patterns (Context Matters):**
104
+ - Internal server-side functions only called from trusted code paths (OAuth callbacks, etc.)
105
+ - Functions with userId parameters called with session.user.id from authenticated contexts
106
+ - Service role keys used in server-side code with proper auth checks elsewhere
107
+ - API routes that call getCurrentUserId() and use the result (the auth check IS the userId call)
108
+
109
+ **BYOK (Bring Your Own Key) Patterns:**
110
+ - User-provided API keys in BYOK mode are INTENTIONAL - the user wants to use their own key
111
+ - This is a feature, not a vulnerability - don't flag it unless there's actual abuse potential
112
+ - When a BYOK key is only used TRANSIENTLY in memory for a single provider call (and is never logged or stored), and the route is authenticated, do NOT report this as a medium/high vulnerability. At most, you may surface a low/info note reminding the developer not to log or persist keys.
113
+ - Frontend components sending a BYOK key to an authenticated backend endpoint for one-shot use are expected behavior, not a vulnerability. Do NOT flag these as data_exposure or dangerous_function unless the key is logged, stored, or echoed back to the client.
114
+ - Only raise medium/high BYOK findings when keys are clearly stored (e.g., written to a database or long-term logs), logged in plaintext, or accepted by unauthenticated endpoints that attackers could abuse at scale.
115
+
116
+ **What TO Flag (Real Vulnerabilities):**
117
+ - SQL string concatenation with user input
118
+ - eval() or Function() with user-controlled strings
119
+ - Missing auth checks where sensitive data could be accessed by wrong user
120
+ - Actual hardcoded secrets (real API keys, not env var references)
121
+ - Command injection (exec/spawn with user input)
122
+
123
+ Respond ONLY with a JSON array of findings. Each finding must have:
124
+ {
125
+ "lineNumber": <number>,
126
+ "severity": "critical" | "high" | "medium" | "low",
127
+ "category": "sql_injection" | "xss" | "command_injection" | "missing_auth" | "dangerous_function",
128
+ "title": "<short title>",
129
+ "description": "<detailed explanation of the vulnerability>",
130
+ "suggestedFix": "<how to fix it>"
131
+ }
132
+
133
+ If no vulnerabilities are found, return an empty array: []
134
+
135
+ CRITICAL: Only report REAL vulnerabilities with HIGH confidence. Be conservative - it's better to miss a low-confidence issue than to report false positives. The code is likely using modern frameworks with built-in protections.`
136
+
137
+ // ============================================================================
138
+ // Auth Context Builder
139
+ // ============================================================================
140
+
141
+ /**
142
+ * Build auth context string for AI prompt
143
+ */
144
+ export function buildAuthContextForPrompt(ctx?: Layer3Context): string {
145
+ if (!ctx) return ''
146
+
147
+ const parts: string[] = []
148
+
149
+ if (ctx.middlewareConfig?.hasAuthMiddleware) {
150
+ parts.push(`**IMPORTANT AUTH CONTEXT**: This project uses ${ctx.middlewareConfig.authType || 'auth'} middleware.`)
151
+ if (ctx.middlewareConfig.protectedPaths.length > 0) {
152
+ parts.push(`Protected paths: ${ctx.middlewareConfig.protectedPaths.join(', ')}`)
153
+ } else {
154
+ parts.push('All /api/** routes are protected by default.')
155
+ }
156
+ parts.push('Routes under these paths are ALREADY AUTHENTICATED - do NOT flag them as "missing auth".')
157
+ parts.push('Client components calling these protected API routes are also safe - the backend handles auth.')
158
+ }
159
+
160
+ if (ctx.authHelpers?.hasThrowingHelpers) {
161
+ parts.push('')
162
+ parts.push('**AUTH HELPER FUNCTIONS**: This project uses throwing auth helpers that guarantee authenticated context:')
163
+ parts.push(ctx.authHelpers.summary)
164
+ parts.push('Code after these helper calls is GUARANTEED to be authenticated. Do NOT flag "missing auth" after these calls.')
165
+ }
166
+
167
+ if (ctx.additionalContext) {
168
+ parts.push('')
169
+ parts.push(ctx.additionalContext)
170
+ }
171
+
172
+ return parts.length > 0 ? '\n\n' + parts.join('\n') : ''
173
+ }