@oculum/scanner 1.0.0

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 (281) hide show
  1. package/dist/formatters/cli-terminal.d.ts +27 -0
  2. package/dist/formatters/cli-terminal.d.ts.map +1 -0
  3. package/dist/formatters/cli-terminal.js +412 -0
  4. package/dist/formatters/cli-terminal.js.map +1 -0
  5. package/dist/formatters/github-comment.d.ts +41 -0
  6. package/dist/formatters/github-comment.d.ts.map +1 -0
  7. package/dist/formatters/github-comment.js +306 -0
  8. package/dist/formatters/github-comment.js.map +1 -0
  9. package/dist/formatters/grouping.d.ts +52 -0
  10. package/dist/formatters/grouping.d.ts.map +1 -0
  11. package/dist/formatters/grouping.js +152 -0
  12. package/dist/formatters/grouping.js.map +1 -0
  13. package/dist/formatters/index.d.ts +9 -0
  14. package/dist/formatters/index.d.ts.map +1 -0
  15. package/dist/formatters/index.js +35 -0
  16. package/dist/formatters/index.js.map +1 -0
  17. package/dist/formatters/vscode-diagnostic.d.ts +103 -0
  18. package/dist/formatters/vscode-diagnostic.d.ts.map +1 -0
  19. package/dist/formatters/vscode-diagnostic.js +151 -0
  20. package/dist/formatters/vscode-diagnostic.js.map +1 -0
  21. package/dist/index.d.ts +52 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +648 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/layer1/comments.d.ts +8 -0
  26. package/dist/layer1/comments.d.ts.map +1 -0
  27. package/dist/layer1/comments.js +203 -0
  28. package/dist/layer1/comments.js.map +1 -0
  29. package/dist/layer1/config-audit.d.ts +8 -0
  30. package/dist/layer1/config-audit.d.ts.map +1 -0
  31. package/dist/layer1/config-audit.js +252 -0
  32. package/dist/layer1/config-audit.js.map +1 -0
  33. package/dist/layer1/entropy.d.ts +8 -0
  34. package/dist/layer1/entropy.d.ts.map +1 -0
  35. package/dist/layer1/entropy.js +500 -0
  36. package/dist/layer1/entropy.js.map +1 -0
  37. package/dist/layer1/file-flags.d.ts +7 -0
  38. package/dist/layer1/file-flags.d.ts.map +1 -0
  39. package/dist/layer1/file-flags.js +112 -0
  40. package/dist/layer1/file-flags.js.map +1 -0
  41. package/dist/layer1/index.d.ts +36 -0
  42. package/dist/layer1/index.d.ts.map +1 -0
  43. package/dist/layer1/index.js +132 -0
  44. package/dist/layer1/index.js.map +1 -0
  45. package/dist/layer1/patterns.d.ts +8 -0
  46. package/dist/layer1/patterns.d.ts.map +1 -0
  47. package/dist/layer1/patterns.js +482 -0
  48. package/dist/layer1/patterns.js.map +1 -0
  49. package/dist/layer1/urls.d.ts +8 -0
  50. package/dist/layer1/urls.d.ts.map +1 -0
  51. package/dist/layer1/urls.js +296 -0
  52. package/dist/layer1/urls.js.map +1 -0
  53. package/dist/layer1/weak-crypto.d.ts +7 -0
  54. package/dist/layer1/weak-crypto.d.ts.map +1 -0
  55. package/dist/layer1/weak-crypto.js +291 -0
  56. package/dist/layer1/weak-crypto.js.map +1 -0
  57. package/dist/layer2/ai-agent-tools.d.ts +19 -0
  58. package/dist/layer2/ai-agent-tools.d.ts.map +1 -0
  59. package/dist/layer2/ai-agent-tools.js +528 -0
  60. package/dist/layer2/ai-agent-tools.js.map +1 -0
  61. package/dist/layer2/ai-endpoint-protection.d.ts +36 -0
  62. package/dist/layer2/ai-endpoint-protection.d.ts.map +1 -0
  63. package/dist/layer2/ai-endpoint-protection.js +332 -0
  64. package/dist/layer2/ai-endpoint-protection.js.map +1 -0
  65. package/dist/layer2/ai-execution-sinks.d.ts +18 -0
  66. package/dist/layer2/ai-execution-sinks.d.ts.map +1 -0
  67. package/dist/layer2/ai-execution-sinks.js +496 -0
  68. package/dist/layer2/ai-execution-sinks.js.map +1 -0
  69. package/dist/layer2/ai-fingerprinting.d.ts +7 -0
  70. package/dist/layer2/ai-fingerprinting.d.ts.map +1 -0
  71. package/dist/layer2/ai-fingerprinting.js +654 -0
  72. package/dist/layer2/ai-fingerprinting.js.map +1 -0
  73. package/dist/layer2/ai-prompt-hygiene.d.ts +19 -0
  74. package/dist/layer2/ai-prompt-hygiene.d.ts.map +1 -0
  75. package/dist/layer2/ai-prompt-hygiene.js +356 -0
  76. package/dist/layer2/ai-prompt-hygiene.js.map +1 -0
  77. package/dist/layer2/ai-rag-safety.d.ts +21 -0
  78. package/dist/layer2/ai-rag-safety.d.ts.map +1 -0
  79. package/dist/layer2/ai-rag-safety.js +459 -0
  80. package/dist/layer2/ai-rag-safety.js.map +1 -0
  81. package/dist/layer2/ai-schema-validation.d.ts +25 -0
  82. package/dist/layer2/ai-schema-validation.d.ts.map +1 -0
  83. package/dist/layer2/ai-schema-validation.js +375 -0
  84. package/dist/layer2/ai-schema-validation.js.map +1 -0
  85. package/dist/layer2/auth-antipatterns.d.ts +20 -0
  86. package/dist/layer2/auth-antipatterns.d.ts.map +1 -0
  87. package/dist/layer2/auth-antipatterns.js +333 -0
  88. package/dist/layer2/auth-antipatterns.js.map +1 -0
  89. package/dist/layer2/byok-patterns.d.ts +12 -0
  90. package/dist/layer2/byok-patterns.d.ts.map +1 -0
  91. package/dist/layer2/byok-patterns.js +299 -0
  92. package/dist/layer2/byok-patterns.js.map +1 -0
  93. package/dist/layer2/dangerous-functions.d.ts +7 -0
  94. package/dist/layer2/dangerous-functions.d.ts.map +1 -0
  95. package/dist/layer2/dangerous-functions.js +1375 -0
  96. package/dist/layer2/dangerous-functions.js.map +1 -0
  97. package/dist/layer2/data-exposure.d.ts +16 -0
  98. package/dist/layer2/data-exposure.d.ts.map +1 -0
  99. package/dist/layer2/data-exposure.js +279 -0
  100. package/dist/layer2/data-exposure.js.map +1 -0
  101. package/dist/layer2/framework-checks.d.ts +7 -0
  102. package/dist/layer2/framework-checks.d.ts.map +1 -0
  103. package/dist/layer2/framework-checks.js +388 -0
  104. package/dist/layer2/framework-checks.js.map +1 -0
  105. package/dist/layer2/index.d.ts +58 -0
  106. package/dist/layer2/index.d.ts.map +1 -0
  107. package/dist/layer2/index.js +380 -0
  108. package/dist/layer2/index.js.map +1 -0
  109. package/dist/layer2/logic-gates.d.ts +7 -0
  110. package/dist/layer2/logic-gates.d.ts.map +1 -0
  111. package/dist/layer2/logic-gates.js +182 -0
  112. package/dist/layer2/logic-gates.js.map +1 -0
  113. package/dist/layer2/risky-imports.d.ts +7 -0
  114. package/dist/layer2/risky-imports.d.ts.map +1 -0
  115. package/dist/layer2/risky-imports.js +161 -0
  116. package/dist/layer2/risky-imports.js.map +1 -0
  117. package/dist/layer2/variables.d.ts +8 -0
  118. package/dist/layer2/variables.d.ts.map +1 -0
  119. package/dist/layer2/variables.js +152 -0
  120. package/dist/layer2/variables.js.map +1 -0
  121. package/dist/layer3/anthropic.d.ts +83 -0
  122. package/dist/layer3/anthropic.d.ts.map +1 -0
  123. package/dist/layer3/anthropic.js +1745 -0
  124. package/dist/layer3/anthropic.js.map +1 -0
  125. package/dist/layer3/index.d.ts +24 -0
  126. package/dist/layer3/index.d.ts.map +1 -0
  127. package/dist/layer3/index.js +119 -0
  128. package/dist/layer3/index.js.map +1 -0
  129. package/dist/layer3/openai.d.ts +25 -0
  130. package/dist/layer3/openai.d.ts.map +1 -0
  131. package/dist/layer3/openai.js +238 -0
  132. package/dist/layer3/openai.js.map +1 -0
  133. package/dist/layer3/package-check.d.ts +63 -0
  134. package/dist/layer3/package-check.d.ts.map +1 -0
  135. package/dist/layer3/package-check.js +508 -0
  136. package/dist/layer3/package-check.js.map +1 -0
  137. package/dist/modes/incremental.d.ts +66 -0
  138. package/dist/modes/incremental.d.ts.map +1 -0
  139. package/dist/modes/incremental.js +200 -0
  140. package/dist/modes/incremental.js.map +1 -0
  141. package/dist/tiers.d.ts +125 -0
  142. package/dist/tiers.d.ts.map +1 -0
  143. package/dist/tiers.js +234 -0
  144. package/dist/tiers.js.map +1 -0
  145. package/dist/types.d.ts +175 -0
  146. package/dist/types.d.ts.map +1 -0
  147. package/dist/types.js +50 -0
  148. package/dist/types.js.map +1 -0
  149. package/dist/utils/auth-helper-detector.d.ts +56 -0
  150. package/dist/utils/auth-helper-detector.d.ts.map +1 -0
  151. package/dist/utils/auth-helper-detector.js +360 -0
  152. package/dist/utils/auth-helper-detector.js.map +1 -0
  153. package/dist/utils/context-helpers.d.ts +96 -0
  154. package/dist/utils/context-helpers.d.ts.map +1 -0
  155. package/dist/utils/context-helpers.js +493 -0
  156. package/dist/utils/context-helpers.js.map +1 -0
  157. package/dist/utils/diff-detector.d.ts +53 -0
  158. package/dist/utils/diff-detector.d.ts.map +1 -0
  159. package/dist/utils/diff-detector.js +104 -0
  160. package/dist/utils/diff-detector.js.map +1 -0
  161. package/dist/utils/diff-parser.d.ts +80 -0
  162. package/dist/utils/diff-parser.d.ts.map +1 -0
  163. package/dist/utils/diff-parser.js +202 -0
  164. package/dist/utils/diff-parser.js.map +1 -0
  165. package/dist/utils/imported-auth-detector.d.ts +37 -0
  166. package/dist/utils/imported-auth-detector.d.ts.map +1 -0
  167. package/dist/utils/imported-auth-detector.js +251 -0
  168. package/dist/utils/imported-auth-detector.js.map +1 -0
  169. package/dist/utils/middleware-detector.d.ts +55 -0
  170. package/dist/utils/middleware-detector.d.ts.map +1 -0
  171. package/dist/utils/middleware-detector.js +260 -0
  172. package/dist/utils/middleware-detector.js.map +1 -0
  173. package/dist/utils/oauth-flow-detector.d.ts +41 -0
  174. package/dist/utils/oauth-flow-detector.d.ts.map +1 -0
  175. package/dist/utils/oauth-flow-detector.js +202 -0
  176. package/dist/utils/oauth-flow-detector.js.map +1 -0
  177. package/dist/utils/path-exclusions.d.ts +55 -0
  178. package/dist/utils/path-exclusions.d.ts.map +1 -0
  179. package/dist/utils/path-exclusions.js +222 -0
  180. package/dist/utils/path-exclusions.js.map +1 -0
  181. package/dist/utils/project-context-builder.d.ts +119 -0
  182. package/dist/utils/project-context-builder.d.ts.map +1 -0
  183. package/dist/utils/project-context-builder.js +534 -0
  184. package/dist/utils/project-context-builder.js.map +1 -0
  185. package/dist/utils/registry-clients.d.ts +93 -0
  186. package/dist/utils/registry-clients.d.ts.map +1 -0
  187. package/dist/utils/registry-clients.js +273 -0
  188. package/dist/utils/registry-clients.js.map +1 -0
  189. package/dist/utils/trpc-analyzer.d.ts +78 -0
  190. package/dist/utils/trpc-analyzer.d.ts.map +1 -0
  191. package/dist/utils/trpc-analyzer.js +297 -0
  192. package/dist/utils/trpc-analyzer.js.map +1 -0
  193. package/package.json +45 -0
  194. package/src/__tests__/benchmark/fixtures/false-positives.ts +227 -0
  195. package/src/__tests__/benchmark/fixtures/index.ts +68 -0
  196. package/src/__tests__/benchmark/fixtures/layer1/config-audit.ts +364 -0
  197. package/src/__tests__/benchmark/fixtures/layer1/hardcoded-secrets.ts +173 -0
  198. package/src/__tests__/benchmark/fixtures/layer1/high-entropy.ts +234 -0
  199. package/src/__tests__/benchmark/fixtures/layer1/index.ts +31 -0
  200. package/src/__tests__/benchmark/fixtures/layer1/sensitive-urls.ts +90 -0
  201. package/src/__tests__/benchmark/fixtures/layer1/weak-crypto.ts +197 -0
  202. package/src/__tests__/benchmark/fixtures/layer2/ai-agent-tools.ts +170 -0
  203. package/src/__tests__/benchmark/fixtures/layer2/ai-endpoint-protection.ts +418 -0
  204. package/src/__tests__/benchmark/fixtures/layer2/ai-execution-sinks.ts +189 -0
  205. package/src/__tests__/benchmark/fixtures/layer2/ai-fingerprinting.ts +316 -0
  206. package/src/__tests__/benchmark/fixtures/layer2/ai-prompt-hygiene.ts +178 -0
  207. package/src/__tests__/benchmark/fixtures/layer2/ai-rag-safety.ts +184 -0
  208. package/src/__tests__/benchmark/fixtures/layer2/ai-schema-validation.ts +434 -0
  209. package/src/__tests__/benchmark/fixtures/layer2/auth-antipatterns.ts +159 -0
  210. package/src/__tests__/benchmark/fixtures/layer2/byok-patterns.ts +112 -0
  211. package/src/__tests__/benchmark/fixtures/layer2/dangerous-functions.ts +246 -0
  212. package/src/__tests__/benchmark/fixtures/layer2/data-exposure.ts +168 -0
  213. package/src/__tests__/benchmark/fixtures/layer2/framework-checks.ts +346 -0
  214. package/src/__tests__/benchmark/fixtures/layer2/index.ts +67 -0
  215. package/src/__tests__/benchmark/fixtures/layer2/injection-vulnerabilities.ts +239 -0
  216. package/src/__tests__/benchmark/fixtures/layer2/logic-gates.ts +246 -0
  217. package/src/__tests__/benchmark/fixtures/layer2/risky-imports.ts +231 -0
  218. package/src/__tests__/benchmark/fixtures/layer2/variables.ts +167 -0
  219. package/src/__tests__/benchmark/index.ts +29 -0
  220. package/src/__tests__/benchmark/run-benchmark.ts +144 -0
  221. package/src/__tests__/benchmark/run-depth-validation.ts +206 -0
  222. package/src/__tests__/benchmark/run-real-world-test.ts +243 -0
  223. package/src/__tests__/benchmark/security-benchmark-script.ts +1737 -0
  224. package/src/__tests__/benchmark/tier-integration-script.ts +177 -0
  225. package/src/__tests__/benchmark/types.ts +144 -0
  226. package/src/__tests__/benchmark/utils/test-runner.ts +475 -0
  227. package/src/__tests__/regression/known-false-positives.test.ts +467 -0
  228. package/src/__tests__/snapshots/__snapshots__/scan-depth.test.ts.snap +178 -0
  229. package/src/__tests__/snapshots/scan-depth.test.ts +258 -0
  230. package/src/__tests__/validation/analyze-results.ts +542 -0
  231. package/src/__tests__/validation/extract-for-triage.ts +146 -0
  232. package/src/__tests__/validation/fp-deep-analysis.ts +327 -0
  233. package/src/__tests__/validation/run-validation.ts +364 -0
  234. package/src/__tests__/validation/triage-template.md +132 -0
  235. package/src/formatters/cli-terminal.ts +446 -0
  236. package/src/formatters/github-comment.ts +382 -0
  237. package/src/formatters/grouping.ts +190 -0
  238. package/src/formatters/index.ts +47 -0
  239. package/src/formatters/vscode-diagnostic.ts +243 -0
  240. package/src/index.ts +823 -0
  241. package/src/layer1/comments.ts +218 -0
  242. package/src/layer1/config-audit.ts +289 -0
  243. package/src/layer1/entropy.ts +583 -0
  244. package/src/layer1/file-flags.ts +127 -0
  245. package/src/layer1/index.ts +181 -0
  246. package/src/layer1/patterns.ts +516 -0
  247. package/src/layer1/urls.ts +334 -0
  248. package/src/layer1/weak-crypto.ts +328 -0
  249. package/src/layer2/ai-agent-tools.ts +601 -0
  250. package/src/layer2/ai-endpoint-protection.ts +387 -0
  251. package/src/layer2/ai-execution-sinks.ts +580 -0
  252. package/src/layer2/ai-fingerprinting.ts +758 -0
  253. package/src/layer2/ai-prompt-hygiene.ts +411 -0
  254. package/src/layer2/ai-rag-safety.ts +511 -0
  255. package/src/layer2/ai-schema-validation.ts +421 -0
  256. package/src/layer2/auth-antipatterns.ts +394 -0
  257. package/src/layer2/byok-patterns.ts +336 -0
  258. package/src/layer2/dangerous-functions.ts +1563 -0
  259. package/src/layer2/data-exposure.ts +315 -0
  260. package/src/layer2/framework-checks.ts +433 -0
  261. package/src/layer2/index.ts +473 -0
  262. package/src/layer2/logic-gates.ts +206 -0
  263. package/src/layer2/risky-imports.ts +186 -0
  264. package/src/layer2/variables.ts +166 -0
  265. package/src/layer3/anthropic.ts +2030 -0
  266. package/src/layer3/index.ts +130 -0
  267. package/src/layer3/package-check.ts +604 -0
  268. package/src/modes/incremental.ts +293 -0
  269. package/src/tiers.ts +318 -0
  270. package/src/types.ts +284 -0
  271. package/src/utils/auth-helper-detector.ts +443 -0
  272. package/src/utils/context-helpers.ts +535 -0
  273. package/src/utils/diff-detector.ts +135 -0
  274. package/src/utils/diff-parser.ts +272 -0
  275. package/src/utils/imported-auth-detector.ts +320 -0
  276. package/src/utils/middleware-detector.ts +333 -0
  277. package/src/utils/oauth-flow-detector.ts +246 -0
  278. package/src/utils/path-exclusions.ts +266 -0
  279. package/src/utils/project-context-builder.ts +707 -0
  280. package/src/utils/registry-clients.ts +351 -0
  281. package/src/utils/trpc-analyzer.ts +382 -0
