@quantracode/vibecheck 0.0.1 → 0.0.2

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 (208) hide show
  1. package/README.md +6 -6
  2. package/dist/index.d.ts +0 -2
  3. package/dist/index.js +7902 -8
  4. package/package.json +13 -7
  5. package/dist/__tests__/cli.test.d.ts +0 -2
  6. package/dist/__tests__/cli.test.d.ts.map +0 -1
  7. package/dist/__tests__/cli.test.js +0 -243
  8. package/dist/__tests__/fixtures/safe-app/app/api/users/route.js +0 -36
  9. package/dist/__tests__/fixtures/vulnerable-app/app/api/users/route.js +0 -28
  10. package/dist/__tests__/fixtures/vulnerable-app/lib/config.d.ts +0 -4
  11. package/dist/__tests__/fixtures/vulnerable-app/lib/config.d.ts.map +0 -1
  12. package/dist/__tests__/fixtures/vulnerable-app/lib/config.js +0 -6
  13. package/dist/__tests__/scanners/env-config.test.d.ts +0 -2
  14. package/dist/__tests__/scanners/env-config.test.d.ts.map +0 -1
  15. package/dist/__tests__/scanners/env-config.test.js +0 -142
  16. package/dist/__tests__/scanners/nextjs-middleware.test.d.ts +0 -2
  17. package/dist/__tests__/scanners/nextjs-middleware.test.d.ts.map +0 -1
  18. package/dist/__tests__/scanners/nextjs-middleware.test.js +0 -193
  19. package/dist/__tests__/scanners/scanner-packs.test.d.ts +0 -2
  20. package/dist/__tests__/scanners/scanner-packs.test.d.ts.map +0 -1
  21. package/dist/__tests__/scanners/scanner-packs.test.js +0 -126
  22. package/dist/__tests__/scanners/unused-security-imports.test.d.ts +0 -2
  23. package/dist/__tests__/scanners/unused-security-imports.test.d.ts.map +0 -1
  24. package/dist/__tests__/scanners/unused-security-imports.test.js +0 -145
  25. package/dist/commands/demo-artifact.d.ts +0 -7
  26. package/dist/commands/demo-artifact.d.ts.map +0 -1
  27. package/dist/commands/demo-artifact.js +0 -322
  28. package/dist/commands/evaluate.d.ts +0 -30
  29. package/dist/commands/evaluate.d.ts.map +0 -1
  30. package/dist/commands/evaluate.js +0 -258
  31. package/dist/commands/explain.d.ts +0 -12
  32. package/dist/commands/explain.d.ts.map +0 -1
  33. package/dist/commands/explain.js +0 -214
  34. package/dist/commands/index.d.ts +0 -7
  35. package/dist/commands/index.d.ts.map +0 -1
  36. package/dist/commands/index.js +0 -6
  37. package/dist/commands/intent.d.ts +0 -21
  38. package/dist/commands/intent.d.ts.map +0 -1
  39. package/dist/commands/intent.js +0 -192
  40. package/dist/commands/scan.d.ts +0 -44
  41. package/dist/commands/scan.d.ts.map +0 -1
  42. package/dist/commands/scan.js +0 -497
  43. package/dist/commands/waivers.d.ts +0 -30
  44. package/dist/commands/waivers.d.ts.map +0 -1
  45. package/dist/commands/waivers.js +0 -249
  46. package/dist/index.d.ts.map +0 -1
  47. package/dist/phase3/index.d.ts +0 -11
  48. package/dist/phase3/index.d.ts.map +0 -1
  49. package/dist/phase3/index.js +0 -12
  50. package/dist/phase3/intent-miner.d.ts +0 -32
  51. package/dist/phase3/intent-miner.d.ts.map +0 -1
  52. package/dist/phase3/intent-miner.js +0 -323
  53. package/dist/phase3/proof-trace-builder.d.ts +0 -42
  54. package/dist/phase3/proof-trace-builder.d.ts.map +0 -1
  55. package/dist/phase3/proof-trace-builder.js +0 -441
  56. package/dist/phase3/scanners/auth-by-ui-server-gap.d.ts +0 -15
  57. package/dist/phase3/scanners/auth-by-ui-server-gap.d.ts.map +0 -1
  58. package/dist/phase3/scanners/auth-by-ui-server-gap.js +0 -237
  59. package/dist/phase3/scanners/comment-claim-unproven.d.ts +0 -14
  60. package/dist/phase3/scanners/comment-claim-unproven.d.ts.map +0 -1
  61. package/dist/phase3/scanners/comment-claim-unproven.js +0 -161
  62. package/dist/phase3/scanners/index.d.ts +0 -31
  63. package/dist/phase3/scanners/index.d.ts.map +0 -1
  64. package/dist/phase3/scanners/index.js +0 -40
  65. package/dist/phase3/scanners/middleware-assumed-not-matching.d.ts +0 -14
  66. package/dist/phase3/scanners/middleware-assumed-not-matching.d.ts.map +0 -1
  67. package/dist/phase3/scanners/middleware-assumed-not-matching.js +0 -172
  68. package/dist/phase3/scanners/validation-claimed-missing.d.ts +0 -15
  69. package/dist/phase3/scanners/validation-claimed-missing.d.ts.map +0 -1
  70. package/dist/phase3/scanners/validation-claimed-missing.js +0 -204
  71. package/dist/scanners/abuse/compute-abuse.d.ts +0 -20
  72. package/dist/scanners/abuse/compute-abuse.d.ts.map +0 -1
  73. package/dist/scanners/abuse/compute-abuse.js +0 -509
  74. package/dist/scanners/abuse/index.d.ts +0 -12
  75. package/dist/scanners/abuse/index.d.ts.map +0 -1
  76. package/dist/scanners/abuse/index.js +0 -15
  77. package/dist/scanners/auth/index.d.ts +0 -5
  78. package/dist/scanners/auth/index.d.ts.map +0 -1
  79. package/dist/scanners/auth/index.js +0 -10
  80. package/dist/scanners/auth/middleware-gap.d.ts +0 -22
  81. package/dist/scanners/auth/middleware-gap.d.ts.map +0 -1
  82. package/dist/scanners/auth/middleware-gap.js +0 -203
  83. package/dist/scanners/auth/unprotected-api-route.d.ts +0 -12
  84. package/dist/scanners/auth/unprotected-api-route.d.ts.map +0 -1
  85. package/dist/scanners/auth/unprotected-api-route.js +0 -126
  86. package/dist/scanners/config/index.d.ts +0 -5
  87. package/dist/scanners/config/index.d.ts.map +0 -1
  88. package/dist/scanners/config/index.js +0 -10
  89. package/dist/scanners/config/insecure-defaults.d.ts +0 -12
  90. package/dist/scanners/config/insecure-defaults.d.ts.map +0 -1
  91. package/dist/scanners/config/insecure-defaults.js +0 -77
  92. package/dist/scanners/config/undocumented-env.d.ts +0 -24
  93. package/dist/scanners/config/undocumented-env.d.ts.map +0 -1
  94. package/dist/scanners/config/undocumented-env.js +0 -159
  95. package/dist/scanners/crypto/index.d.ts +0 -6
  96. package/dist/scanners/crypto/index.d.ts.map +0 -1
  97. package/dist/scanners/crypto/index.js +0 -11
  98. package/dist/scanners/crypto/jwt-decode-unverified.d.ts +0 -14
  99. package/dist/scanners/crypto/jwt-decode-unverified.d.ts.map +0 -1
  100. package/dist/scanners/crypto/jwt-decode-unverified.js +0 -87
  101. package/dist/scanners/crypto/math-random-tokens.d.ts +0 -13
  102. package/dist/scanners/crypto/math-random-tokens.d.ts.map +0 -1
  103. package/dist/scanners/crypto/math-random-tokens.js +0 -80
  104. package/dist/scanners/crypto/weak-hashing.d.ts +0 -11
  105. package/dist/scanners/crypto/weak-hashing.d.ts.map +0 -1
  106. package/dist/scanners/crypto/weak-hashing.js +0 -95
  107. package/dist/scanners/env-config.d.ts +0 -24
  108. package/dist/scanners/env-config.d.ts.map +0 -1
  109. package/dist/scanners/env-config.js +0 -164
  110. package/dist/scanners/hallucinations/index.d.ts +0 -4
  111. package/dist/scanners/hallucinations/index.d.ts.map +0 -1
  112. package/dist/scanners/hallucinations/index.js +0 -8
  113. package/dist/scanners/hallucinations/unused-security-imports.d.ts +0 -36
  114. package/dist/scanners/hallucinations/unused-security-imports.d.ts.map +0 -1
  115. package/dist/scanners/hallucinations/unused-security-imports.js +0 -309
  116. package/dist/scanners/helpers/ast-helpers.d.ts +0 -6
  117. package/dist/scanners/helpers/ast-helpers.d.ts.map +0 -1
  118. package/dist/scanners/helpers/ast-helpers.js +0 -945
  119. package/dist/scanners/helpers/context-builder.d.ts +0 -17
  120. package/dist/scanners/helpers/context-builder.d.ts.map +0 -1
  121. package/dist/scanners/helpers/context-builder.js +0 -148
  122. package/dist/scanners/helpers/index.d.ts +0 -3
  123. package/dist/scanners/helpers/index.d.ts.map +0 -1
  124. package/dist/scanners/helpers/index.js +0 -2
  125. package/dist/scanners/index.d.ts +0 -30
  126. package/dist/scanners/index.d.ts.map +0 -1
  127. package/dist/scanners/index.js +0 -102
  128. package/dist/scanners/middleware/index.d.ts +0 -4
  129. package/dist/scanners/middleware/index.d.ts.map +0 -1
  130. package/dist/scanners/middleware/index.js +0 -7
  131. package/dist/scanners/middleware/missing-rate-limit.d.ts +0 -13
  132. package/dist/scanners/middleware/missing-rate-limit.d.ts.map +0 -1
  133. package/dist/scanners/middleware/missing-rate-limit.js +0 -140
  134. package/dist/scanners/network/cors-misconfiguration.d.ts +0 -14
  135. package/dist/scanners/network/cors-misconfiguration.d.ts.map +0 -1
  136. package/dist/scanners/network/cors-misconfiguration.js +0 -89
  137. package/dist/scanners/network/index.d.ts +0 -7
  138. package/dist/scanners/network/index.d.ts.map +0 -1
  139. package/dist/scanners/network/index.js +0 -18
  140. package/dist/scanners/network/missing-timeout.d.ts +0 -15
  141. package/dist/scanners/network/missing-timeout.d.ts.map +0 -1
  142. package/dist/scanners/network/missing-timeout.js +0 -93
  143. package/dist/scanners/network/open-redirect.d.ts +0 -15
  144. package/dist/scanners/network/open-redirect.d.ts.map +0 -1
  145. package/dist/scanners/network/open-redirect.js +0 -88
  146. package/dist/scanners/network/ssrf-prone-fetch.d.ts +0 -12
  147. package/dist/scanners/network/ssrf-prone-fetch.d.ts.map +0 -1
  148. package/dist/scanners/network/ssrf-prone-fetch.js +0 -90
  149. package/dist/scanners/nextjs-middleware.d.ts +0 -26
  150. package/dist/scanners/nextjs-middleware.d.ts.map +0 -1
  151. package/dist/scanners/nextjs-middleware.js +0 -246
  152. package/dist/scanners/privacy/debug-flags.d.ts +0 -13
  153. package/dist/scanners/privacy/debug-flags.d.ts.map +0 -1
  154. package/dist/scanners/privacy/debug-flags.js +0 -124
  155. package/dist/scanners/privacy/index.d.ts +0 -6
  156. package/dist/scanners/privacy/index.d.ts.map +0 -1
  157. package/dist/scanners/privacy/index.js +0 -11
  158. package/dist/scanners/privacy/over-broad-response.d.ts +0 -15
  159. package/dist/scanners/privacy/over-broad-response.d.ts.map +0 -1
  160. package/dist/scanners/privacy/over-broad-response.js +0 -109
  161. package/dist/scanners/privacy/sensitive-logging.d.ts +0 -11
  162. package/dist/scanners/privacy/sensitive-logging.d.ts.map +0 -1
  163. package/dist/scanners/privacy/sensitive-logging.js +0 -78
  164. package/dist/scanners/types.d.ts +0 -456
  165. package/dist/scanners/types.d.ts.map +0 -1
  166. package/dist/scanners/types.js +0 -16
  167. package/dist/scanners/unused-security-imports.d.ts +0 -34
  168. package/dist/scanners/unused-security-imports.d.ts.map +0 -1
  169. package/dist/scanners/unused-security-imports.js +0 -206
  170. package/dist/scanners/uploads/index.d.ts +0 -5
  171. package/dist/scanners/uploads/index.d.ts.map +0 -1
  172. package/dist/scanners/uploads/index.js +0 -9
  173. package/dist/scanners/uploads/missing-constraints.d.ts +0 -15
  174. package/dist/scanners/uploads/missing-constraints.d.ts.map +0 -1
  175. package/dist/scanners/uploads/missing-constraints.js +0 -109
  176. package/dist/scanners/uploads/public-path.d.ts +0 -11
  177. package/dist/scanners/uploads/public-path.d.ts.map +0 -1
  178. package/dist/scanners/uploads/public-path.js +0 -87
  179. package/dist/scanners/validation/client-side-only.d.ts +0 -14
  180. package/dist/scanners/validation/client-side-only.d.ts.map +0 -1
  181. package/dist/scanners/validation/client-side-only.js +0 -140
  182. package/dist/scanners/validation/ignored-validation.d.ts +0 -12
  183. package/dist/scanners/validation/ignored-validation.d.ts.map +0 -1
  184. package/dist/scanners/validation/ignored-validation.js +0 -119
  185. package/dist/scanners/validation/index.d.ts +0 -5
  186. package/dist/scanners/validation/index.d.ts.map +0 -1
  187. package/dist/scanners/validation/index.js +0 -9
  188. package/dist/utils/exclude-patterns.d.ts +0 -35
  189. package/dist/utils/exclude-patterns.d.ts.map +0 -1
  190. package/dist/utils/exclude-patterns.js +0 -78
  191. package/dist/utils/file-utils.d.ts +0 -37
  192. package/dist/utils/file-utils.d.ts.map +0 -1
  193. package/dist/utils/file-utils.js +0 -77
  194. package/dist/utils/fingerprint.d.ts +0 -25
  195. package/dist/utils/fingerprint.d.ts.map +0 -1
  196. package/dist/utils/fingerprint.js +0 -28
  197. package/dist/utils/git-info.d.ts +0 -14
  198. package/dist/utils/git-info.d.ts.map +0 -1
  199. package/dist/utils/git-info.js +0 -55
  200. package/dist/utils/index.d.ts +0 -4
  201. package/dist/utils/index.d.ts.map +0 -1
  202. package/dist/utils/index.js +0 -3
  203. package/dist/utils/progress.d.ts +0 -42
  204. package/dist/utils/progress.d.ts.map +0 -1
  205. package/dist/utils/progress.js +0 -165
  206. package/dist/utils/sarif-formatter.d.ts +0 -92
  207. package/dist/utils/sarif-formatter.d.ts.map +0 -1
  208. package/dist/utils/sarif-formatter.js +0 -172
