@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
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@oculum/scanner",
3
+ "version": "1.0.0",
4
+ "description": "AI-native security scanner for detecting vulnerabilities in LLM-generated code",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.js",
11
+ "require": "./dist/index.js"
12
+ },
13
+ "./formatters": {
14
+ "types": "./dist/formatters/index.d.ts",
15
+ "import": "./dist/formatters/index.js",
16
+ "require": "./dist/formatters/index.js"
17
+ },
18
+ "./types": {
19
+ "types": "./dist/types.d.ts",
20
+ "import": "./dist/types.js",
21
+ "require": "./dist/types.js"
22
+ }
23
+ },
24
+ "scripts": {
25
+ "build": "tsc",
26
+ "dev": "tsc --watch",
27
+ "test": "echo \"No tests configured yet\"",
28
+ "lint": "eslint src/"
29
+ },
30
+ "dependencies": {
31
+ "@anthropic-ai/sdk": "^0.71.2",
32
+ "openai": "^6.16.0"
33
+ },
34
+ "devDependencies": {
35
+ "@types/jest": "^30.0.0",
36
+ "@types/node": "^20",
37
+ "jest": "^29.7.0",
38
+ "ts-jest": "^29.4.6",
39
+ "typescript": "^5"
40
+ },
41
+ "files": [
42
+ "dist",
43
+ "src"
44
+ ]
45
+ }
@@ -0,0 +1,227 @@
1
+ /**
2
+ * False Positive Test Fixtures
3
+ * Files that should NOT generate high-severity findings
4
+ */
5
+
6
+ import type { TestFixture } from '../types'
7
+
8
+ /**
9
+ * Test/Mock files should be ignored
10
+ */
11
+ export const testFileFixture: TestFixture = {
12
+ name: 'Test File - Should Not Flag',
13
+ expectFindings: false,
14
+ description: 'Test files with mock data should not generate high-severity findings',
15
+ file: {
16
+ path: 'src/__tests__/auth.test.ts',
17
+ content: `
18
+ // Test file - all these should be SAFE
19
+ const TEST_API_KEY = "sk-test-12345"
20
+ const MOCK_SECRET = "mock-secret-for-testing"
21
+
22
+ describe('Authentication', () => {
23
+ it('should authenticate with valid key', async () => {
24
+ const result = await authenticate(TEST_API_KEY)
25
+ expect(result).toBeTruthy()
26
+ })
27
+
28
+ it('should reject eval for testing', () => {
29
+ // Testing eval handling
30
+ expect(() => eval('1+1')).not.toThrow()
31
+ })
32
+ })
33
+ `,
34
+ language: 'typescript',
35
+ size: 400,
36
+ },
37
+ }
38
+
39
+ /**
40
+ * Example/documentation files should be ignored
41
+ */
42
+ export const exampleFileFixture: TestFixture = {
43
+ name: 'Example File - Should Not Flag',
44
+ expectFindings: false,
45
+ description: 'Example files with placeholder values should not be flagged',
46
+ file: {
47
+ path: 'examples/getting-started.ts',
48
+ content: `
49
+ // Example file - all these should be SAFE
50
+ const EXAMPLE_API_KEY = "your-api-key-here"
51
+ const SAMPLE_SECRET = "replace-with-your-secret"
52
+
53
+ // Example usage
54
+ const client = new Client({
55
+ apiKey: EXAMPLE_API_KEY
56
+ })
57
+
58
+ // Example SQL (for documentation)
59
+ const exampleQuery = "SELECT * FROM users WHERE id = '" + userId + "'"
60
+ `,
61
+ language: 'typescript',
62
+ size: 300,
63
+ },
64
+ }
65
+
66
+ /**
67
+ * Configuration files with env vars should be mostly safe
68
+ */
69
+ export const configFileFixture: TestFixture = {
70
+ name: 'Config File - Should Not Flag',
71
+ expectFindings: false,
72
+ description: 'Config files using environment variables should be safe',
73
+ file: {
74
+ path: 'src/config/index.ts',
75
+ content: `
76
+ // All from environment - SAFE
77
+ export const config = {
78
+ database: {
79
+ url: process.env.DATABASE_URL!,
80
+ poolSize: parseInt(process.env.DB_POOL_SIZE || '10'),
81
+ },
82
+ auth: {
83
+ secret: process.env.JWT_SECRET!,
84
+ expiresIn: process.env.JWT_EXPIRES_IN || '7d',
85
+ },
86
+ api: {
87
+ openaiKey: process.env.OPENAI_API_KEY!,
88
+ anthropicKey: process.env.ANTHROPIC_API_KEY!,
89
+ },
90
+ }
91
+
92
+ // Type checking
93
+ if (!config.database.url) {
94
+ throw new Error('DATABASE_URL is required')
95
+ }
96
+ `,
97
+ language: 'typescript',
98
+ size: 500,
99
+ },
100
+ }
101
+
102
+ /**
103
+ * Middleware file that protects routes
104
+ */
105
+ export const middlewareFileFixture: TestFixture = {
106
+ name: 'Middleware - Should Detect Auth',
107
+ expectFindings: false,
108
+ description: 'Middleware files should not generate auth warnings',
109
+ file: {
110
+ path: 'middleware.ts',
111
+ content: `
112
+ import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server'
113
+
114
+ const isPublicRoute = createRouteMatcher([
115
+ '/sign-in(.*)',
116
+ '/sign-up(.*)',
117
+ '/api/webhook(.*)',
118
+ '/',
119
+ ])
120
+
121
+ export default clerkMiddleware((auth, request) => {
122
+ if (!isPublicRoute(request)) {
123
+ auth().protect()
124
+ }
125
+ })
126
+
127
+ export const config = {
128
+ matcher: ['/((?!.+\\.[\\w]+$|_next).*)', '/', '/(api|trpc)(.*)'],
129
+ }
130
+ `,
131
+ language: 'typescript',
132
+ size: 400,
133
+ },
134
+ }
135
+
136
+ /**
137
+ * Routes under /api should NOT be flagged (protected by middleware)
138
+ */
139
+ export const protectedApiRouteFixture: TestFixture = {
140
+ name: 'Protected Route - Should Not Flag Missing Auth',
141
+ expectFindings: false,
142
+ description: 'Routes protected by middleware should not be flagged for missing auth',
143
+ file: {
144
+ path: 'app/api/user/settings/route.ts',
145
+ content: `
146
+ import { NextResponse } from 'next/server'
147
+ import { db } from '@/lib/db'
148
+ import { getCurrentUserId } from '@/lib/auth'
149
+
150
+ // Protected by Clerk middleware - Should NOT flag as missing auth
151
+ export async function GET() {
152
+ const userId = await getCurrentUserId() // Throws if not authenticated
153
+
154
+ const settings = await db.settings.findUnique({
155
+ where: { userId }
156
+ })
157
+
158
+ return NextResponse.json(settings)
159
+ }
160
+
161
+ export async function PUT(request: Request) {
162
+ const userId = await getCurrentUserId()
163
+ const body = await request.json()
164
+
165
+ await db.settings.update({
166
+ where: { userId },
167
+ data: body
168
+ })
169
+
170
+ return NextResponse.json({ success: true })
171
+ }
172
+ `,
173
+ language: 'typescript',
174
+ size: 600,
175
+ },
176
+ }
177
+
178
+ /**
179
+ * Documentation/README files
180
+ */
181
+ export const documentationFixture: TestFixture = {
182
+ name: 'Documentation - Should Not Flag',
183
+ expectFindings: false,
184
+ description: 'Documentation files should not be flagged',
185
+ file: {
186
+ path: 'docs/API_GUIDE.md',
187
+ content: `
188
+ # API Guide
189
+
190
+ ## Authentication
191
+
192
+ To authenticate, you need an API key:
193
+
194
+ \`\`\`typescript
195
+ const client = new Client({
196
+ apiKey: "sk-your-api-key-here"
197
+ })
198
+ \`\`\`
199
+
200
+ ## Example Query
201
+
202
+ \`\`\`sql
203
+ SELECT * FROM users WHERE id = 'user_123'
204
+ \`\`\`
205
+
206
+ ## Configuration
207
+
208
+ Set these environment variables:
209
+ - \`API_KEY=your-api-key\`
210
+ - \`DATABASE_URL=postgresql://localhost/mydb\`
211
+ `,
212
+ language: 'markdown',
213
+ size: 400,
214
+ },
215
+ }
216
+
217
+ /**
218
+ * All false positive fixtures
219
+ */
220
+ export const falsePositiveFixtures: TestFixture[] = [
221
+ testFileFixture,
222
+ exampleFileFixture,
223
+ configFileFixture,
224
+ middlewareFileFixture,
225
+ protectedApiRouteFixture,
226
+ documentationFixture,
227
+ ]
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Main Fixtures Index
3
+ * Exports all test fixtures for the security benchmark suite
4
+ */
5
+
6
+ // Layer 1 fixtures
7
+ export * from './layer1'
8
+ export { layer1TestGroups, highEntropyTests } from './layer1'
9
+
10
+ // Layer 2 fixtures
11
+ export * from './layer2'
12
+ export { layer2TestGroups } from './layer2'
13
+
14
+ // False positive fixtures
15
+ export { falsePositiveFixtures } from './false-positives'
16
+ export {
17
+ testFileFixture,
18
+ exampleFileFixture,
19
+ configFileFixture,
20
+ middlewareFileFixture,
21
+ protectedApiRouteFixture,
22
+ documentationFixture,
23
+ } from './false-positives'
24
+
25
+ import type { TestGroup, TestFixture } from '../types'
26
+ import { layer1TestGroups, highEntropyTests } from './layer1'
27
+ import { layer2TestGroups } from './layer2'
28
+ import { falsePositiveFixtures } from './false-positives'
29
+
30
+ /**
31
+ * All test groups organized by layer and tier
32
+ */
33
+ export const allTestGroups: TestGroup[] = [
34
+ ...layer1TestGroups,
35
+ highEntropyTests,
36
+ ...layer2TestGroups,
37
+ ]
38
+
39
+ /**
40
+ * Get all true positive fixtures
41
+ */
42
+ export function getAllTruePositives(): TestFixture[] {
43
+ return allTestGroups.flatMap(group => group.truePositives)
44
+ }
45
+
46
+ /**
47
+ * Get all false negative fixtures
48
+ */
49
+ export function getAllFalseNegatives(): TestFixture[] {
50
+ return [
51
+ ...allTestGroups.flatMap(group => group.falseNegatives),
52
+ ...falsePositiveFixtures,
53
+ ]
54
+ }
55
+
56
+ /**
57
+ * Get test groups by layer
58
+ */
59
+ export function getTestGroupsByLayer(layer: 1 | 2): TestGroup[] {
60
+ return allTestGroups.filter(group => group.layer === layer)
61
+ }
62
+
63
+ /**
64
+ * Get test groups by tier
65
+ */
66
+ export function getTestGroupsByTier(tier: 'A' | 'B' | 'C'): TestGroup[] {
67
+ return allTestGroups.filter(group => group.tier === tier)
68
+ }
@@ -0,0 +1,364 @@
1
+ /**
2
+ * Configuration Audit Test Fixtures
3
+ * Tests for detecting security misconfigurations in config files
4
+ */
5
+
6
+ import type { TestGroup } from '../../types'
7
+
8
+ export const configAuditTests: TestGroup = {
9
+ name: 'Configuration Auditing',
10
+ tier: 'B',
11
+ layer: 1,
12
+ description: 'Detection of security misconfigurations in Dockerfile, CORS, Next.js, and package.json',
13
+
14
+ truePositives: [
15
+ {
16
+ name: 'Dockerfile Security Issues',
17
+ expectFindings: true,
18
+ expectedCategories: ['insecure_config'],
19
+ description: 'Dockerfile misconfigurations that MUST be detected',
20
+ file: {
21
+ path: 'Dockerfile',
22
+ content: `
23
+ FROM node:18-alpine
24
+
25
+ WORKDIR /app
26
+
27
+ COPY package*.json ./
28
+ RUN npm install
29
+
30
+ COPY . .
31
+
32
+ # Explicitly running as root - HIGH
33
+ USER root
34
+
35
+ # Hardcoded secrets in build args - CRITICAL
36
+ ARG DATABASE_PASSWORD=supersecret123
37
+ ARG API_SECRET_KEY=sk-live-abc123
38
+ ENV JWT_SECRET=my-jwt-signing-key
39
+ ENV DB_PASSWORD=production-db-pass
40
+
41
+ EXPOSE 3000
42
+
43
+ CMD ["npm", "start"]
44
+ `,
45
+ language: 'dockerfile',
46
+ size: 350,
47
+ },
48
+ },
49
+ {
50
+ name: 'Permissive CORS Configuration',
51
+ expectFindings: true,
52
+ expectedCategories: ['insecure_config'],
53
+ description: 'Wildcard CORS that MUST be detected',
54
+ file: {
55
+ path: 'src/server/cors.ts',
56
+ content: `
57
+ import express from 'express'
58
+ import cors from 'cors'
59
+
60
+ const app = express()
61
+
62
+ // Permissive CORS - MEDIUM
63
+ app.use(cors({
64
+ origin: '*',
65
+ credentials: true,
66
+ }))
67
+
68
+ // Another pattern - MEDIUM
69
+ const headers = {
70
+ 'Access-Control-Allow-Origin': '*',
71
+ 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE',
72
+ }
73
+
74
+ // Config object pattern - MEDIUM
75
+ const corsConfig = {
76
+ allowedOrigins: ['*'],
77
+ origin: '*',
78
+ }
79
+
80
+ // In response header
81
+ res.setHeader('Access-Control-Allow-Origin', '*')
82
+ `,
83
+ language: 'typescript',
84
+ size: 450,
85
+ },
86
+ },
87
+ {
88
+ name: 'Next.js Security Config',
89
+ expectFindings: true,
90
+ expectedCategories: ['insecure_config'],
91
+ description: 'Next.js security misconfigurations that MUST be detected',
92
+ file: {
93
+ path: 'next.config.js',
94
+ content: `
95
+ /** @type {import('next').NextConfig} */
96
+ const nextConfig = {
97
+ // Exposing X-Powered-By header - LOW
98
+ poweredByHeader: true,
99
+
100
+ // Exposing source maps in production - MEDIUM
101
+ productionBrowserSourceMaps: true,
102
+
103
+ // Other config
104
+ reactStrictMode: true,
105
+ images: {
106
+ domains: ['cdn.example.com'],
107
+ },
108
+ }
109
+
110
+ module.exports = nextConfig
111
+ `,
112
+ language: 'javascript',
113
+ size: 300,
114
+ },
115
+ },
116
+ {
117
+ name: 'Package.json Security Issues',
118
+ expectFindings: true,
119
+ expectedCategories: ['insecure_config'],
120
+ description: 'Package.json security issues that MUST be detected',
121
+ file: {
122
+ path: 'package.json',
123
+ content: `{
124
+ "name": "my-app",
125
+ "version": "1.0.0",
126
+ "scripts": {
127
+ "start": "node index.js",
128
+ "postinstall": "node scripts/setup.js",
129
+ "preinstall": "node scripts/verify.js"
130
+ },
131
+ "dependencies": {
132
+ "express": "*",
133
+ "lodash": "latest",
134
+ "axios": "^1.0.0"
135
+ },
136
+ "devDependencies": {
137
+ "jest": "*"
138
+ }
139
+ }`,
140
+ language: 'json',
141
+ size: 350,
142
+ },
143
+ },
144
+ {
145
+ name: 'Dockerfile Without USER',
146
+ expectFindings: true,
147
+ expectedCategories: ['insecure_config'],
148
+ description: 'Dockerfile without USER instruction runs as root by default',
149
+ file: {
150
+ path: 'services/api/Dockerfile',
151
+ content: `
152
+ FROM python:3.11-slim
153
+
154
+ WORKDIR /app
155
+
156
+ COPY requirements.txt .
157
+ RUN pip install -r requirements.txt
158
+
159
+ COPY . .
160
+
161
+ EXPOSE 8000
162
+
163
+ # No USER instruction - runs as root by default - MEDIUM
164
+ CMD ["python", "app.py"]
165
+ `,
166
+ language: 'dockerfile',
167
+ size: 200,
168
+ },
169
+ },
170
+ ],
171
+
172
+ falseNegatives: [
173
+ {
174
+ name: 'Safe Dockerfile Configuration',
175
+ expectFindings: false,
176
+ description: 'Properly configured Dockerfile that should NOT be flagged',
177
+ allowedInfoFindings: [
178
+ {
179
+ category: 'insecure_config',
180
+ maxCount: 1,
181
+ reason: 'Some patterns may generate low-severity findings',
182
+ },
183
+ ],
184
+ file: {
185
+ path: 'Dockerfile',
186
+ content: `
187
+ FROM node:18-alpine
188
+
189
+ WORKDIR /app
190
+
191
+ COPY package*.json ./
192
+ RUN npm install --production
193
+
194
+ COPY . .
195
+
196
+ # Running as non-root user - SAFE
197
+ USER node
198
+
199
+ # Secrets from build args without defaults - SAFE
200
+ ARG DATABASE_URL
201
+ ENV DATABASE_URL=\${DATABASE_URL}
202
+
203
+ EXPOSE 3000
204
+
205
+ CMD ["npm", "start"]
206
+ `,
207
+ language: 'dockerfile',
208
+ size: 250,
209
+ },
210
+ },
211
+ {
212
+ name: 'Safe Docker Compose',
213
+ expectFindings: false,
214
+ description: 'Docker Compose with secrets from env vars should NOT be flagged',
215
+ file: {
216
+ path: 'docker-compose.yml',
217
+ content: `
218
+ version: '3.8'
219
+
220
+ services:
221
+ app:
222
+ build: .
223
+ ports:
224
+ - "3000:3000"
225
+ environment:
226
+ # Secrets from environment variables - SAFE
227
+ DATABASE_PASSWORD: \${DATABASE_PASSWORD}
228
+ API_KEY: \${API_KEY}
229
+ JWT_SECRET: \${JWT_SECRET}
230
+ env_file:
231
+ - .env
232
+
233
+ db:
234
+ image: postgres:15
235
+ environment:
236
+ POSTGRES_PASSWORD: \${POSTGRES_PASSWORD}
237
+ `,
238
+ language: 'yaml',
239
+ size: 350,
240
+ },
241
+ },
242
+ {
243
+ name: 'Safe CORS Configuration',
244
+ expectFindings: false,
245
+ description: 'Properly configured CORS should NOT be flagged',
246
+ allowedInfoFindings: [
247
+ {
248
+ category: 'insecure_config',
249
+ maxCount: 1,
250
+ reason: 'CORS patterns may generate low-severity findings',
251
+ },
252
+ {
253
+ category: 'sensitive_url',
254
+ maxCount: 2,
255
+ reason: 'URLs in CORS config may trigger URL detection',
256
+ },
257
+ {
258
+ category: 'ai_pattern',
259
+ maxCount: 1,
260
+ reason: 'Function-based patterns may trigger AI detection',
261
+ },
262
+ ],
263
+ file: {
264
+ path: 'src/config/cors-config.ts',
265
+ content: `
266
+ // Environment-based CORS configuration - SAFE
267
+ export const corsConfig = {
268
+ origin: process.env.ALLOWED_ORIGINS?.split(','),
269
+ credentials: true,
270
+ }
271
+ `,
272
+ language: 'typescript',
273
+ size: 100,
274
+ },
275
+ },
276
+ {
277
+ name: 'Safe Next.js Config',
278
+ expectFindings: false,
279
+ description: 'Secure Next.js configuration should NOT be flagged',
280
+ file: {
281
+ path: 'next.config.js',
282
+ content: `
283
+ /** @type {import('next').NextConfig} */
284
+ const nextConfig = {
285
+ // Disabled header - SAFE (or omitted entirely)
286
+ poweredByHeader: false,
287
+
288
+ // Source maps disabled - SAFE
289
+ productionBrowserSourceMaps: false,
290
+
291
+ reactStrictMode: true,
292
+
293
+ // Security headers
294
+ async headers() {
295
+ return [
296
+ {
297
+ source: '/:path*',
298
+ headers: [
299
+ { key: 'X-Frame-Options', value: 'DENY' },
300
+ { key: 'X-Content-Type-Options', value: 'nosniff' },
301
+ ],
302
+ },
303
+ ]
304
+ },
305
+ }
306
+
307
+ module.exports = nextConfig
308
+ `,
309
+ language: 'javascript',
310
+ size: 400,
311
+ },
312
+ },
313
+ {
314
+ name: 'Safe Package.json',
315
+ expectFindings: false,
316
+ description: 'Properly configured package.json should NOT be flagged',
317
+ file: {
318
+ path: 'package.json',
319
+ content: `{
320
+ "name": "my-app",
321
+ "version": "1.0.0",
322
+ "scripts": {
323
+ "start": "node index.js",
324
+ "build": "tsc",
325
+ "test": "jest"
326
+ },
327
+ "dependencies": {
328
+ "express": "^4.18.2",
329
+ "lodash": "^4.17.21",
330
+ "axios": "~1.6.0"
331
+ },
332
+ "devDependencies": {
333
+ "jest": "^29.7.0",
334
+ "typescript": "^5.3.0"
335
+ }
336
+ }`,
337
+ language: 'json',
338
+ size: 300,
339
+ },
340
+ },
341
+ {
342
+ name: 'Example/Template Configs',
343
+ expectFindings: false,
344
+ description: 'Example configs with placeholders should NOT be flagged',
345
+ file: {
346
+ path: 'docker-compose.example.yml',
347
+ content: `
348
+ version: '3.8'
349
+
350
+ services:
351
+ app:
352
+ build: .
353
+ environment:
354
+ # Replace with your actual values
355
+ DATABASE_PASSWORD: <YOUR_PASSWORD_HERE>
356
+ API_KEY: your-api-key-here
357
+ JWT_SECRET: CHANGEME
358
+ `,
359
+ language: 'yaml',
360
+ size: 200,
361
+ },
362
+ },
363
+ ],
364
+ }