@@ -0,0 +1,332 @@
1
+ "use strict";
2
+ /**
3
+ * Layer 2: AI Endpoint Protection Detection
4
+ * Detects AI/LLM endpoints without proper authentication or rate limiting
5
+ *
6
+ * Covers:
7
+ * - M5.2: AI endpoints without auth/rate limiting
8
+ * - Cost-bearing AI endpoints exposed publicly
9
+ * - Missing rate limiting on AI routes
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.detectAIEndpointProtection = detectAIEndpointProtection;
13
+ exports.isRouteFile = isRouteFile;
14
+ exports.hasAIApiCalls = hasAIApiCalls;
15
+ exports.hasAuthentication = hasAuthentication;
16
+ exports.hasRateLimiting = hasRateLimiting;
17
+ const context_helpers_1 = require("../utils/context-helpers");
18
+ // ============================================================================
19
+ // Context Detection
20
+ // ============================================================================
21
+ /**
22
+ * Check if file is a route/API handler
23
+ */
24
+ function isRouteFile(filePath) {
25
+ const routePatterns = [
26
+ /\/api\/.*\.(ts|js)$/i,
27
+ /\/routes?\/.*\.(ts|js)$/i,
28
+ /route\.(ts|js)$/i,
29
+ /\/pages\/api\/.*\.(ts|js)$/i,
30
+ /\/app\/.*\/route\.(ts|js)$/i,
31
+ /\.(controller|handler)\.(ts|js)$/i,
32
+ ];
33
+ return routePatterns.some(p => p.test(filePath));
34
+ }
35
+ /**
36
+ * Check if content contains AI/LLM API calls
37
+ */
38
+ function hasAIApiCalls(content) {
39
+ const aiPatterns = [
40
+ // OpenAI
41
+ /openai\.chat\.completions?\.create/i,
42
+ /openai\.completions?\.create/i,
43
+ /openai\.embeddings?\.create/i,
44
+ // Anthropic
45
+ /anthropic\.messages\.create/i,
46
+ /anthropic\.completions?\.create/i,
47
+ // Vercel AI SDK
48
+ /\bgenerateText\s*\(/i,
49
+ /\bstreamText\s*\(/i,
50
+ /\bgenerateObject\s*\(/i,
51
+ /\bstreamObject\s*\(/i,
52
+ // Generic patterns
53
+ /\.create\s*\(\s*\{[^}]*model\s*:/i,
54
+ /ChatCompletion|MessageCreate/i,
55
+ // LangChain
56
+ /\.invoke\s*\([^)]*\)/i,
57
+ /ChatOpenAI|ChatAnthropic|ChatModel/i,
58
+ // Other providers
59
+ /replicate\.run/i,
60
+ /cohere\.(?:generate|chat)/i,
61
+ /mistral\.chat/i,
62
+ ];
63
+ return aiPatterns.some(p => p.test(content));
64
+ }
65
+ /**
66
+ * Check if there's authentication in the route
67
+ */
68
+ function hasAuthentication(content) {
69
+ const authPatterns = [
70
+ // Session/user checks
71
+ /getSession|getServerSession|getCurrentUser/i,
72
+ /auth\(\)|requireAuth|withAuth|ensureAuth/i,
73
+ /verifyToken|validateToken|checkToken/i,
74
+ /req\.user|request\.user|context\.user/i,
75
+ /isAuthenticated|checkAuth/i,
76
+ // Header checks
77
+ /Authorization.*Bearer/i,
78
+ /headers\[['"`]authorization['"`]\]/i,
79
+ /getHeader\(['"`]authorization['"`]\)/i,
80
+ // API key validation
81
+ /apiKey|api_key|x-api-key/i,
82
+ // Clerk/NextAuth/Auth0
83
+ /currentUser\(\)|auth\(\)\.protect/i,
84
+ /getAuth\(\)|clerkClient/i,
85
+ // User ID extraction (implies auth)
86
+ /userId|user\.id|currentUserId/i,
87
+ // 401/403 responses
88
+ /status\(401\)|status\(403\)/i,
89
+ /Unauthorized|Forbidden/i,
90
+ ];
91
+ return authPatterns.some(p => p.test(content));
92
+ }
93
+ /**
94
+ * Check if there's rate limiting
95
+ */
96
+ function hasRateLimiting(content) {
97
+ const rateLimitPatterns = [
98
+ // Rate limit middleware/libraries
99
+ /rateLimit|rateLimiter/i,
100
+ /express-rate-limit/i,
101
+ /upstash.*ratelimit|@upstash\/ratelimit/i,
102
+ /rate-limiter-flexible/i,
103
+ // Custom rate limiting
104
+ /throttle|Throttle/i,
105
+ /requestsPerMinute|requestsPerHour/i,
106
+ /maxRequests|requestLimit/i,
107
+ // Rate limit headers
108
+ /X-RateLimit|x-ratelimit/i,
109
+ /Retry-After/i,
110
+ // 429 responses
111
+ /status\(429\)|\.status === 429/i,
112
+ /Too Many Requests|TooManyRequests/i,
113
+ // Sliding window/token bucket
114
+ /slidingWindow|tokenBucket|fixedWindow/i,
115
+ ];
116
+ return rateLimitPatterns.some(p => p.test(content));
117
+ }
118
+ /**
119
+ * Check if this is a BYOK (Bring Your Own Key) endpoint
120
+ * BYOK endpoints have lower risk since user pays for their own usage
121
+ */
122
+ function isBYOKEndpoint(content) {
123
+ const byokPatterns = [
124
+ /req\.body\.(?:apiKey|api_key|openaiKey|anthropicKey)/i,
125
+ /request\.(?:apiKey|api_key|openaiKey|anthropicKey)/i,
126
+ /userApiKey|user_api_key|clientApiKey/i,
127
+ /['"`](?:apiKey|api_key|openai_key|anthropic_key)['"`]\s*:/i,
128
+ // Headers with user's key
129
+ /headers\[['"`]x-openai-key['"`]\]/i,
130
+ /headers\[['"`]x-api-key['"`]\]/i,
131
+ ];
132
+ return byokPatterns.some(p => p.test(content));
133
+ }
134
+ /**
135
+ * Check if route is protected by middleware (from config)
136
+ */
137
+ function isProtectedByMiddleware(filePath, middlewareConfig) {
138
+ if (!middlewareConfig?.protectedPaths)
139
+ return false;
140
+ // Extract route path from file path
141
+ const routePath = filePath
142
+ .replace(/.*\/(pages|app)\/api/, '/api')
143
+ .replace(/.*\/routes?/, '')
144
+ .replace(/\/route\.(ts|js)$/, '')
145
+ .replace(/\.(ts|js)$/, '')
146
+ .replace(/\[([^\]]+)\]/g, ':$1');
147
+ return middlewareConfig.protectedPaths.some(p => routePath.startsWith(p));
148
+ }
149
+ /**
150
+ * Check if this is an internal/admin-only route
151
+ */
152
+ function isInternalRoute(filePath, content) {
153
+ const internalPatterns = [
154
+ /\/internal\//i,
155
+ /\/admin\//i,
156
+ /\/_internal\//i,
157
+ // Content checks
158
+ /adminOnly|internalOnly|isAdmin/i,
159
+ /process\.env\.INTERNAL_SECRET/i,
160
+ ];
161
+ return internalPatterns.some(p => p.test(filePath) || p.test(content));
162
+ }
163
+ /**
164
+ * Get surrounding context
165
+ */
166
+ function getSurroundingContext(content, lineIndex, windowSize = 50) {
167
+ const lines = content.split('\n');
168
+ const start = Math.max(0, lineIndex - windowSize);
169
+ const end = Math.min(lines.length, lineIndex + windowSize);
170
+ return lines.slice(start, end).join('\n');
171
+ }
172
+ /**
173
+ * Route handler patterns by framework
174
+ */
175
+ const ROUTE_HANDLER_PATTERNS = [
176
+ // Next.js App Router
177
+ {
178
+ name: 'Next.js App Router AI endpoint',
179
+ pattern: /export\s+(?:async\s+)?function\s+(GET|POST|PUT|PATCH|DELETE)\s*\(/gi,
180
+ framework: 'nextjs_app',
181
+ description: 'Next.js App Router endpoint with AI API calls lacks protection.',
182
+ suggestedFix: 'Add authentication check at start of handler. Consider using middleware for auth and rate limiting.',
183
+ },
184
+ // Next.js Pages Router
185
+ {
186
+ name: 'Next.js Pages API route',
187
+ pattern: /export\s+default\s+(?:async\s+)?function\s*(?:\w+\s*)?\([^)]*req/gi,
188
+ framework: 'nextjs_pages',
189
+ description: 'Next.js Pages API route with AI calls lacks protection.',
190
+ suggestedFix: 'Add authentication: const session = await getServerSession(req, res, authOptions); if (!session) return res.status(401).json({error: "Unauthorized"})',
191
+ },
192
+ // Express
193
+ {
194
+ name: 'Express AI route',
195
+ pattern: /(?:app|router)\.(get|post|put|patch|delete)\s*\(\s*['"`][^'"`]+['"`]\s*,/gi,
196
+ framework: 'express',
197
+ description: 'Express route with AI API calls lacks middleware protection.',
198
+ suggestedFix: 'Add authentication and rate limiting middleware: app.post("/api/chat", authMiddleware, rateLimiter, handler)',
199
+ },
200
+ // Fastify
201
+ {
202
+ name: 'Fastify AI route',
203
+ pattern: /fastify\.(get|post|put|patch|delete)\s*\(\s*['"`][^'"`]+['"`]/gi,
204
+ framework: 'fastify',
205
+ description: 'Fastify route with AI calls lacks protection.',
206
+ suggestedFix: 'Add preHandler hooks for auth and rate limiting: { preHandler: [authenticate, rateLimit] }',
207
+ },
208
+ // Generic handler exports
209
+ {
210
+ name: 'API handler with AI calls',
211
+ pattern: /export\s+(?:const|async\s+function)\s+(?:handler|apiHandler)\s*[=:]/gi,
212
+ framework: 'generic',
213
+ description: 'API handler with AI calls may lack protection.',
214
+ suggestedFix: 'Ensure authentication and rate limiting are applied before AI API calls.',
215
+ },
216
+ ];
217
+ /**
218
+ * Main detection function for AI endpoint protection issues
219
+ */
220
+ function detectAIEndpointProtection(content, filePath, options = {}) {
221
+ const vulnerabilities = [];
222
+ // Skip non-applicable files
223
+ if ((0, context_helpers_1.isScannerOrFixtureFile)(filePath))
224
+ return vulnerabilities;
225
+ if ((0, context_helpers_1.isDocumentationFile)(filePath))
226
+ return vulnerabilities;
227
+ // Only scan route files that have AI API calls
228
+ if (!isRouteFile(filePath) || !hasAIApiCalls(content)) {
229
+ return vulnerabilities;
230
+ }
231
+ const lines = content.split('\n');
232
+ const isTestFile = (0, context_helpers_1.isTestOrMockFile)(filePath);
233
+ const isExample = (0, context_helpers_1.isExampleDirectory)(filePath);
234
+ // Check file-level protection
235
+ const fileHasAuth = hasAuthentication(content);
236
+ const fileHasRateLimit = hasRateLimiting(content);
237
+ const isByok = isBYOKEndpoint(content);
238
+ const isInternal = isInternalRoute(filePath, content);
239
+ const isMiddlewareProtected = isProtectedByMiddleware(filePath, options.middlewareConfig);
240
+ // Scan for route handler patterns
241
+ for (const pattern of ROUTE_HANDLER_PATTERNS) {
242
+ const regex = new RegExp(pattern.pattern.source, pattern.pattern.flags);
243
+ let match;
244
+ while ((match = regex.exec(content)) !== null) {
245
+ const lineNumber = content.substring(0, match.index).split('\n').length;
246
+ const lineContent = lines[lineNumber - 1]?.trim() || '';
247
+ // Skip comments
248
+ if ((0, context_helpers_1.isComment)(lineContent))
249
+ continue;
250
+ // Get surrounding context
251
+ const context = getSurroundingContext(content, lineNumber - 1, 50);
252
+ // Check for local protection patterns (within handler)
253
+ const handlerHasAuth = hasAuthentication(context);
254
+ const handlerHasRateLimit = hasRateLimiting(context);
255
+ // Calculate severity based on protection status
256
+ let severity;
257
+ const notes = [];
258
+ if (isMiddlewareProtected || isInternal) {
259
+ severity = 'info';
260
+ notes.push(isMiddlewareProtected ? 'Protected by middleware' : 'Internal route');
261
+ }
262
+ else if (handlerHasAuth || fileHasAuth) {
263
+ if (handlerHasRateLimit || fileHasRateLimit) {
264
+ // Has both auth and rate limiting
265
+ severity = 'info';
266
+ notes.push('Has authentication and rate limiting');
267
+ }
268
+ else {
269
+ // Has auth but no rate limiting
270
+ severity = 'low';
271
+ notes.push('Has authentication but missing rate limiting');
272
+ }
273
+ }
274
+ else if (handlerHasRateLimit || fileHasRateLimit) {
275
+ // Has rate limiting but no auth
276
+ severity = 'medium';
277
+ notes.push('Has rate limiting but missing authentication');
278
+ }
279
+ else {
280
+ // No protection at all
281
+ severity = 'high';
282
+ notes.push('Missing authentication and rate limiting');
283
+ }
284
+ // BYOK endpoints have lower risk
285
+ if (isByok && severity !== 'info') {
286
+ severity = severity === 'high' ? 'medium' : (severity === 'medium' ? 'low' : severity);
287
+ notes.push('BYOK endpoint - user provides API key');
288
+ }
289
+ // Downgrade test files
290
+ if (isTestFile) {
291
+ severity = 'info';
292
+ notes.push('in test file');
293
+ }
294
+ // Downgrade example/demo directories - these are tutorials, not production code
295
+ if (isExample && severity !== 'info') {
296
+ severity = 'info';
297
+ notes.push('in example/demo directory - tutorial code');
298
+ }
299
+ // Build description
300
+ let description = pattern.description;
301
+ if (notes.length > 0) {
302
+ description += ` (${notes.join('; ')})`;
303
+ }
304
+ // Determine suggested fix based on what's missing
305
+ let suggestedFix = pattern.suggestedFix;
306
+ if (handlerHasAuth && !handlerHasRateLimit) {
307
+ suggestedFix = 'Add rate limiting to prevent cost abuse: npm install express-rate-limit or use Upstash ratelimit for serverless.';
308
+ }
309
+ vulnerabilities.push({
310
+ id: `ai-endpoint-${filePath}-${lineNumber}-${pattern.name.replace(/\s+/g, '-')}`,
311
+ filePath,
312
+ lineNumber,
313
+ lineContent,
314
+ severity,
315
+ category: 'ai_endpoint_unprotected',
316
+ title: pattern.name,
317
+ description,
318
+ suggestedFix,
319
+ confidence: severity === 'info' ? 'low' : 'medium',
320
+ layer: 2,
321
+ requiresAIValidation: severity !== 'info',
322
+ });
323
+ // Only report one finding per file (file-level issue)
324
+ break;
325
+ }
326
+ // Only process if we found a route handler (avoid duplicate patterns)
327
+ if (vulnerabilities.length > 0)
328
+ break;
329
+ }
330
+ return vulnerabilities;
331
+ }
332
+ //# sourceMappingURL=ai-endpoint-protection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-endpoint-protection.js","sourceRoot":"","sources":["../../src/layer2/ai-endpoint-protection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Layer 2: AI Execution Sink Detection
3
+ * Detects patterns where LLM output is fed into dangerous execution sinks
4
+ *
5
+ * Covers B2: Unsafe execution of model output (LLM02)
6
+ *
7
+ * Sinks include:
8
+ * - Code execution: eval(), Function(), vm.runInContext()
9
+ * - Shell execution: exec(), spawn(), child_process
10
+ * - SQL builders: .query(), .execute(), .raw()
11
+ * - Template rendering: innerHTML, dangerouslySetInnerHTML
12
+ */
13
+ import type { Vulnerability } from '../types';
14
+ /**
15
+ * Main detection function for LLM output execution sinks
16
+ */
17
+ export declare function detectAIExecutionSinks(content: string, filePath: string): Vulnerability[];
18
+ //# sourceMappingURL=ai-execution-sinks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-execution-sinks.d.ts","sourceRoot":"","sources":["../../src/layer2/ai-execution-sinks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAyB,MAAM,UAAU,CAAA;AAqcpE;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,aAAa,EAAE,CA2GjB"}