@@ -1,17 +0,0 @@
1
- import type { ScanContext, FileProgressCallback } from "../types.js";
2
- /**
3
- * Options for building scan context
4
- */
5
- export interface ScanContextOptions {
6
- /** Additional glob patterns to exclude */
7
- excludePatterns?: string[];
8
- /** Include test files in scan */
9
- includeTests?: boolean;
10
- /** Progress callback for file processing */
11
- onFileProgress?: FileProgressCallback;
12
- }
13
- /**
14
- * Build a complete ScanContext for scanner use
15
- */
16
- export declare function buildScanContext(repoRoot: string, options?: ScanContextOptions): Promise<ScanContext>;
17
- //# sourceMappingURL=context-builder.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"context-builder.d.ts","sourceRoot":"","sources":["../../../src/scanners/helpers/context-builder.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAA0E,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAE7I;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,0CAA0C;IAC1C,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,iCAAiC;IACjC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,4CAA4C;IAC5C,cAAc,CAAC,EAAE,oBAAoB,CAAC;CACvC;AAyKD;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,WAAW,CAAC,CAmBtB"}
@@ -1,148 +0,0 @@
1
- import { findFiles, readJsonSync, resolvePath, fileExists, readFileSync } from "../../utils/file-utils.js";
2
- import { createAstHelpers } from "./ast-helpers.js";
3
- import { mergeExcludes, normalizePatterns } from "../../utils/exclude-patterns.js";
4
- /**
5
- * Detect framework from package.json dependencies
6
- */
7
- function detectFramework(deps, devDeps) {
8
- const allDeps = { ...deps, ...devDeps };
9
- if (allDeps["next"])
10
- return "next";
11
- if (allDeps["express"])
12
- return "express";
13
- if (allDeps["fastify"])
14
- return "fastify";
15
- if (allDeps["koa"])
16
- return "koa";
17
- return "unknown";
18
- }
19
- /**
20
- * Build file index for quick lookups
21
- */
22
- async function buildFileIndex(repoRoot, options = {}) {
23
- // Build exclude patterns from defaults + custom
24
- const customExcludes = options.excludePatterns ?? [];
25
- const ignorePatterns = normalizePatterns(mergeExcludes(customExcludes, { includeTests: options.includeTests }));
26
- // Find all source files
27
- const allSourceFiles = await findFiles(["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx"], { cwd: repoRoot, ignore: ignorePatterns });
28
- // TypeScript files only
29
- const tsTsxFiles = allSourceFiles.filter((f) => f.endsWith(".ts") || f.endsWith(".tsx"));
30
- // Config files
31
- const configFiles = await findFiles([".env*", "**/*.config.*", "**/config.*"], { cwd: repoRoot, ignore: ignorePatterns });
32
- // Next.js route files (App Router)
33
- const routeFiles = await findFiles(["**/route.ts", "**/route.js", "src/**/route.ts", "src/**/route.js"], { cwd: repoRoot, ignore: ignorePatterns });
34
- // API route files specifically
35
- const apiRouteFiles = routeFiles.filter((f) => f.includes("/api/") || f.includes("\\api\\"));
36
- // Find middleware file
37
- let middlewareFile;
38
- const middlewareCandidates = [
39
- "middleware.ts",
40
- "middleware.js",
41
- "src/middleware.ts",
42
- "src/middleware.js",
43
- ];
44
- for (const candidate of middlewareCandidates) {
45
- if (fileExists(resolvePath(repoRoot, candidate))) {
46
- middlewareFile = candidate;
47
- break;
48
- }
49
- }
50
- return {
51
- allSourceFiles,
52
- tsTsxFiles,
53
- configFiles,
54
- routeFiles,
55
- middlewareFile,
56
- apiRouteFiles,
57
- };
58
- }
59
- /**
60
- * Build repository metadata from package.json
61
- */
62
- function buildRepoMeta(repoRoot) {
63
- const pkgPath = resolvePath(repoRoot, "package.json");
64
- const pkg = readJsonSync(pkgPath);
65
- const dependencies = pkg?.dependencies ?? {};
66
- const devDependencies = pkg?.devDependencies ?? {};
67
- const allDeps = { ...dependencies, ...devDependencies };
68
- return {
69
- dependencies,
70
- devDependencies,
71
- framework: detectFramework(dependencies, devDependencies),
72
- hasTypeScript: Boolean(allDeps["typescript"]),
73
- hasNextAuth: Boolean(allDeps["next-auth"]),
74
- hasPrisma: Boolean(allDeps["prisma"] || allDeps["@prisma/client"]),
75
- };
76
- }
77
- /**
78
- * Build framework hints from dependencies
79
- */
80
- function buildFrameworkHints(repoRoot, deps, devDeps) {
81
- const allDeps = { ...deps, ...devDeps };
82
- return {
83
- isNext: Boolean(allDeps["next"]),
84
- isExpress: Boolean(allDeps["express"]),
85
- hasPrisma: Boolean(allDeps["prisma"] || allDeps["@prisma/client"]),
86
- hasNextAuth: Boolean(allDeps["next-auth"]),
87
- hasMulter: Boolean(allDeps["multer"]),
88
- hasFormidable: Boolean(allDeps["formidable"]),
89
- };
90
- }
91
- /**
92
- * Parse Prisma schema file if it exists
93
- */
94
- function parsePrismaSchema(repoRoot) {
95
- const schemaPath = resolvePath(repoRoot, "prisma/schema.prisma");
96
- const content = readFileSync(schemaPath);
97
- if (!content)
98
- return undefined;
99
- const models = new Map();
100
- const sensitiveFieldPatterns = /password|hash|token|secret|apikey|api_key|private_key|credential/i;
101
- // Parse model blocks
102
- const modelRegex = /model\s+(\w+)\s*\{([^}]+)\}/g;
103
- let match;
104
- while ((match = modelRegex.exec(content)) !== null) {
105
- const modelName = match[1];
106
- const modelBody = match[2];
107
- // Extract field names (first word on each non-empty line)
108
- const fields = [];
109
- const lines = modelBody.split("\n");
110
- for (const line of lines) {
111
- const trimmed = line.trim();
112
- if (!trimmed || trimmed.startsWith("//") || trimmed.startsWith("@@"))
113
- continue;
114
- const fieldMatch = trimmed.match(/^(\w+)\s+/);
115
- if (fieldMatch) {
116
- fields.push(fieldMatch[1]);
117
- }
118
- }
119
- const hasSensitiveFields = fields.some((f) => sensitiveFieldPatterns.test(f));
120
- models.set(modelName.toLowerCase(), {
121
- name: modelName,
122
- fields,
123
- hasSensitiveFields,
124
- });
125
- }
126
- return { models };
127
- }
128
- /**
129
- * Build a complete ScanContext for scanner use
130
- */
131
- export async function buildScanContext(repoRoot, options = {}) {
132
- const [fileIndex, repoMeta] = await Promise.all([
133
- buildFileIndex(repoRoot, options),
134
- Promise.resolve(buildRepoMeta(repoRoot)),
135
- ]);
136
- const helpers = createAstHelpers(repoRoot, fileIndex.allSourceFiles.length, options.onFileProgress);
137
- const frameworkHints = buildFrameworkHints(repoRoot, repoMeta.dependencies, repoMeta.devDependencies);
138
- const prismaSchemaInfo = parsePrismaSchema(repoRoot);
139
- return {
140
- repoRoot,
141
- fileIndex,
142
- repoMeta,
143
- helpers,
144
- frameworkHints,
145
- prismaSchemaInfo,
146
- onFileProgress: options.onFileProgress,
147
- };
148
- }
@@ -1,3 +0,0 @@
1
- export { createAstHelpers } from "./ast-helpers.js";
2
- export { buildScanContext, type ScanContextOptions } from "./context-builder.js";
3
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/scanners/helpers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,KAAK,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
@@ -1,2 +0,0 @@
1
- export { createAstHelpers } from "./ast-helpers.js";
2
- export { buildScanContext } from "./context-builder.js";
@@ -1,30 +0,0 @@
1
- export * from "./types.js";
2
- export { buildScanContext, createAstHelpers, type ScanContextOptions } from "./helpers/index.js";
3
- export { authPack } from "./auth/index.js";
4
- export { validationPack } from "./validation/index.js";
5
- export { privacyPack } from "./privacy/index.js";
6
- export { configPack } from "./config/index.js";
7
- export { networkPack } from "./network/index.js";
8
- export { hallucinationsPack } from "./hallucinations/index.js";
9
- export { middlewarePack } from "./middleware/index.js";
10
- export { cryptoPack } from "./crypto/index.js";
11
- export { uploadsPack } from "./uploads/index.js";
12
- export { abusePack } from "./abuse/index.js";
13
- import type { ScannerPack, Scanner } from "./types.js";
14
- /**
15
- * All available scanner packs
16
- */
17
- export declare const ALL_SCANNER_PACKS: ScannerPack[];
18
- /**
19
- * All available scanners (flattened from packs)
20
- */
21
- export declare const ALL_SCANNERS: Scanner[];
22
- /**
23
- * Get a scanner pack by ID
24
- */
25
- export declare function getScannerPack(id: string): ScannerPack | undefined;
26
- /**
27
- * Get all rule IDs covered by the scanners
28
- */
29
- export declare const SUPPORTED_RULES: readonly ["VC-AUTH-001", "VC-AUTH-INFO-001", "VC-MW-001", "VC-VAL-001", "VC-VAL-002", "VC-PRIV-001", "VC-PRIV-002", "VC-PRIV-003", "VC-CONFIG-001", "VC-CONFIG-002", "VC-NET-001", "VC-NET-002", "VC-NET-003", "VC-NET-004", "VC-HALL-001", "VC-HALL-002", "VC-HALL-010", "VC-HALL-011", "VC-HALL-012", "VC-AUTH-010", "VC-RATE-001", "VC-CRYPTO-001", "VC-CRYPTO-002", "VC-CRYPTO-003", "VC-UP-001", "VC-UP-002", "VC-ABUSE-001", "VC-ABUSE-002", "VC-ABUSE-003", "VC-ABUSE-004"];
30
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scanners/index.ts"],"names":[],"mappings":"AACA,cAAc,YAAY,CAAC;AAG3B,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAGjG,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAG7C,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAkBvD;;GAEG;AACH,eAAO,MAAM,iBAAiB,EAAE,WAAW,EAc1C,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,OAAO,EAAuD,CAAC;AAE1F;;GAEG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAElE;AAED;;GAEG;AACH,eAAO,MAAM,eAAe,odA2ClB,CAAC"}
@@ -1,102 +0,0 @@
1
- // Export types
2
- export * from "./types.js";
3
- // Export helpers
4
- export { buildScanContext, createAstHelpers } from "./helpers/index.js";
5
- // Export scanner packs
6
- export { authPack } from "./auth/index.js";
7
- export { validationPack } from "./validation/index.js";
8
- export { privacyPack } from "./privacy/index.js";
9
- export { configPack } from "./config/index.js";
10
- export { networkPack } from "./network/index.js";
11
- export { hallucinationsPack } from "./hallucinations/index.js";
12
- export { middlewarePack } from "./middleware/index.js";
13
- export { cryptoPack } from "./crypto/index.js";
14
- export { uploadsPack } from "./uploads/index.js";
15
- export { abusePack } from "./abuse/index.js";
16
- import { authPack } from "./auth/index.js";
17
- import { validationPack } from "./validation/index.js";
18
- import { privacyPack } from "./privacy/index.js";
19
- import { configPack } from "./config/index.js";
20
- import { networkPack } from "./network/index.js";
21
- import { hallucinationsPack } from "./hallucinations/index.js";
22
- import { middlewarePack } from "./middleware/index.js";
23
- import { cryptoPack } from "./crypto/index.js";
24
- import { uploadsPack } from "./uploads/index.js";
25
- import { abusePack } from "./abuse/index.js";
26
- // Phase 3 scanners
27
- import { hallucinationsPack as hallucinationsPackPhase3, authPackPhase3, } from "../phase3/index.js";
28
- /**
29
- * All available scanner packs
30
- */
31
- export const ALL_SCANNER_PACKS = [
32
- authPack,
33
- validationPack,
34
- privacyPack,
35
- configPack,
36
- networkPack,
37
- hallucinationsPack,
38
- middlewarePack,
39
- cryptoPack,
40
- uploadsPack,
41
- abusePack,
42
- // Phase 3 packs
43
- hallucinationsPackPhase3,
44
- authPackPhase3,
45
- ];
46
- /**
47
- * All available scanners (flattened from packs)
48
- */
49
- export const ALL_SCANNERS = ALL_SCANNER_PACKS.flatMap((pack) => pack.scanners);
50
- /**
51
- * Get a scanner pack by ID
52
- */
53
- export function getScannerPack(id) {
54
- return ALL_SCANNER_PACKS.find((pack) => pack.id === id);
55
- }
56
- /**
57
- * Get all rule IDs covered by the scanners
58
- */
59
- export const SUPPORTED_RULES = [
60
- // Auth pack
61
- "VC-AUTH-001",
62
- "VC-AUTH-INFO-001",
63
- "VC-MW-001",
64
- // Validation pack
65
- "VC-VAL-001",
66
- "VC-VAL-002",
67
- // Privacy pack
68
- "VC-PRIV-001",
69
- "VC-PRIV-002",
70
- "VC-PRIV-003",
71
- // Config pack
72
- "VC-CONFIG-001",
73
- "VC-CONFIG-002",
74
- // Network pack
75
- "VC-NET-001",
76
- "VC-NET-002",
77
- "VC-NET-003",
78
- "VC-NET-004",
79
- // Hallucinations pack (Phase 1-2)
80
- "VC-HALL-001",
81
- "VC-HALL-002",
82
- // Hallucinations pack (Phase 3)
83
- "VC-HALL-010",
84
- "VC-HALL-011",
85
- "VC-HALL-012",
86
- // Auth pack (Phase 3)
87
- "VC-AUTH-010",
88
- // Middleware pack
89
- "VC-RATE-001",
90
- // Crypto pack
91
- "VC-CRYPTO-001",
92
- "VC-CRYPTO-002",
93
- "VC-CRYPTO-003",
94
- // Uploads pack
95
- "VC-UP-001",
96
- "VC-UP-002",
97
- // Abuse pack
98
- "VC-ABUSE-001",
99
- "VC-ABUSE-002",
100
- "VC-ABUSE-003",
101
- "VC-ABUSE-004",
102
- ];
@@ -1,4 +0,0 @@
1
- import type { ScannerPack } from "../types.js";
2
- export declare const middlewarePack: ScannerPack;
3
- export { scanMissingRateLimit } from "./missing-rate-limit.js";
4
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/scanners/middleware/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG/C,eAAO,MAAM,cAAc,EAAE,WAI5B,CAAC;AAEF,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC"}
@@ -1,7 +0,0 @@
1
- import { scanMissingRateLimit } from "./missing-rate-limit.js";
2
- export const middlewarePack = {
3
- id: "middleware",
4
- name: "Middleware Security",
5
- scanners: [scanMissingRateLimit],
6
- };
7
- export { scanMissingRateLimit } from "./missing-rate-limit.js";
@@ -1,13 +0,0 @@
1
- import type { Finding } from "@vibecheck/schema";
2
- import type { ScanContext } from "../types.js";
3
- /**
4
- * VC-RATE-001: Missing rate limiting on public state-changing endpoints
5
- *
6
- * Only consider POST/PUT/PATCH/DELETE route handlers that:
7
- * - appear unauthenticated (no auth check)
8
- * - AND include a sink: DB write, email send, payment, or login/signup keywords
9
- *
10
- * If no rate-limit signals found in handler or middleware, flag it.
11
- */
12
- export declare function scanMissingRateLimit(context: ScanContext): Promise<Finding[]>;
13
- //# sourceMappingURL=missing-rate-limit.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"missing-rate-limit.d.ts","sourceRoot":"","sources":["../../../src/scanners/middleware/missing-rate-limit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAgB,MAAM,mBAAmB,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAgB/C;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAkInF"}
@@ -1,140 +0,0 @@
1
- import { resolvePath } from "../../utils/file-utils.js";
2
- import { generateFingerprint, generateFindingId } from "../../utils/fingerprint.js";
3
- const RULE_ID = "VC-RATE-001";
4
- /**
5
- * State-changing HTTP methods
6
- */
7
- const STATE_CHANGING_METHODS = ["POST", "PUT", "PATCH", "DELETE"];
8
- /**
9
- * Keywords that suggest sensitive operations
10
- */
11
- const SENSITIVE_SINK_PATTERNS = /create|insert|update|delete|send|email|mail|payment|charge|login|signup|register|auth|password|reset/i;
12
- /**
13
- * VC-RATE-001: Missing rate limiting on public state-changing endpoints
14
- *
15
- * Only consider POST/PUT/PATCH/DELETE route handlers that:
16
- * - appear unauthenticated (no auth check)
17
- * - AND include a sink: DB write, email send, payment, or login/signup keywords
18
- *
19
- * If no rate-limit signals found in handler or middleware, flag it.
20
- */
21
- export async function scanMissingRateLimit(context) {
22
- const { repoRoot, fileIndex, helpers } = context;
23
- const findings = [];
24
- // Check if middleware has rate limiting
25
- let middlewareHasRateLimit = false;
26
- if (fileIndex.middlewareFile) {
27
- const middlewarePath = resolvePath(repoRoot, fileIndex.middlewareFile);
28
- const middlewareSource = helpers.parseFile(middlewarePath);
29
- if (middlewareSource) {
30
- middlewareHasRateLimit = helpers.hasRateLimitSignals(middlewareSource);
31
- }
32
- }
33
- // If middleware already has rate limiting, skip this scanner
34
- if (middlewareHasRateLimit) {
35
- return findings;
36
- }
37
- // Scan API route files
38
- for (const relPath of fileIndex.apiRouteFiles) {
39
- const absPath = resolvePath(repoRoot, relPath);
40
- const sourceFile = helpers.parseFile(absPath);
41
- if (!sourceFile)
42
- continue;
43
- // Check if file has rate limiting
44
- const fileHasRateLimit = helpers.hasRateLimitSignals(sourceFile);
45
- if (fileHasRateLimit)
46
- continue;
47
- const handlers = helpers.findRouteHandlers(sourceFile);
48
- for (const handler of handlers) {
49
- // Only check state-changing methods
50
- if (!STATE_CHANGING_METHODS.includes(handler.method)) {
51
- continue;
52
- }
53
- // Check for auth - only flag unauthenticated endpoints
54
- const hasAuth = helpers.containsAuthCheck(handler.functionNode);
55
- if (hasAuth)
56
- continue;
57
- // Find sensitive sinks
58
- const dbSinks = helpers.findDbSinks(handler.functionNode);
59
- const handlerText = helpers.getNodeText(handler.functionNode);
60
- const hasSensitiveSink = dbSinks.length > 0 || SENSITIVE_SINK_PATTERNS.test(handlerText);
61
- if (!hasSensitiveSink)
62
- continue;
63
- const evidence = [
64
- {
65
- file: relPath,
66
- startLine: handler.startLine,
67
- endLine: handler.endLine,
68
- snippet: handlerText.slice(0, 200) + "...",
69
- label: `Unauthenticated ${handler.method} handler without rate limiting`,
70
- },
71
- ];
72
- // Add sink evidence
73
- if (dbSinks.length > 0) {
74
- evidence.push({
75
- file: relPath,
76
- startLine: dbSinks[0].line,
77
- endLine: dbSinks[0].line,
78
- snippet: dbSinks[0].snippet,
79
- label: `Sensitive operation: ${dbSinks[0].kind}.${dbSinks[0].operation}`,
80
- });
81
- }
82
- const fingerprint = generateFingerprint({
83
- ruleId: RULE_ID,
84
- file: relPath,
85
- symbol: handler.method,
86
- startLine: handler.startLine,
87
- });
88
- findings.push({
89
- id: generateFindingId({
90
- ruleId: RULE_ID,
91
- file: relPath,
92
- symbol: handler.method,
93
- startLine: handler.startLine,
94
- }),
95
- ruleId: RULE_ID,
96
- title: `Missing rate limiting on public ${handler.method} endpoint`,
97
- description: `This public (unauthenticated) ${handler.method} handler performs sensitive operations but lacks rate limiting. Without rate limiting, attackers can abuse this endpoint for credential stuffing, brute force attacks, or denial of service by overwhelming your resources.`,
98
- severity: "medium",
99
- confidence: 0.65,
100
- category: "middleware",
101
- evidence,
102
- remediation: {
103
- recommendedFix: `Add rate limiting to protect against abuse. Consider using @upstash/ratelimit for serverless, or express-rate-limit for Express apps.`,
104
- patch: `// Using @upstash/ratelimit with Vercel KV:
105
- import { Ratelimit } from "@upstash/ratelimit";
106
- import { kv } from "@vercel/kv";
107
-
108
- const ratelimit = new Ratelimit({
109
- redis: kv,
110
- limiter: Ratelimit.slidingWindow(10, "60 s"), // 10 requests per minute
111
- });
112
-
113
- export async function POST(request: Request) {
114
- const ip = request.headers.get("x-forwarded-for") ?? "127.0.0.1";
115
- const { success, limit, reset, remaining } = await ratelimit.limit(ip);
116
-
117
- if (!success) {
118
- return new Response("Too Many Requests", {
119
- status: 429,
120
- headers: {
121
- "X-RateLimit-Limit": limit.toString(),
122
- "X-RateLimit-Remaining": remaining.toString(),
123
- "X-RateLimit-Reset": reset.toString(),
124
- },
125
- });
126
- }
127
-
128
- // ... rest of handler
129
- }`,
130
- },
131
- links: {
132
- owasp: "https://cheatsheetseries.owasp.org/cheatsheets/Denial_of_Service_Cheat_Sheet.html",
133
- cwe: "https://cwe.mitre.org/data/definitions/770.html",
134
- },
135
- fingerprint,
136
- });
137
- }
138
- }
139
- return findings;
140
- }
@@ -1,14 +0,0 @@
1
- import type { Finding } from "@vibecheck/schema";
2
- import type { ScanContext } from "../types.js";
3
- /**
4
- * VC-NET-003: Over-permissive CORS with credentials
5
- *
6
- * Detects CORS configurations that combine:
7
- * - allowCredentials: true (or "Access-Control-Allow-Credentials: true")
8
- * AND
9
- * - allowOrigin: "*" (or reflects arbitrary origin unsafely)
10
- *
11
- * Two-signal: must see both wildcard origin AND credentials enabled
12
- */
13
- export declare function scanCorsMisconfiguration(context: ScanContext): Promise<Finding[]>;
14
- //# sourceMappingURL=cors-misconfiguration.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cors-misconfiguration.d.ts","sourceRoot":"","sources":["../../../src/scanners/network/cors-misconfiguration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAgB,MAAM,mBAAmB,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAM/C;;;;;;;;;GASG;AACH,wBAAsB,wBAAwB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAkFvF"}
@@ -1,89 +0,0 @@
1
- import { resolvePath } from "../../utils/file-utils.js";
2
- import { generateFingerprint, generateFindingId } from "../../utils/fingerprint.js";
3
- const RULE_ID = "VC-NET-003";
4
- /**
5
- * VC-NET-003: Over-permissive CORS with credentials
6
- *
7
- * Detects CORS configurations that combine:
8
- * - allowCredentials: true (or "Access-Control-Allow-Credentials: true")
9
- * AND
10
- * - allowOrigin: "*" (or reflects arbitrary origin unsafely)
11
- *
12
- * Two-signal: must see both wildcard origin AND credentials enabled
13
- */
14
- export async function scanCorsMisconfiguration(context) {
15
- const { repoRoot, fileIndex, helpers } = context;
16
- const findings = [];
17
- // Scan all source files for CORS configuration
18
- for (const relPath of fileIndex.allSourceFiles) {
19
- const absPath = resolvePath(repoRoot, relPath);
20
- const sourceFile = helpers.parseFile(absPath);
21
- if (!sourceFile)
22
- continue;
23
- const corsConfigs = helpers.findCorsConfig(sourceFile);
24
- for (const config of corsConfigs) {
25
- // Two-signal: only flag when BOTH wildcard origin AND credentials
26
- if (!config.hasWildcardOrigin || !config.hasCredentials) {
27
- continue;
28
- }
29
- const evidence = [
30
- {
31
- file: relPath,
32
- startLine: config.line,
33
- endLine: config.line,
34
- snippet: config.snippet,
35
- label: `CORS with origin: "${config.originValue}" and credentials: ${config.credentialsValue}`,
36
- },
37
- ];
38
- const fingerprint = generateFingerprint({
39
- ruleId: RULE_ID,
40
- file: relPath,
41
- symbol: "cors",
42
- startLine: config.line,
43
- });
44
- findings.push({
45
- id: generateFindingId({
46
- ruleId: RULE_ID,
47
- file: relPath,
48
- symbol: "cors",
49
- startLine: config.line,
50
- }),
51
- ruleId: RULE_ID,
52
- title: "Over-permissive CORS with credentials",
53
- description: `The CORS configuration allows credentials (cookies, auth headers) to be sent with requests from any origin (*). This is dangerous because it allows any website to make authenticated requests to your API on behalf of logged-in users, enabling CSRF-like attacks. Browsers will actually block this specific combination, but the intent suggests a security misunderstanding.`,
54
- severity: "high",
55
- confidence: 0.9,
56
- category: "network",
57
- evidence,
58
- remediation: {
59
- recommendedFix: `When using credentials, you must specify explicit allowed origins instead of "*". Use an allowlist of trusted domains.`,
60
- patch: `// Instead of:
61
- // cors({ origin: "*", credentials: true })
62
-
63
- // Use an allowlist:
64
- const allowedOrigins = [
65
- 'https://app.example.com',
66
- 'https://admin.example.com',
67
- ];
68
-
69
- app.use(cors({
70
- origin: (origin, callback) => {
71
- if (!origin || allowedOrigins.includes(origin)) {
72
- callback(null, true);
73
- } else {
74
- callback(new Error('Not allowed by CORS'));
75
- }
76
- },
77
- credentials: true,
78
- }));`,
79
- },
80
- links: {
81
- cwe: "https://cwe.mitre.org/data/definitions/942.html",
82
- owasp: "https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/11-Client-side_Testing/07-Testing_Cross_Origin_Resource_Sharing",
83
- },
84
- fingerprint,
85
- });
86
- }
87
- }
88
- return findings;
89
- }
@@ -1,7 +0,0 @@
1
- import type { ScannerPack } from "../types.js";
2
- export declare const networkPack: ScannerPack;
3
- export { scanSsrfProneFetch } from "./ssrf-prone-fetch.js";
4
- export { scanOpenRedirect } from "./open-redirect.js";
5
- export { scanCorsMisconfiguration } from "./cors-misconfiguration.js";
6
- export { scanMissingTimeout } from "./missing-timeout.js";
7
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/scanners/network/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAM/C,eAAO,MAAM,WAAW,EAAE,WASzB,CAAC;AAEF,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
@@ -1,18 +0,0 @@
1
- import { scanSsrfProneFetch } from "./ssrf-prone-fetch.js";
2
- import { scanOpenRedirect } from "./open-redirect.js";
3
- import { scanCorsMisconfiguration } from "./cors-misconfiguration.js";
4
- import { scanMissingTimeout } from "./missing-timeout.js";
5
- export const networkPack = {
6
- id: "network",
7
- name: "Network Security",
8
- scanners: [
9
- scanSsrfProneFetch,
10
- scanOpenRedirect,
11
- scanCorsMisconfiguration,
12
- scanMissingTimeout,
13
- ],
14
- };
15
- export { scanSsrfProneFetch } from "./ssrf-prone-fetch.js";
16
- export { scanOpenRedirect } from "./open-redirect.js";
17
- export { scanCorsMisconfiguration } from "./cors-misconfiguration.js";
18
- export { scanMissingTimeout } from "./missing-timeout.js";
@@ -1,15 +0,0 @@
1
- import type { Finding } from "@vibecheck/schema";
2
- import type { ScanContext } from "../types.js";
3
- /**
4
- * VC-NET-004: Missing request timeout on outbound calls
5
- *
6
- * Detects axios/fetch usage without explicit timeout:
7
- * - axios(...) without timeout option
8
- * - fetch(...) without AbortController / timeout wrapper
9
- *
10
- * Precision rule:
11
- * - Only flag when outbound call is inside a route handler (app/api/**) AND
12
- * - Call appears to hit non-localhost URL (string literal starting http)
13
- */
14
- export declare function scanMissingTimeout(context: ScanContext): Promise<Finding[]>;
15
- //# sourceMappingURL=missing-timeout.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"missing-timeout.d.ts","sourceRoot":"","sources":["../../../src/scanners/network/missing-timeout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAgB,MAAM,mBAAmB,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAM/C;;;;;;;;;;GAUG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAqFjF"}