@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,375 @@
1
+ "use strict";
2
+ /**
3
+ * Layer 2: AI Schema/Tooling Validation Detection
4
+ * Detects missing or weak validation of AI-generated structured outputs
5
+ *
6
+ * Covers:
7
+ * - M5.3: Schema/tooling mismatch
8
+ * - Unvalidated JSON parsing of AI outputs
9
+ * - Weak schema patterns (any, permissive)
10
+ * - Tool invocation parameters not validated
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.detectAISchemaValidation = detectAISchemaValidation;
14
+ exports.isAIContextFile = isAIContextFile;
15
+ exports.hasSchemaValidation = hasSchemaValidation;
16
+ const context_helpers_1 = require("../utils/context-helpers");
17
+ // ============================================================================
18
+ // Context Detection
19
+ // ============================================================================
20
+ /**
21
+ * Check if file is in an AI/LLM context
22
+ */
23
+ function isAIContextFile(filePath, content) {
24
+ // File path patterns
25
+ const aiPathPatterns = [
26
+ /\/(ai|llm|chat|openai|anthropic|agents?|tools?)\//i,
27
+ /(ai|llm|chat|agent|tool|function).*\.(ts|js|tsx|jsx|py)$/i,
28
+ ];
29
+ if (aiPathPatterns.some(p => p.test(filePath))) {
30
+ return true;
31
+ }
32
+ // Content patterns
33
+ const aiContentPatterns = [
34
+ /openai\.|anthropic\.|ChatCompletion|MessageCreate/i,
35
+ /\.chat\.completions?\.create/i,
36
+ /\.messages\.create/i,
37
+ /generateText|streamText|generateObject/i,
38
+ /tool_calls?|function_call|functionCall/i,
39
+ /from\s+['"](?:openai|@anthropic-ai|langchain)/i,
40
+ ];
41
+ return aiContentPatterns.some(p => p.test(content));
42
+ }
43
+ /**
44
+ * Check if there's schema validation in the context
45
+ */
46
+ function hasSchemaValidation(context) {
47
+ const validationPatterns = [
48
+ // Zod
49
+ /z\.(?:parse|safeParse|parseAsync)\s*\(/i,
50
+ /\.parse\s*\([^)]*response/i,
51
+ /zodSchema|z\.object/i,
52
+ // Ajv
53
+ /ajv\.(?:compile|validate)/i,
54
+ /\.validate\s*\([^)]*schema/i,
55
+ // Joi
56
+ /joi\.(?:object|string|number).*\.validate/i,
57
+ /\.validate\s*\([^)]*joi/i,
58
+ // Yup
59
+ /yup\.(?:object|string|number).*\.validate/i,
60
+ // TypeBox
61
+ /Type\.(?:Object|String|Number)/i,
62
+ /Value\.(?:Check|Decode)/i,
63
+ // Generic validation
64
+ /validateSchema|schemaValidator/i,
65
+ /JSON\.parse.*try.*catch.*schema/i,
66
+ // OpenAI Structured Outputs
67
+ /response_format.*json_schema/i,
68
+ /json_schema\s*:/i,
69
+ ];
70
+ return validationPatterns.some(p => p.test(context));
71
+ }
72
+ /**
73
+ * Check if there's a security-sensitive sink after parsing
74
+ */
75
+ function hasSecuritySink(context) {
76
+ const sinkPatterns = [
77
+ // Execution sinks
78
+ /eval\s*\(/i,
79
+ /Function\s*\(/i,
80
+ /exec\s*\(|spawn\s*\(/i,
81
+ /child_process/i,
82
+ // Database sinks
83
+ /\.query\s*\(/i,
84
+ /\.execute\s*\(/i,
85
+ /\.raw\s*\(/i,
86
+ /\$\{.*\}.*(?:SELECT|INSERT|UPDATE|DELETE)/i,
87
+ // File system sinks
88
+ /fs\.(?:readFile|writeFile|unlink|mkdir)/i,
89
+ /readFileSync|writeFileSync/i,
90
+ // Network sinks
91
+ /fetch\s*\(|axios\.|request\s*\(/i,
92
+ // DOM sinks (if applicable)
93
+ /innerHTML|dangerouslySetInnerHTML/i,
94
+ ];
95
+ return sinkPatterns.some(p => p.test(context));
96
+ }
97
+ /**
98
+ * Check if there's try-catch around the parsing
99
+ */
100
+ function hasTryCatch(content, lineIndex) {
101
+ const lines = content.split('\n');
102
+ const start = Math.max(0, lineIndex - 15);
103
+ const end = Math.min(lines.length, lineIndex + 5);
104
+ const context = lines.slice(start, end).join('\n');
105
+ // Simple check for try block wrapping
106
+ const tryPattern = /try\s*\{[^}]*$/;
107
+ const beforeContext = lines.slice(start, lineIndex).join('\n');
108
+ return tryPattern.test(beforeContext);
109
+ }
110
+ /**
111
+ * Get surrounding context
112
+ */
113
+ function getSurroundingContext(content, lineIndex, windowSize = 20) {
114
+ const lines = content.split('\n');
115
+ const start = Math.max(0, lineIndex - windowSize);
116
+ const end = Math.min(lines.length, lineIndex + windowSize);
117
+ return lines.slice(start, end).join('\n');
118
+ }
119
+ /**
120
+ * Unvalidated AI output parsing patterns
121
+ */
122
+ const UNVALIDATED_PARSING_PATTERNS = [
123
+ // JSON.parse on AI response content
124
+ {
125
+ name: 'AI response content parsed without validation',
126
+ pattern: /JSON\.parse\s*\(\s*(?:response|result|completion|output|message)(?:\.\w+)*(?:\.content|\.text|\.message)?/gi,
127
+ riskType: 'unvalidated_parse',
128
+ baseSeverity: 'medium',
129
+ description: 'AI-generated JSON parsed without schema validation. Model may return malformed or malicious structures.',
130
+ suggestedFix: 'Validate with schema: const data = schema.parse(JSON.parse(response.content)) // using zod',
131
+ },
132
+ // OpenAI choices parsing
133
+ {
134
+ name: 'OpenAI response parsed directly',
135
+ pattern: /JSON\.parse\s*\(\s*(?:\w+\.)?choices\[\d+\]\.message\.content/gi,
136
+ riskType: 'unvalidated_parse',
137
+ baseSeverity: 'medium',
138
+ description: 'OpenAI response content parsed without validation. AI output structure should be verified.',
139
+ suggestedFix: 'Use OpenAI Structured Outputs (response_format: { type: "json_schema", json_schema: {...} }) or validate with zod.',
140
+ },
141
+ // Anthropic content parsing
142
+ {
143
+ name: 'Anthropic response parsed directly',
144
+ pattern: /JSON\.parse\s*\(\s*(?:\w+\.)?content\[0\]\.text/gi,
145
+ riskType: 'unvalidated_parse',
146
+ baseSeverity: 'medium',
147
+ description: 'Anthropic response parsed without validation. AI output may not match expected schema.',
148
+ suggestedFix: 'Validate response structure with zod or similar schema validation library.',
149
+ },
150
+ // Tool call arguments parsing
151
+ {
152
+ name: 'Tool call arguments parsed without validation',
153
+ pattern: /JSON\.parse\s*\(\s*(?:\w+\.)?(?:tool_calls?|function_call)(?:\[\d+\])?\.(?:function\.)?arguments/gi,
154
+ riskType: 'unvalidated_parse',
155
+ baseSeverity: 'medium',
156
+ description: 'Function calling arguments parsed without schema validation. Tool parameters should be verified.',
157
+ suggestedFix: 'Define and validate tool argument schema: const args = toolSchema.parse(JSON.parse(toolCall.function.arguments))',
158
+ },
159
+ // Generic AI output parsing
160
+ {
161
+ name: 'AI output assigned without parsing/validation',
162
+ pattern: /(?:const|let|var)\s+\w+\s*=\s*(?:response|completion|result)\.(?:content|text|data)\s*;?\s*(?!.*(?:parse|validate|schema))/gi,
163
+ riskType: 'unvalidated_parse',
164
+ baseSeverity: 'low',
165
+ description: 'AI output assigned directly to variable. If used as structured data, validate first.',
166
+ suggestedFix: 'If expecting JSON: const data = schema.safeParse(JSON.parse(response.content))',
167
+ },
168
+ ];
169
+ /**
170
+ * Weak schema patterns
171
+ */
172
+ const WEAK_SCHEMA_PATTERNS = [
173
+ // any type for AI response
174
+ {
175
+ name: 'AI response typed as any',
176
+ pattern: /(?:response|aiResponse|completion|result)\s*:\s*any\b/gi,
177
+ riskType: 'weak_schema',
178
+ baseSeverity: 'low',
179
+ description: 'AI response typed as `any`. TypeScript cannot catch type errors at compile time.',
180
+ suggestedFix: 'Define explicit interface and use runtime validation: interface AIResponse { ... }; const data: AIResponse = schema.parse(response)',
181
+ },
182
+ // Permissive zod schemas
183
+ {
184
+ name: 'Permissive zod schema for AI output',
185
+ pattern: /z\.(?:any|unknown)\s*\(\s*\).*(?:response|output|completion)/gi,
186
+ riskType: 'weak_schema',
187
+ baseSeverity: 'low',
188
+ description: 'Using z.any() or z.unknown() defeats the purpose of schema validation.',
189
+ suggestedFix: 'Define specific schema: z.object({ field: z.string(), ... }).strict()',
190
+ },
191
+ // Passthrough schemas
192
+ {
193
+ name: 'Passthrough schema allowing extra properties',
194
+ pattern: /z\.object\s*\([^)]+\)\.passthrough\s*\(\s*\)/gi,
195
+ riskType: 'weak_schema',
196
+ baseSeverity: 'info',
197
+ description: 'Schema uses passthrough() allowing unexpected properties from AI output.',
198
+ suggestedFix: 'Use .strict() instead to reject unexpected properties from AI responses.',
199
+ },
200
+ // Record<string, any>
201
+ {
202
+ name: 'Record<string, any> for AI data',
203
+ pattern: /Record<string,\s*any>\s*.*(?:response|result|output|completion|aiData)/gi,
204
+ riskType: 'weak_schema',
205
+ baseSeverity: 'low',
206
+ description: 'Generic Record<string, any> type used for AI output provides no type safety.',
207
+ suggestedFix: 'Define specific interface or use zod schema for runtime validation.',
208
+ },
209
+ // Object type without specifics
210
+ {
211
+ name: 'Generic object type for AI response',
212
+ pattern: /(?:response|completion|aiOutput)\s*:\s*(?:object|Object|{})\b/gi,
213
+ riskType: 'weak_schema',
214
+ baseSeverity: 'info',
215
+ description: 'Generic object type for AI response. Consider defining specific interface.',
216
+ suggestedFix: 'Replace with specific interface that documents expected AI output structure.',
217
+ },
218
+ ];
219
+ /**
220
+ * Tool parameter validation issues
221
+ */
222
+ const TOOL_PARAM_PATTERNS = [
223
+ // Tool parameters used directly in paths
224
+ {
225
+ name: 'Tool parameter used in file path',
226
+ pattern: /(?:tool|args|parameters)(?:\.\w+)*\.(?:path|filename|filepath|file).*(?:readFile|writeFile|fs\.|path\.)/gi,
227
+ riskType: 'tool_params',
228
+ baseSeverity: 'high',
229
+ description: 'AI-generated file path used without validation. Path traversal attack possible.',
230
+ suggestedFix: 'Validate path against allowlist: if (!allowedPaths.some(p => resolvedPath.startsWith(p))) throw new Error("Invalid path")',
231
+ },
232
+ // Tool parameters in commands
233
+ {
234
+ name: 'Tool parameter used in shell command',
235
+ pattern: /(?:tool|args|parameters)(?:\.\w+)*\.(?:command|cmd|script).*(?:exec|spawn|shell)/gi,
236
+ riskType: 'tool_params',
237
+ baseSeverity: 'critical',
238
+ description: 'AI-generated command executed without validation. Command injection possible.',
239
+ suggestedFix: 'Use allowlist for permitted commands. Never execute arbitrary AI-generated commands.',
240
+ },
241
+ // Tool parameters in URLs
242
+ {
243
+ name: 'Tool parameter used in URL',
244
+ pattern: /(?:tool|args|parameters)(?:\.\w+)*\.(?:url|endpoint|host).*(?:fetch|axios|request|http)/gi,
245
+ riskType: 'tool_params',
246
+ baseSeverity: 'high',
247
+ description: 'AI-generated URL used without validation. SSRF attack possible.',
248
+ suggestedFix: 'Validate URL against allowlist of permitted hosts before making request.',
249
+ },
250
+ // Tool parameters in database queries
251
+ {
252
+ name: 'Tool parameter used in database query',
253
+ pattern: /(?:tool|args|parameters)(?:\.\w+)*\.(?:query|sql|table|column).*(?:\.query|\.execute|\.raw)/gi,
254
+ riskType: 'tool_params',
255
+ baseSeverity: 'high',
256
+ description: 'AI-generated value used in database query. SQL injection possible.',
257
+ suggestedFix: 'Use parameterized queries. Validate table/column names against allowlist.',
258
+ },
259
+ // Function call name used in switch/if
260
+ {
261
+ name: 'Tool/function call routed without validation',
262
+ pattern: /(?:tool_call|function_call|functionCall)\.(?:name|function\.name).*(?:switch|if|\[.*\])/gi,
263
+ riskType: 'tool_params',
264
+ baseSeverity: 'medium',
265
+ description: 'AI-selected function name used for routing. Validate against allowed functions.',
266
+ suggestedFix: 'Check function name against allowlist: const allowedFunctions = ["search", "calculate"]; if (!allowedFunctions.includes(name)) throw',
267
+ },
268
+ ];
269
+ // ============================================================================
270
+ // Main Detection Function
271
+ // ============================================================================
272
+ /**
273
+ * Main detection function for AI schema/tooling validation issues
274
+ */
275
+ function detectAISchemaValidation(content, filePath) {
276
+ const vulnerabilities = [];
277
+ // Skip non-applicable files
278
+ if ((0, context_helpers_1.isScannerOrFixtureFile)(filePath))
279
+ return vulnerabilities;
280
+ if ((0, context_helpers_1.isDocumentationFile)(filePath))
281
+ return vulnerabilities;
282
+ // Only scan files in AI context
283
+ if (!isAIContextFile(filePath, content)) {
284
+ return vulnerabilities;
285
+ }
286
+ const lines = content.split('\n');
287
+ const isTestFile = (0, context_helpers_1.isTestOrMockFile)(filePath);
288
+ // Check file-level validation presence
289
+ const fileHasValidation = hasSchemaValidation(content);
290
+ // Process all pattern categories
291
+ const allPatterns = [
292
+ ...UNVALIDATED_PARSING_PATTERNS,
293
+ ...WEAK_SCHEMA_PATTERNS,
294
+ ...TOOL_PARAM_PATTERNS,
295
+ ];
296
+ for (const pattern of allPatterns) {
297
+ const regex = new RegExp(pattern.pattern.source, pattern.pattern.flags);
298
+ let match;
299
+ while ((match = regex.exec(content)) !== null) {
300
+ const lineNumber = content.substring(0, match.index).split('\n').length;
301
+ const lineContent = lines[lineNumber - 1]?.trim() || '';
302
+ // Skip comments
303
+ if ((0, context_helpers_1.isComment)(lineContent))
304
+ continue;
305
+ // Get surrounding context
306
+ const context = getSurroundingContext(content, lineNumber - 1, 20);
307
+ // Check for local validation
308
+ const localHasValidation = hasSchemaValidation(context);
309
+ const localHasTryCatch = hasTryCatch(content, lineNumber - 1);
310
+ const localHasSecuritySink = hasSecuritySink(context);
311
+ // Calculate severity based on context
312
+ let severity = pattern.baseSeverity;
313
+ const notes = [];
314
+ // Apply context-aware adjustments
315
+ if (pattern.riskType === 'unvalidated_parse') {
316
+ if (localHasValidation || fileHasValidation) {
317
+ severity = 'info';
318
+ notes.push('Schema validation detected nearby');
319
+ }
320
+ else if (localHasSecuritySink) {
321
+ // Elevate if used in security-sensitive context
322
+ if (severity === 'medium')
323
+ severity = 'high';
324
+ notes.push('Used in security-sensitive context');
325
+ }
326
+ else if (localHasTryCatch && !localHasSecuritySink) {
327
+ // Try-catch without sink is minor
328
+ severity = 'low';
329
+ notes.push('Has try-catch but no schema validation');
330
+ }
331
+ }
332
+ if (pattern.riskType === 'weak_schema') {
333
+ // Weak schemas at API boundaries are more concerning
334
+ if (/export|handler|route|api/i.test(context)) {
335
+ if (severity === 'low')
336
+ severity = 'medium';
337
+ notes.push('At API boundary');
338
+ }
339
+ }
340
+ if (pattern.riskType === 'tool_params') {
341
+ // Already high/critical, check for mitigation
342
+ if (localHasValidation) {
343
+ severity = severity === 'critical' ? 'medium' : 'low';
344
+ notes.push('Validation detected');
345
+ }
346
+ }
347
+ // Downgrade test files
348
+ if (isTestFile) {
349
+ severity = 'info';
350
+ notes.push('in test file');
351
+ }
352
+ // Build final description
353
+ let description = pattern.description;
354
+ if (notes.length > 0) {
355
+ description += ` (${notes.join('; ')})`;
356
+ }
357
+ vulnerabilities.push({
358
+ id: `ai-schema-${filePath}-${lineNumber}-${pattern.name.replace(/\s+/g, '-')}`,
359
+ filePath,
360
+ lineNumber,
361
+ lineContent,
362
+ severity,
363
+ category: 'ai_schema_mismatch',
364
+ title: pattern.name,
365
+ description,
366
+ suggestedFix: pattern.suggestedFix,
367
+ confidence: severity === 'info' ? 'low' : 'medium',
368
+ layer: 2,
369
+ requiresAIValidation: true, // Tier B - always validate with AI
370
+ });
371
+ }
372
+ }
373
+ return vulnerabilities;
374
+ }
375
+ //# sourceMappingURL=ai-schema-validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-schema-validation.js","sourceRoot":"","sources":["../../src/layer2/ai-schema-validation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Layer 2: Authentication Anti-Pattern Detection
3
+ * Identifies weak or missing authentication/authorization patterns
4
+ *
5
+ * Key improvements:
6
+ * - Respects global middleware protection (caps severity at info)
7
+ * - Detects throwing auth helpers and suppresses redundant null checks
8
+ * - Properly classifies public endpoints
9
+ */
10
+ import type { Vulnerability } from '../types';
11
+ import type { MiddlewareAuthConfig } from '../utils/middleware-detector';
12
+ import type { AuthHelperContext } from '../utils/auth-helper-detector';
13
+ import type { FileAuthImports } from '../utils/imported-auth-detector';
14
+ export interface AuthAntipatternOptions {
15
+ middlewareConfig?: MiddlewareAuthConfig;
16
+ authHelpers?: AuthHelperContext;
17
+ fileAuthImports?: Map<string, FileAuthImports>;
18
+ }
19
+ export declare function detectAuthAntipatterns(content: string, filePath: string, options?: AuthAntipatternOptions): Vulnerability[];
20
+ //# sourceMappingURL=auth-antipatterns.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-antipatterns.d.ts","sourceRoot":"","sources":["../../src/layer2/auth-antipatterns.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAyB,MAAM,UAAU,CAAA;AACpE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAA;AAExE,OAAO,KAAK,EAAc,iBAAiB,EAAE,MAAM,+BAA+B,CAAA;AAElF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAA;AA6OtE,MAAM,WAAW,sBAAsB;IACrC,gBAAgB,CAAC,EAAE,oBAAoB,CAAA;IACvC,WAAW,CAAC,EAAE,iBAAiB,CAAA;IAC/B,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;CAC/C;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,sBAA2B,GACnC,aAAa,EAAE,CAmIjB"}