@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,246 @@
1
+ /**
2
+ * Logic Gates Test Fixtures
3
+ * Tests for detecting security bypass patterns and dangerous logic flows
4
+ */
5
+
6
+ import type { TestGroup } from '../../types'
7
+
8
+ export const logicGatesTests: TestGroup = {
9
+ name: 'Logic Gates / Security Bypass',
10
+ tier: 'C',
11
+ layer: 2,
12
+ description: 'Detection of security bypass patterns, debug flags, and dangerous logic flows',
13
+
14
+ truePositives: [
15
+ {
16
+ name: 'Security Bypass - True Positives',
17
+ expectFindings: true,
18
+ expectedCategories: ['security_bypass'],
19
+ description: 'Security bypass patterns that MUST be detected',
20
+ file: {
21
+ path: 'src/middleware/auth.ts',
22
+ content: `
23
+ import { NextRequest, NextResponse } from 'next/server'
24
+
25
+ // Development mode security bypass - HIGH
26
+ export function authMiddleware(req: NextRequest) {
27
+ if (process.env.NODE_ENV !== 'production') return true
28
+ if (process.env.NODE_ENV === 'development') {
29
+ return NextResponse.next()
30
+ }
31
+
32
+ // Auth bypass with hardcoded true - CRITICAL
33
+ if (true) {
34
+ return NextResponse.next()
35
+ }
36
+
37
+ // Debug bypass flags - HIGH
38
+ if (DEBUG) {
39
+ return NextResponse.next()
40
+ }
41
+ if (SKIP_AUTH) {
42
+ return true
43
+ }
44
+ if (BYPASS) {
45
+ return allow()
46
+ }
47
+
48
+ return verifyAuth(req)
49
+ }
50
+
51
+ // Commented auth check - HIGH
52
+ export async function handler(req: Request) {
53
+ // if (!user) return unauthorized
54
+ // await verifyToken(token)
55
+ // check permission before proceeding
56
+ return processRequest(req)
57
+ }
58
+
59
+ // Validation skip patterns - HIGH
60
+ const config = {
61
+ skipValidation: true,
62
+ validate: false,
63
+ noValidate: true,
64
+ }
65
+
66
+ // Disabled CSRF protection - HIGH
67
+ const securityOptions = {
68
+ csrf: false,
69
+ csrfProtection: false,
70
+ }
71
+
72
+ // Disabled SSL verification - CRITICAL
73
+ const httpsOptions = {
74
+ rejectUnauthorized: false,
75
+ verify: false,
76
+ ssl: false,
77
+ }
78
+ process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'
79
+
80
+ // Unsafe default allow - MEDIUM
81
+ function checkPermission(role: string) {
82
+ switch (role) {
83
+ case 'admin': return true
84
+ case 'user': return limited()
85
+ default: return true // Unsafe!
86
+ }
87
+ }
88
+
89
+ // Empty error handler - MEDIUM
90
+ try {
91
+ await riskyOperation()
92
+ } catch (e) {
93
+ // silently ignore
94
+ }
95
+
96
+ try {
97
+ await anotherOperation()
98
+ } catch (error) {}
99
+
100
+ // Open redirect vulnerability - HIGH
101
+ app.get('/redirect', (req, res) => {
102
+ redirect(req.query.url)
103
+ redirect(req.params.destination)
104
+ redirect(request.body.redirectUrl)
105
+ })
106
+
107
+ // Timing attack vulnerable comparison - MEDIUM
108
+ function verifySecret(input: string) {
109
+ if (input === 'super-secret-value-12345678')
110
+ if (token === userToken)
111
+ if (password === storedPassword)
112
+ if (secret === expectedSecret)
113
+ }
114
+
115
+ // Admin bypass pattern - MEDIUM
116
+ function checkAccess(user: User) {
117
+ if (isAdmin) return true
118
+ if (isSuperUser) continue
119
+ if (role === 'admin') return
120
+ }
121
+ `,
122
+ language: 'typescript',
123
+ size: 1800,
124
+ },
125
+ },
126
+ ],
127
+
128
+ falseNegatives: [
129
+ {
130
+ name: 'Security Bypass - False Negatives',
131
+ expectFindings: false,
132
+ description: 'Safe patterns that should NOT be flagged as security bypasses',
133
+ allowedInfoFindings: [
134
+ {
135
+ category: 'security_bypass',
136
+ maxCount: 5,
137
+ reason: 'Development mode checks may still generate low-severity findings',
138
+ },
139
+ {
140
+ category: 'ai_pattern',
141
+ maxCount: 3,
142
+ reason: 'Catch blocks and feature flags may trigger ai-fingerprinting at info level',
143
+ },
144
+ {
145
+ category: 'insecure_config',
146
+ maxCount: 2,
147
+ reason: 'Config patterns may trigger config detection',
148
+ },
149
+ {
150
+ category: 'data_exposure',
151
+ maxCount: 2,
152
+ reason: 'Error handling patterns may trigger data exposure detection',
153
+ },
154
+ {
155
+ category: 'dangerous_function',
156
+ maxCount: 2,
157
+ reason: 'URL operations may trigger dangerous function detection',
158
+ },
159
+ ],
160
+ file: {
161
+ path: 'src/middleware/safe-auth.ts',
162
+ content: `
163
+ import { NextRequest, NextResponse } from 'next/server'
164
+ import crypto from 'crypto'
165
+
166
+ // Auth middleware with proper checks - SAFE
167
+ export function authMiddleware(req: NextRequest) {
168
+ const token = req.headers.get('authorization')
169
+ if (!token) {
170
+ return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
171
+ }
172
+ return NextResponse.next()
173
+ }
174
+
175
+ // Proper error handling - SAFE
176
+ try {
177
+ await riskyOperation()
178
+ } catch (error) {
179
+ console.error('Operation failed:', error)
180
+ throw new Error('Operation failed')
181
+ }
182
+
183
+ // Proper secret comparison using timing-safe - SAFE
184
+ function verifySecret(input: string, expected: string) {
185
+ const inputBuffer = Buffer.from(input)
186
+ const expectedBuffer = Buffer.from(expected)
187
+ return crypto.timingSafeEqual(inputBuffer, expectedBuffer)
188
+ }
189
+
190
+ // Default deny pattern - SAFE
191
+ function checkPermission(role: string) {
192
+ switch (role) {
193
+ case 'admin': return true
194
+ case 'user': return limited()
195
+ default: return false // Safe default deny
196
+ }
197
+ }
198
+ `,
199
+ language: 'typescript',
200
+ size: 700,
201
+ },
202
+ },
203
+ {
204
+ name: 'Test File Patterns',
205
+ expectFindings: false,
206
+ description: 'Security bypass patterns in test files are expected',
207
+ allowedInfoFindings: [
208
+ {
209
+ category: 'security_bypass',
210
+ maxCount: 8,
211
+ reason: 'Test files intentionally have bypass patterns for testing',
212
+ },
213
+ {
214
+ category: 'insecure_config',
215
+ maxCount: 3,
216
+ reason: 'Test configs may trigger config detection',
217
+ },
218
+ {
219
+ category: 'ai_pattern',
220
+ maxCount: 2,
221
+ reason: 'Test patterns may trigger AI detection',
222
+ },
223
+ ],
224
+ file: {
225
+ path: 'src/__tests__/auth.test.ts',
226
+ content: `
227
+ import { describe, it, expect, vi } from 'vitest'
228
+
229
+ describe('Auth middleware', () => {
230
+ it('should authenticate valid users', () => {
231
+ const result = authenticate({ token: 'valid' })
232
+ expect(result.authenticated).toBe(true)
233
+ })
234
+
235
+ it('should reject invalid users', () => {
236
+ const result = authenticate({ token: 'invalid' })
237
+ expect(result.authenticated).toBe(false)
238
+ })
239
+ })
240
+ `,
241
+ language: 'typescript',
242
+ size: 300,
243
+ },
244
+ },
245
+ ],
246
+ }
@@ -0,0 +1,231 @@
1
+ /**
2
+ * Risky Imports Test Fixtures
3
+ * Tests for detecting deprecated, vulnerable, or risky package imports
4
+ */
5
+
6
+ import type { TestGroup } from '../../types'
7
+
8
+ export const riskyImportsTests: TestGroup = {
9
+ name: 'Risky Imports',
10
+ tier: 'C',
11
+ layer: 2,
12
+ description: 'Detection of deprecated, vulnerable, or risky package imports',
13
+
14
+ truePositives: [
15
+ {
16
+ name: 'Risky Imports - True Positives (JavaScript/TypeScript)',
17
+ expectFindings: true,
18
+ expectedCategories: ['suspicious_package'],
19
+ description: 'Risky package imports that MUST be detected',
20
+ file: {
21
+ path: 'src/lib/http-client.ts',
22
+ content: `
23
+ // Deprecated packages - MEDIUM/LOW
24
+ import request from 'request'
25
+ const request = require('request')
26
+
27
+ import uuid from 'node-uuid'
28
+ const nodeUuid = require('node-uuid')
29
+
30
+ // Full lodash import (bundle size/attack surface) - LOW
31
+ import _ from 'lodash'
32
+ import * as lodash from 'lodash'
33
+ const _ = require('lodash')
34
+
35
+ // Deprecated moment.js - LOW
36
+ import moment from 'moment'
37
+ const moment = require('moment')
38
+
39
+ // Deprecated bcrypt-nodejs - MEDIUM
40
+ import bcrypt from 'bcrypt-nodejs'
41
+ const bcrypt = require('bcrypt-nodejs')
42
+
43
+ // Less maintained mysql package - LOW
44
+ import mysql from 'mysql'
45
+ const mysql = require('mysql')
46
+
47
+ // Outdated crypto - LOW
48
+ import CryptoJS from 'crypto-js'
49
+
50
+ // serialize-javascript RCE risk - MEDIUM
51
+ import serialize from 'serialize-javascript'
52
+
53
+ // express-jwt CVE history - MEDIUM
54
+ import expressJwt from 'express-jwt'
55
+ const jwt = require('express-jwt')
56
+
57
+ // Native module concerns - LOW
58
+ import gyp from 'node-gyp'
59
+
60
+ // Analytics packages (privacy) - LOW
61
+ import analytics from 'analytics'
62
+ import segment from 'segment'
63
+ import mixpanel from 'mixpanel'
64
+ import amplitude from 'amplitude'
65
+
66
+ // vm2 sandbox (info - for awareness) - INFO
67
+ import { VM } from 'vm2'
68
+ const vm2 = require('vm2')
69
+ `,
70
+ language: 'typescript',
71
+ size: 1000,
72
+ },
73
+ },
74
+ {
75
+ name: 'Risky Imports - True Positives (Python)',
76
+ expectFindings: true,
77
+ expectedCategories: ['suspicious_package'],
78
+ description: 'Python risky patterns that MUST be detected',
79
+ file: {
80
+ path: 'src/scripts/processor.py',
81
+ content: `
82
+ # Pickle unsafe deserialization - HIGH
83
+ import pickle
84
+ from pickle import load, dump
85
+
86
+ # Load pickle data from file
87
+ data = pickle.load(open('data.pkl', 'rb'))
88
+
89
+ # YAML unsafe load - HIGH
90
+ import yaml
91
+
92
+ config = yaml.load(open('config.yml')) # Missing Loader parameter
93
+ data = yaml.load(file_content)
94
+
95
+ # subprocess shell injection - HIGH
96
+ import subprocess
97
+
98
+ subprocess.call(user_command, shell=True)
99
+ subprocess.run(cmd, shell=True)
100
+ subprocess.Popen(command, shell=True)
101
+ subprocess.check_output(user_input, shell=True)
102
+ `,
103
+ language: 'python',
104
+ size: 500,
105
+ },
106
+ },
107
+ ],
108
+
109
+ falseNegatives: [
110
+ {
111
+ name: 'Risky Imports - False Negatives (Safe Alternatives)',
112
+ expectFindings: false,
113
+ description: 'Modern/safe alternatives that should NOT be flagged',
114
+ allowedInfoFindings: [
115
+ {
116
+ category: 'suspicious_package',
117
+ maxCount: 1,
118
+ reason: 'Some packages may still generate info-level awareness findings',
119
+ },
120
+ ],
121
+ file: {
122
+ path: 'src/lib/safe-client.ts',
123
+ content: `
124
+ // Modern HTTP clients - SAFE
125
+ import axios from 'axios'
126
+ import fetch from 'node-fetch'
127
+
128
+ // Modern UUID - SAFE
129
+ import { v4 as uuidv4 } from 'uuid'
130
+
131
+ // Tree-shakeable lodash imports - SAFE
132
+ import get from 'lodash/get'
133
+ import set from 'lodash/set'
134
+ import { get, set } from 'lodash-es'
135
+
136
+ // Modern date libraries - SAFE
137
+ import { format, parse } from 'date-fns'
138
+ import dayjs from 'dayjs'
139
+
140
+ // Modern bcrypt - SAFE
141
+ import bcrypt from 'bcrypt'
142
+ import bcryptjs from 'bcryptjs'
143
+
144
+ // mysql2 (maintained) - SAFE
145
+ import mysql from 'mysql2'
146
+
147
+ // Native crypto - SAFE
148
+ import crypto from 'crypto'
149
+ import { randomBytes } from 'crypto'
150
+
151
+ // jose for JWT - SAFE
152
+ import { SignJWT, jwtVerify } from 'jose'
153
+ import jwt from 'jsonwebtoken'
154
+ `,
155
+ language: 'typescript',
156
+ size: 600,
157
+ },
158
+ },
159
+ {
160
+ name: 'Risky Imports - False Negatives (Python Safe Patterns)',
161
+ expectFindings: false,
162
+ description: 'Safe Python patterns that should NOT be flagged',
163
+ allowedInfoFindings: [
164
+ {
165
+ category: 'suspicious_package',
166
+ maxCount: 8,
167
+ reason: 'Package imports may still be flagged at info level even when used safely',
168
+ },
169
+ {
170
+ category: 'dangerous_function',
171
+ maxCount: 3,
172
+ reason: 'Subprocess and file operations may trigger dangerous function detection',
173
+ },
174
+ {
175
+ category: 'insecure_config',
176
+ maxCount: 2,
177
+ reason: 'Config loading patterns may trigger config detection',
178
+ },
179
+ ],
180
+ file: {
181
+ path: 'src/scripts/safe_processor.py',
182
+ content: `
183
+ # Safe YAML loading with explicit safe loader - SAFE
184
+ import yaml
185
+
186
+ # Using safe_load is the recommended approach
187
+ config = yaml.safe_load(open('config.yml'))
188
+
189
+ # JSON is always safe for serialization - SAFE
190
+ import json
191
+
192
+ data = json.load(open('data.json'))
193
+ `,
194
+ language: 'python',
195
+ size: 200,
196
+ },
197
+ },
198
+ {
199
+ name: 'Comments About Risky Packages',
200
+ expectFindings: false,
201
+ description: 'Comments mentioning risky packages should NOT be flagged',
202
+ file: {
203
+ path: 'src/MIGRATION.md',
204
+ content: `
205
+ # Migration Guide
206
+
207
+ ## HTTP Client Migration
208
+
209
+ We migrated from the deprecated 'request' package to axios.
210
+ The old code used: import request from 'request'
211
+ New code uses: import axios from 'axios'
212
+
213
+ ## Date Library Migration
214
+
215
+ // Old: import moment from 'moment'
216
+ // New: import { format } from 'date-fns'
217
+
218
+ Note: moment.js is now in maintenance mode.
219
+
220
+ ## UUID Migration
221
+
222
+ Previously we used node-uuid which is deprecated.
223
+ // const uuid = require('node-uuid')
224
+ Now we use the uuid package directly.
225
+ `,
226
+ language: 'markdown',
227
+ size: 400,
228
+ },
229
+ },
230
+ ],
231
+ }
@@ -0,0 +1,167 @@
1
+ /**
2
+ * Sensitive Variables Test Fixtures
3
+ * Tests for detecting sensitive variable names with hardcoded values
4
+ */
5
+
6
+ import type { TestGroup } from '../../types'
7
+
8
+ export const sensitiveVariablesTests: TestGroup = {
9
+ name: 'Sensitive Variables',
10
+ tier: 'C',
11
+ layer: 2,
12
+ description: 'Detection of sensitive variable names with hardcoded values',
13
+
14
+ truePositives: [
15
+ {
16
+ name: 'Sensitive Variables - True Positives',
17
+ expectFindings: true,
18
+ expectedCategories: ['sensitive_variable'],
19
+ description: 'Hardcoded sensitive variables that MUST be detected',
20
+ file: {
21
+ path: 'src/config/secrets.ts',
22
+ content: `
23
+ // Password-related variables with hardcoded values - HIGH/CRITICAL
24
+ const password = 'my-secret-password-123'
25
+ const passwd = 'admin123'
26
+ const pwd = 'password456'
27
+ const user_password = 'userpass789'
28
+ const admin_password = 'admin@secure!'
29
+ const db_password = 'database-pass-abc'
30
+ const database_password = 'dbpass123456'
31
+
32
+ // Token-related variables - HIGH
33
+ const auth_token = 'eyJhbGciOiJIUzI1NiJ9.token'
34
+ const access_token = 'ya29.access-token-value'
35
+ const refresh_token = 'refresh-token-12345'
36
+ const bearer_token = 'Bearer abc123def456'
37
+ const api_token = 'tok_live_1234567890'
38
+ const api_key = 'sk-proj-abcdefghijklmnop'
39
+ const apikey = 'api-key-secret-value'
40
+
41
+ // Secret-related variables - HIGH/CRITICAL
42
+ const secret = 'my-application-secret'
43
+ const secret_key = 'secret-key-value-here'
44
+ const private_key = 'private-key-content'
45
+ const signing_key = 'signing-key-abc123'
46
+ const client_secret = 'client-secret-xyz789'
47
+ const app_secret = 'app-secret-12345'
48
+ const jwt_secret = 'jwt-signing-secret-key'
49
+
50
+ // Credential-related - HIGH
51
+ const credential = 'user:password@host'
52
+ const credentials = 'admin:secretpassword'
53
+ const creds = 'authentication-creds'
54
+
55
+ // Connection strings - HIGH
56
+ const connection_string = 'postgresql://user:pass@host:5432/db'
57
+ const conn_string = 'mysql://root:password@localhost/mydb'
58
+ const database_url = 'mongodb://admin:secret@cluster.mongodb.net'
59
+ const db_url = 'redis://user:password@redis-host:6379'
60
+
61
+ // Encryption keys - CRITICAL
62
+ const encryption_key = 'aes-256-encryption-key-value'
63
+ const decrypt_key = 'decryption-key-secret'
64
+ const cipher_key = 'cipher-key-for-encryption'
65
+ const aes_key = 'AES-secret-key-32bytes'
66
+
67
+ // SSH/Certificate keys - CRITICAL
68
+ const ssh_key = 'ssh-rsa AAAAB3NzaC1yc2E...'
69
+ const ssl_key = 'ssl-private-key-content'
70
+ const cert_key = 'certificate-key-value'
71
+ `,
72
+ language: 'typescript',
73
+ size: 1500,
74
+ },
75
+ },
76
+ ],
77
+
78
+ falseNegatives: [
79
+ {
80
+ name: 'Sensitive Variables - False Negatives',
81
+ expectFindings: false,
82
+ description: 'Safe patterns that should NOT be flagged',
83
+ allowedInfoFindings: [
84
+ {
85
+ category: 'sensitive_variable',
86
+ maxCount: 5,
87
+ reason: 'Variable names may still trigger sensitive variable detection even with safe values',
88
+ },
89
+ {
90
+ category: 'hardcoded_secret',
91
+ maxCount: 3,
92
+ reason: 'Layer 1 may detect placeholder patterns at info level',
93
+ },
94
+ {
95
+ category: 'ai_pattern',
96
+ maxCount: 2,
97
+ reason: 'Placeholder patterns may trigger AI detection',
98
+ },
99
+ ],
100
+ file: {
101
+ path: 'src/config/safe-config.ts',
102
+ content: `
103
+ // Environment variable references - SAFE
104
+ const dbUrl = process.env.DATABASE_URL
105
+ const apiUrl = process.env.API_URL
106
+
107
+ // Type definitions (not actual values) - SAFE
108
+ interface Config {
109
+ databaseUrl: string
110
+ apiUrl: string
111
+ }
112
+
113
+ // Empty/default values - SAFE
114
+ const configValue = ''
115
+ const setting = null
116
+
117
+ // Environment-based configuration - SAFE
118
+ const endpoint = process.env.ENDPOINT || 'localhost'
119
+ `,
120
+ language: 'typescript',
121
+ size: 400,
122
+ },
123
+ },
124
+ {
125
+ name: 'Test File Patterns',
126
+ expectFindings: false,
127
+ description: 'Test files may have mock sensitive variables',
128
+ allowedInfoFindings: [
129
+ {
130
+ category: 'sensitive_variable',
131
+ maxCount: 8,
132
+ reason: 'Test files may have mock credentials for testing',
133
+ },
134
+ {
135
+ category: 'hardcoded_secret',
136
+ maxCount: 5,
137
+ reason: 'Test credentials may be detected at low severity',
138
+ },
139
+ {
140
+ category: 'high_entropy_string',
141
+ maxCount: 2,
142
+ reason: 'Test strings may trigger entropy detection',
143
+ },
144
+ ],
145
+ file: {
146
+ path: 'src/__tests__/config.test.ts',
147
+ content: `
148
+ import { describe, it, expect } from 'vitest'
149
+
150
+ describe('Config', () => {
151
+ it('should mask sensitive values in logs', () => {
152
+ const value = 'test-value'
153
+ expect(maskValue(value)).toBe('***')
154
+ })
155
+
156
+ it('should validate format', () => {
157
+ const input = 'valid-input'
158
+ expect(isValid(input)).toBe(true)
159
+ })
160
+ })
161
+ `,
162
+ language: 'typescript',
163
+ size: 300,
164
+ },
165
+ },
166
+ ],
167
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Security Benchmark Test Suite
3
+ *
4
+ * Modular benchmark suite for the Oculum scanner covering:
5
+ * - Traditional OWASP-style vulnerabilities
6
+ * - AI-specific security issues (prompt injection, unsafe execution, BYOK, etc.)
7
+ * - False positive scenarios
8
+ *
9
+ * Usage:
10
+ * Run all tests: npx tsx src/lib/scanner/__tests__/benchmark/run-benchmark.ts
11
+ *
12
+ * Import fixtures: import { allTestGroups } from './benchmark'
13
+ * Import utilities: import { runTestFixture } from './benchmark'
14
+ */
15
+
16
+ // Types
17
+ export * from './types'
18
+
19
+ // Test fixtures
20
+ export * from './fixtures'
21
+
22
+ // Test utilities
23
+ export {
24
+ runTestFixture,
25
+ runTestGroup,
26
+ printTestResult,
27
+ computeSummary,
28
+ printSummary,
29
+ } from './utils/test-runner'