@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,255 @@
1
+ /**
2
+ * AI Package Hallucination Test Fixtures
3
+ * Tests for detecting AI-hallucinated/fake package names in dependencies
4
+ *
5
+ * Background: USENIX research shows ~20% of AI-generated code references
6
+ * packages that don't exist, creating supply chain attack vectors.
7
+ */
8
+
9
+ import type { TestGroup } from '../../types'
10
+
11
+ export const aiPackageHallucinationTests: TestGroup = {
12
+ name: 'AI Package Hallucination Detection',
13
+ tier: 'A',
14
+ layer: 2,
15
+ description: 'Detection of AI-hallucinated and potentially fake package names in imports and dependencies',
16
+
17
+ truePositives: [
18
+ {
19
+ name: 'Package Hallucination - True Positives (Known Fakes)',
20
+ expectFindings: true,
21
+ expectedCategories: ['ai_package_hallucination'],
22
+ description: 'Known hallucinated packages that MUST be detected',
23
+ file: {
24
+ path: 'src/utils/helpers.ts',
25
+ content: `
26
+ // Known AI-hallucinated package names (verified fakes from research)
27
+ import { Chart } from 'react-charts' // Fake - react-chartjs-2 or recharts are real
28
+ import { MongoClient } from 'mongo-client' // Fake - mongodb is real
29
+ import { PostgresClient } from 'postgres-client' // Fake - pg is real
30
+ import fastJson from 'fast-json' // Fake - fast-json-stringify or ajv are real
31
+ import helpers from 'node-helpers' // Fake - doesn't exist
32
+
33
+ // Import with destructuring
34
+ const { utils } = require('easy-utils') // Fake
35
+ const tools = require('simple-tools') // Fake
36
+
37
+ // Dynamic import
38
+ const csvParser = await import('csv-parser-pro') // Fake - csv-parser or papaparse are real
39
+ `,
40
+ language: 'typescript',
41
+ size: 600,
42
+ },
43
+ },
44
+ {
45
+ name: 'Package Hallucination - True Positives (Suspicious Patterns)',
46
+ expectFindings: true,
47
+ expectedCategories: ['ai_package_hallucination'],
48
+ description: 'Suspicious package naming patterns that suggest hallucination',
49
+ file: {
50
+ path: 'src/api/services.ts',
51
+ content: `
52
+ // Unscoped generic utility names (frequently hallucinated)
53
+ import utils from 'utils' // Too generic - likely hallucinated
54
+ import helpers from 'helpers' // Too generic - likely hallucinated
55
+ import common from 'common' // Too generic - likely hallucinated
56
+ import tools from 'tools' // Too generic - likely hallucinated
57
+
58
+ // easy-* pattern (frequently hallucinated)
59
+ import easyConfig from 'easy-config' // Suspicious pattern
60
+ import easyDb from 'easy-database' // Suspicious pattern
61
+ import easyAuth from 'easy-auth' // Suspicious pattern
62
+
63
+ // simple-* pattern (frequently hallucinated)
64
+ import simpleApi from 'simple-api' // Suspicious pattern
65
+ import simpleServer from 'simple-server' // Suspicious pattern
66
+ import simpleCache from 'simple-cache' // Suspicious pattern
67
+
68
+ // node-* patterns for non-core modules (frequently hallucinated)
69
+ import nodeUtils from 'node-utils' // Suspicious - not a core module
70
+ import nodeHelpers from 'node-helpers' // Suspicious - not a core module
71
+
72
+ // fast-* patterns without real packages
73
+ import fastParser from 'fast-parser' // Suspicious pattern
74
+ import fastValidator from 'fast-validator' // Suspicious pattern
75
+ `,
76
+ language: 'typescript',
77
+ size: 900,
78
+ },
79
+ },
80
+ {
81
+ name: 'Package Hallucination - True Positives (package.json)',
82
+ expectFindings: true,
83
+ expectedCategories: ['ai_package_hallucination'],
84
+ description: 'Hallucinated packages in package.json dependencies',
85
+ file: {
86
+ path: 'package.json',
87
+ content: `{
88
+ "name": "my-app",
89
+ "dependencies": {
90
+ "react": "^18.0.0",
91
+ "react-charts": "^1.0.0",
92
+ "mongo-client": "^3.0.0",
93
+ "easy-config": "^2.0.0",
94
+ "utils": "^1.0.0",
95
+ "helpers": "^1.0.0",
96
+ "node-helpers": "^1.0.0"
97
+ },
98
+ "devDependencies": {
99
+ "simple-test": "^1.0.0",
100
+ "fast-bundler": "^1.0.0"
101
+ }
102
+ }`,
103
+ language: 'json',
104
+ size: 400,
105
+ },
106
+ },
107
+ {
108
+ name: 'Package Hallucination - True Positives (requirements.txt)',
109
+ expectFindings: true,
110
+ expectedCategories: ['ai_package_hallucination'],
111
+ description: 'Hallucinated packages in Python requirements',
112
+ file: {
113
+ path: 'requirements.txt',
114
+ content: `# Real packages
115
+ flask==2.0.0
116
+ requests==2.28.0
117
+
118
+ # Likely hallucinated packages
119
+ easy-flask==1.0.0
120
+ simple-api==1.0.0
121
+ fast-db==2.0.0
122
+ python-helpers==1.0.0
123
+ utils==1.0.0
124
+ common==1.0.0
125
+ `,
126
+ language: 'text',
127
+ size: 250,
128
+ },
129
+ },
130
+ ],
131
+
132
+ falseNegatives: [
133
+ {
134
+ name: 'Package Hallucination - False Negatives (Real Packages)',
135
+ expectFindings: false,
136
+ description: 'Real, well-known packages that should NOT be flagged',
137
+ allowedInfoFindings: [
138
+ {
139
+ category: 'suspicious_package',
140
+ maxCount: 2,
141
+ reason: 'Some real packages may trigger info-level findings from risky-imports detector',
142
+ },
143
+ {
144
+ category: 'ai_package_hallucination',
145
+ maxCount: 1,
146
+ reason: 'Edge cases may generate info-level findings',
147
+ },
148
+ ],
149
+ file: {
150
+ path: 'src/app/real-packages.ts',
151
+ content: `
152
+ // Popular, well-known real packages - SHOULD NOT FLAG
153
+ import React from 'react'
154
+ import { useState } from 'react'
155
+ import express from 'express'
156
+ import axios from 'axios'
157
+ import lodash from 'lodash'
158
+ import { z } from 'zod'
159
+ import dayjs from 'dayjs'
160
+ import { MongoClient } from 'mongodb' // Real (not 'mongo-client')
161
+ import pg from 'pg' // Real postgres client
162
+ import Fastify from 'fastify' // Real
163
+ import csvParser from 'csv-parser' // Real (not 'csv-parser-pro')
164
+
165
+ // Scoped packages are generally real
166
+ import { Hono } from '@hono/hono'
167
+ import { createClient } from '@supabase/supabase-js'
168
+ import { OpenAI } from 'openai'
169
+ import Anthropic from '@anthropic-ai/sdk'
170
+ import { PrismaClient } from '@prisma/client'
171
+
172
+ // These are real 'simple-' packages that exist
173
+ import SimpleSchema from 'simpl-schema' // Real package
174
+ import simpleGit from 'simple-git' // Real package (has >10M weekly downloads)
175
+
176
+ // These are real 'fast-' packages that exist
177
+ import fastJson from 'fast-json-stringify' // Real package
178
+ import fastify from 'fastify' // Real package
179
+ import fastGlob from 'fast-glob' // Real package
180
+
181
+ // Real utility packages with specific names
182
+ import _ from 'underscore'
183
+ import __ from 'radash'
184
+ import clsx from 'clsx'
185
+ import nanoid from 'nanoid'
186
+ `,
187
+ language: 'typescript',
188
+ size: 1000,
189
+ },
190
+ },
191
+ {
192
+ name: 'Package Hallucination - False Negatives (Internal/Monorepo)',
193
+ expectFindings: false,
194
+ description: 'Internal monorepo packages that should NOT be flagged',
195
+ file: {
196
+ path: 'apps/web/src/index.ts',
197
+ content: `
198
+ // Internal monorepo packages - these are workspace packages, not external
199
+ import { scanner } from '@oculum/scanner'
200
+ import { shared } from '@oculum/shared'
201
+ import { Button } from '@mycompany/ui'
202
+ import { utils } from '@internal/utils' // Scoped internal is fine
203
+
204
+ // Relative imports should never be flagged
205
+ import { helper } from './utils'
206
+ import { common } from '../shared/common'
207
+ import api from '../../api'
208
+
209
+ // Aliased paths should not be flagged
210
+ import { config } from '@/config'
211
+ import { utils } from '~/utils'
212
+ import { helpers } from '#utils/helpers'
213
+ `,
214
+ language: 'typescript',
215
+ size: 500,
216
+ },
217
+ },
218
+ {
219
+ name: 'Package Hallucination - False Negatives (Test Files)',
220
+ expectFindings: false,
221
+ description: 'Test files may use mocks that should be downgraded',
222
+ allowedInfoFindings: [
223
+ {
224
+ category: 'ai_package_hallucination',
225
+ maxCount: 3,
226
+ reason: 'Test file mock packages may generate info-level findings',
227
+ },
228
+ ],
229
+ file: {
230
+ path: 'src/__tests__/mocks/packages.test.ts',
231
+ content: `
232
+ // Test mocks - these might look suspicious but are test-only
233
+ import mockUtils from 'utils'
234
+ import mockHelpers from 'helpers'
235
+
236
+ jest.mock('utils', () => ({
237
+ format: jest.fn()
238
+ }))
239
+
240
+ jest.mock('helpers', () => ({
241
+ parse: jest.fn()
242
+ }))
243
+
244
+ describe('mock tests', () => {
245
+ it('should work', () => {
246
+ expect(mockUtils).toBeDefined()
247
+ })
248
+ })
249
+ `,
250
+ language: 'typescript',
251
+ size: 400,
252
+ },
253
+ },
254
+ ],
255
+ }
@@ -10,7 +10,7 @@ export const aiPromptHygieneTests: TestGroup = {
10
10
  tier: 'B',
11
11
  layer: 2,
12
12
  description: 'Detection of prompt injection vulnerabilities and unsafe prompt practices',
13
-
13
+
14
14
  truePositives: [
15
15
  {
16
16
  name: 'AI Prompt Hygiene - True Positives',
@@ -87,6 +87,204 @@ export async function concatenatedPrompt(name: string, task: string) {
87
87
  size: 1600,
88
88
  },
89
89
  },
90
+ // ========== NEW: Secrets in Prompts True Positives ==========
91
+ {
92
+ name: 'Secrets in Prompts - Provider Tokens',
93
+ expectFindings: true,
94
+ expectedCategories: ['hardcoded_secret'],
95
+ description: 'Various provider API keys/tokens in LLM prompt code that MUST be detected',
96
+ file: {
97
+ path: 'src/api/ai/secrets-in-prompts.ts',
98
+ content: `
99
+ import OpenAI from 'openai'
100
+ import Anthropic from '@anthropic-ai/sdk'
101
+
102
+ const openai = new OpenAI()
103
+ const anthropic = new Anthropic()
104
+
105
+ // 1. OpenAI API key in prompt context - CRITICAL
106
+ export async function openaiKeyInPrompt() {
107
+ const apiKey = "sk-1234567890abcdefghijklmnopqrstuvwxyz"
108
+ return openai.chat.completions.create({
109
+ model: 'gpt-4',
110
+ messages: [
111
+ { role: 'system', content: \`Use API key \${apiKey} to call the service\` }
112
+ ]
113
+ })
114
+ }
115
+
116
+ // 2. GitHub token in prompt - CRITICAL
117
+ export async function githubTokenInPrompt() {
118
+ const token = "ghp_abcdefghijklmnopqrstuvwxyz1234567890"
119
+ return openai.chat.completions.create({
120
+ model: 'gpt-4',
121
+ messages: [
122
+ { role: 'system', content: \`Access the repo using token: \${token}\` }
123
+ ]
124
+ })
125
+ }
126
+
127
+ // 3. Stripe key in prompt - CRITICAL
128
+ export async function stripeKeyInPrompt() {
129
+ const stripeKey = "sk_live_1234567890abcdefghijklmnop"
130
+ return openai.chat.completions.create({
131
+ model: 'gpt-4',
132
+ messages: [
133
+ { role: 'system', content: \`Process payment with Stripe key: \${stripeKey}\` }
134
+ ]
135
+ })
136
+ }
137
+
138
+ // 4. AWS credentials in prompt - CRITICAL
139
+ export async function awsCredentialsInPrompt() {
140
+ const awsKey = "AKIAIOSFODNN7EXAMPLE"
141
+ return openai.chat.completions.create({
142
+ model: 'gpt-4',
143
+ messages: [
144
+ { role: 'system', content: \`AWS access key: \${awsKey}\` }
145
+ ]
146
+ })
147
+ }
148
+
149
+ // 5. Slack token in prompt - CRITICAL
150
+ export async function slackTokenInPrompt() {
151
+ const slackToken = "xoxb-123456789012-1234567890123-abcdefghijklmnopqrstuvwx"
152
+ return anthropic.messages.create({
153
+ model: 'claude-3-opus-20240229',
154
+ messages: [
155
+ { role: 'user', content: \`Post to Slack using token: \${slackToken}\` }
156
+ ],
157
+ max_tokens: 1024
158
+ })
159
+ }
160
+
161
+ // 6. SendGrid key in prompt - CRITICAL
162
+ export async function sendgridKeyInPrompt() {
163
+ const sendgridKey = "SG.abcdefghijklmnopqrstuv.wxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789012"
164
+ return openai.chat.completions.create({
165
+ model: 'gpt-4',
166
+ messages: [
167
+ { role: 'system', content: \`Send email using SendGrid: \${sendgridKey}\` }
168
+ ]
169
+ })
170
+ }
171
+
172
+ // 7. Database URL with credentials - CRITICAL
173
+ export async function dbUrlInPrompt() {
174
+ const dbUrl = "postgres://admin:secretpassword123@db.example.com:5432/mydb"
175
+ return openai.chat.completions.create({
176
+ model: 'gpt-4',
177
+ messages: [
178
+ { role: 'system', content: \`Connect to database: \${dbUrl}\` }
179
+ ]
180
+ })
181
+ }
182
+
183
+ // 8. JWT token in prompt - HIGH
184
+ export async function jwtInPrompt() {
185
+ const jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
186
+ return openai.chat.completions.create({
187
+ model: 'gpt-4',
188
+ messages: [
189
+ { role: 'system', content: \`User session: \${jwt}\` }
190
+ ]
191
+ })
192
+ }
193
+
194
+ // 9. Private key in prompt - CRITICAL
195
+ export async function privateKeyInPrompt() {
196
+ const privateKey = \`-----BEGIN RSA PRIVATE KEY-----
197
+ MIIEowIBAAKCAQEA0Z3Vx...
198
+ -----END RSA PRIVATE KEY-----\`
199
+ return openai.chat.completions.create({
200
+ model: 'gpt-4',
201
+ messages: [
202
+ { role: 'system', content: \`Sign with key: \${privateKey}\` }
203
+ ]
204
+ })
205
+ }
206
+
207
+ // 10. HuggingFace token - CRITICAL
208
+ export async function hfTokenInPrompt() {
209
+ const hfToken = "hf_abcdefghijklmnopqrstuvwxyz1234567890"
210
+ return openai.chat.completions.create({
211
+ model: 'gpt-4',
212
+ messages: [
213
+ { role: 'system', content: \`Download model with HF token: \${hfToken}\` }
214
+ ]
215
+ })
216
+ }
217
+ `,
218
+ language: 'typescript',
219
+ size: 3500,
220
+ },
221
+ },
222
+ // ========== Variable Indirection - Secrets flowing to prompts ==========
223
+ {
224
+ name: 'Secrets in Prompts - Variable Flow',
225
+ expectFindings: true,
226
+ expectedCategories: ['hardcoded_secret'],
227
+ description: 'Secrets assigned to variables that flow into prompts',
228
+ file: {
229
+ path: 'src/api/ai/secrets-variable-flow.ts',
230
+ content: `
231
+ import OpenAI from 'openai'
232
+
233
+ const openai = new OpenAI()
234
+
235
+ // Secret assigned to variable, then used in prompt
236
+ export async function variableFlowSecret() {
237
+ const apiKey = "sk-abcdefghijklmnopqrstuvwxyz1234"
238
+ const authToken = "ghp_1234567890abcdefghijklmnopqrstuvwxyz"
239
+
240
+ // These secrets flow into the prompt via template interpolation
241
+ const systemPrompt = \`You have access to external APIs.
242
+ OpenAI key: \${apiKey}
243
+ GitHub token: \${authToken}\`
244
+
245
+ return openai.chat.completions.create({
246
+ model: 'gpt-4',
247
+ messages: [
248
+ { role: 'system', content: systemPrompt }
249
+ ]
250
+ })
251
+ }
252
+
253
+ // Secret via concatenation
254
+ export async function concatFlowSecret() {
255
+ const secretKey = "sk_live_abcdefghijklmnopqrstuvwx"
256
+
257
+ // Secret flows via string concatenation
258
+ const prompt = "Process payment with key: " + secretKey
259
+
260
+ return openai.chat.completions.create({
261
+ model: 'gpt-4',
262
+ messages: [
263
+ { role: 'system', content: prompt }
264
+ ]
265
+ })
266
+ }
267
+
268
+ // Multi-hop variable flow
269
+ export async function multiHopSecret() {
270
+ const credentials = {
271
+ apiToken: "xoxb-123456789012-1234567890123-abcdefghijkl"
272
+ }
273
+
274
+ const token = credentials.apiToken
275
+
276
+ return openai.chat.completions.create({
277
+ model: 'gpt-4',
278
+ messages: [
279
+ { role: 'system', content: \`Slack token for notifications: \${token}\` }
280
+ ]
281
+ })
282
+ }
283
+ `,
284
+ language: 'typescript',
285
+ size: 1500,
286
+ },
287
+ },
90
288
  ],
91
289
 
92
290
  falseNegatives: [
@@ -174,5 +372,106 @@ export async function allowedModel(model: string, prompt: string) {
174
372
  size: 1500,
175
373
  },
176
374
  },
375
+ // ========== Safe Secrets Patterns ==========
376
+ {
377
+ name: 'Secrets in Prompts - Safe Patterns',
378
+ expectFindings: false,
379
+ description: 'Safe patterns for handling secrets near LLM code that should NOT be flagged',
380
+ allowedInfoFindings: [
381
+ {
382
+ category: 'hardcoded_secret',
383
+ maxCount: 1,
384
+ reason: 'Info-level for test variable names or placeholders',
385
+ },
386
+ {
387
+ category: 'ai_pattern',
388
+ maxCount: 1,
389
+ reason: 'Info-level BYOK pattern detection for user-provided API keys (feature, not vulnerability)',
390
+ },
391
+ ],
392
+ file: {
393
+ path: 'src/api/ai/safe-secrets.ts',
394
+ content: `
395
+ import OpenAI from 'openai'
396
+
397
+ const openai = new OpenAI()
398
+
399
+ // 1. Using environment variables (SAFE)
400
+ export async function envVarSecret() {
401
+ const apiKey = process.env.OPENAI_API_KEY
402
+ const client = new OpenAI({ apiKey })
403
+
404
+ return client.chat.completions.create({
405
+ model: 'gpt-4',
406
+ messages: [
407
+ { role: 'system', content: 'You are a helpful assistant.' }
408
+ ]
409
+ })
410
+ }
411
+
412
+ // 2. Server-side API call without exposing key to prompt (SAFE)
413
+ export async function serverSideCall() {
414
+ // Key is used for client auth, NOT exposed to prompt
415
+ const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY)
416
+
417
+ const result = await openai.chat.completions.create({
418
+ model: 'gpt-4',
419
+ messages: [
420
+ { role: 'user', content: 'What products should I buy?' }
421
+ ]
422
+ })
423
+
424
+ // Use AI response to make server-side Stripe call
425
+ const products = await stripe.products.list()
426
+ return { aiResponse: result, products }
427
+ }
428
+
429
+ // 3. Placeholder/example values (SAFE)
430
+ export async function examplePlaceholder() {
431
+ // These are clearly placeholders, not real secrets
432
+ const EXAMPLE_API_KEY = "your-api-key-here"
433
+ const TEST_TOKEN = "test_token_placeholder"
434
+ const DEMO_KEY = "demo_sk_1234"
435
+
436
+ // Documentation example
437
+ console.log("Replace EXAMPLE_API_KEY with your actual key")
438
+ }
439
+
440
+ // 4. Test/mock variable names (SAFE)
441
+ export async function testVariables() {
442
+ const TEST_API_KEY = "sk-test1234567890abcdefghijklmnop"
443
+ const MOCK_SECRET = "mock_secret_for_testing"
444
+ const DUMMY_TOKEN = "dummy_ghp_1234567890"
445
+
446
+ // Used in unit tests, not production
447
+ }
448
+
449
+ // 5. Import.meta.env reference (SAFE)
450
+ export async function importMetaEnv() {
451
+ const key = import.meta.env.VITE_API_KEY
452
+ return openai.chat.completions.create({
453
+ model: 'gpt-4',
454
+ messages: [{ role: 'user', content: 'Hello' }]
455
+ })
456
+ }
457
+
458
+ // 6. Python os.environ (SAFE)
459
+ // const apiKey = os.environ.get('API_KEY')
460
+ // const token = os.getenv('AUTH_TOKEN')
461
+
462
+ // 7. Referencing user's own key (BYOK pattern - SAFE)
463
+ export async function byokPattern(userApiKey: string) {
464
+ // User provides their own key - this is the BYOK feature
465
+ const client = new OpenAI({ apiKey: userApiKey })
466
+ return client.chat.completions.create({
467
+ model: 'gpt-4',
468
+ messages: [{ role: 'user', content: 'Hello' }]
469
+ })
470
+ }
471
+ `,
472
+ language: 'typescript',
473
+ size: 2200,
474
+ },
475
+ },
177
476
  ],
178
477
  }