@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
+ * Dangerous Functions Test Fixtures
3
+ * Tests for detecting eval, exec, SQL injection, XSS, and other dangerous function usage
4
+ */
5
+
6
+ import type { TestGroup } from '../../types'
7
+
8
+ export const dangerousFunctionsTests: TestGroup = {
9
+ name: 'Dangerous Functions',
10
+ tier: 'A',
11
+ layer: 2,
12
+ description: 'Detection of dangerous function calls that can lead to code injection, SQL injection, and XSS',
13
+
14
+ truePositives: [
15
+ {
16
+ name: 'Dangerous Functions - True Positives',
17
+ expectFindings: true,
18
+ expectedCategories: ['dangerous_function'],
19
+ description: 'Dangerous function patterns that MUST be detected',
20
+ file: {
21
+ path: 'src/api/execute.ts',
22
+ content: `
23
+ import { exec, execSync, spawn } from 'child_process'
24
+
25
+ // eval() with user input (Critical)
26
+ export function executeUserCode(userCode: string) {
27
+ return eval(userCode)
28
+ }
29
+
30
+ // Function constructor (Critical)
31
+ export function createDynamicFunction(code: string) {
32
+ return new Function('input', code)
33
+ }
34
+
35
+ // exec() with user input (Critical - Command Injection)
36
+ export function runCommand(userCommand: string) {
37
+ exec(userCommand, (error, stdout) => {
38
+ console.log(stdout)
39
+ })
40
+ }
41
+
42
+ // execSync with template literal (Critical)
43
+ export function runUserScript(filename: string) {
44
+ return execSync(\`node \${filename}\`)
45
+ }
46
+
47
+ // spawn with user-controlled args (High)
48
+ export function spawnProcess(program: string, args: string[]) {
49
+ return spawn(program, args)
50
+ }
51
+
52
+ // SQL injection via string concatenation (Critical)
53
+ export async function getUser(userId: string) {
54
+ const query = "SELECT * FROM users WHERE id = '" + userId + "'"
55
+ return db.query(query)
56
+ }
57
+
58
+ // SQL injection via template literal (Critical)
59
+ export async function searchUsers(searchTerm: string) {
60
+ return db.query(\`SELECT * FROM users WHERE name LIKE '%\${searchTerm}%'\`)
61
+ }
62
+
63
+ // innerHTML with user data (High - XSS)
64
+ export function renderUserContent(userHtml: string) {
65
+ document.getElementById('content').innerHTML = userHtml
66
+ }
67
+
68
+ // dangerouslySetInnerHTML with user data (High - XSS in React)
69
+ export function UserContent({ html }: { html: string }) {
70
+ return <div dangerouslySetInnerHTML={{ __html: html }} />
71
+ }
72
+
73
+ // Unvalidated redirect (Medium - Open Redirect)
74
+ export function redirect(url: string) {
75
+ window.location.href = url
76
+ }
77
+
78
+ // setTimeout with string (Medium)
79
+ export function delayedExec(code: string) {
80
+ setTimeout(code, 1000)
81
+ }
82
+
83
+ // setInterval with string (Medium)
84
+ export function repeatedExec(code: string) {
85
+ setInterval(code, 1000)
86
+ }
87
+ `,
88
+ language: 'typescript',
89
+ size: 1800,
90
+ },
91
+ },
92
+ {
93
+ name: 'Dangerous Functions - SQL Injection Variants',
94
+ expectFindings: true,
95
+ expectedCategories: ['dangerous_function'],
96
+ description: 'Various SQL injection patterns',
97
+ file: {
98
+ path: 'src/api/queries.ts',
99
+ content: `
100
+ // String concatenation SQL injection
101
+ export async function getUserByEmail(email: string) {
102
+ return db.query("SELECT * FROM users WHERE email = '" + email + "'")
103
+ }
104
+
105
+ // Template literal SQL injection
106
+ export async function searchProducts(term: string) {
107
+ return db.query(\`SELECT * FROM products WHERE name LIKE '%\${term}%'\`)
108
+ }
109
+
110
+ // Multi-line SQL with injection
111
+ export async function getOrders(userId: string, status: string) {
112
+ const query = \`
113
+ SELECT * FROM orders
114
+ WHERE user_id = '\${userId}'
115
+ AND status = '\${status}'
116
+ \`
117
+ return db.query(query)
118
+ }
119
+
120
+ // UPDATE statement injection
121
+ export async function updateUser(userId: string, name: string) {
122
+ return db.query(\`UPDATE users SET name = '\${name}' WHERE id = '\${userId}'\`)
123
+ }
124
+
125
+ // DELETE statement injection
126
+ export async function deleteUser(userId: string) {
127
+ return db.query("DELETE FROM users WHERE id = '" + userId + "'")
128
+ }
129
+ `,
130
+ language: 'typescript',
131
+ size: 900,
132
+ },
133
+ },
134
+ ],
135
+
136
+ falseNegatives: [
137
+ {
138
+ name: 'Dangerous Functions - False Negatives',
139
+ expectFindings: false,
140
+ description: 'Safe function patterns that should NOT be flagged',
141
+ allowedInfoFindings: [
142
+ {
143
+ category: 'dangerous_function',
144
+ maxCount: 6,
145
+ reason: 'Static eval, hardcoded exec, and JSON.parse with safe sources generate info-level findings',
146
+ },
147
+ ],
148
+ file: {
149
+ path: 'src/api/safe-execute.ts',
150
+ content: `
151
+ import { execSync } from 'child_process'
152
+
153
+ // Static eval (no user input) - SAFE
154
+ const config = eval('({ mode: "production" })')
155
+
156
+ // exec with hardcoded command - SAFE
157
+ function checkVersion() {
158
+ return execSync('node --version').toString()
159
+ }
160
+
161
+ // Parameterized SQL queries - SAFE
162
+ async function getUser(userId: string) {
163
+ return db.query('SELECT * FROM users WHERE id = $1', [userId])
164
+ }
165
+
166
+ // ORM queries - SAFE
167
+ async function findUser(userId: string) {
168
+ return prisma.user.findUnique({ where: { id: userId } })
169
+ }
170
+
171
+ // innerHTML with static content - SAFE
172
+ function setStaticContent() {
173
+ document.getElementById('footer').innerHTML = '<p>Copyright 2024</p>'
174
+ }
175
+
176
+ // React JSX (auto-escaped) - SAFE
177
+ function UserName({ name }: { name: string }) {
178
+ return <div>{name}</div>
179
+ }
180
+
181
+ // dangerouslySetInnerHTML with sanitized content - SAFE
182
+ import DOMPurify from 'dompurify'
183
+ function SafeUserContent({ html }: { html: string }) {
184
+ const clean = DOMPurify.sanitize(html)
185
+ return <div dangerouslySetInnerHTML={{ __html: clean }} />
186
+ }
187
+
188
+ // JSON.parse from own database - SAFE
189
+ async function getConfig() {
190
+ const row = await db.query('SELECT config FROM settings WHERE id = 1')
191
+ return JSON.parse(row.config)
192
+ }
193
+
194
+ // JSON.parse with try-catch - SAFE
195
+ function parseConfig(data: string) {
196
+ try {
197
+ return JSON.parse(data)
198
+ } catch {
199
+ return {}
200
+ }
201
+ }
202
+ `,
203
+ language: 'typescript',
204
+ size: 1400,
205
+ },
206
+ },
207
+ {
208
+ name: 'Dangerous Functions - Parameterized Queries',
209
+ expectFindings: false,
210
+ description: 'Properly parameterized SQL that should not be flagged',
211
+ file: {
212
+ path: 'src/api/safe-queries.ts',
213
+ content: `
214
+ // Parameterized queries - SAFE
215
+ async function getUserById(id: string) {
216
+ return db.query('SELECT * FROM users WHERE id = $1', [id])
217
+ }
218
+
219
+ // Named parameters - SAFE
220
+ async function findByEmail(email: string) {
221
+ return db.query('SELECT * FROM users WHERE email = :email', { email })
222
+ }
223
+
224
+ // Prisma ORM - SAFE
225
+ async function getOrders(userId: string) {
226
+ return prisma.order.findMany({
227
+ where: { userId }
228
+ })
229
+ }
230
+
231
+ // Drizzle ORM - SAFE
232
+ async function getProducts(category: string) {
233
+ return db.select().from(products).where(eq(products.category, category))
234
+ }
235
+
236
+ // Knex query builder - SAFE
237
+ async function searchUsers(name: string) {
238
+ return knex('users').where('name', 'like', \`%\${name}%\`)
239
+ }
240
+ `,
241
+ language: 'typescript',
242
+ size: 700,
243
+ },
244
+ },
245
+ ],
246
+ }
@@ -0,0 +1,168 @@
1
+ /**
2
+ * Data Exposure Test Fixtures
3
+ * Tests for detecting sensitive data exposure in logs, responses, and error handling
4
+ */
5
+
6
+ import type { TestGroup } from '../../types'
7
+
8
+ export const dataExposureTests: TestGroup = {
9
+ name: 'Data Exposure',
10
+ tier: 'B',
11
+ layer: 2,
12
+ description: 'Detection of sensitive data exposure in logs, responses, and error handling',
13
+
14
+ truePositives: [
15
+ {
16
+ name: 'Data Exposure - True Positives',
17
+ expectFindings: true,
18
+ expectedCategories: ['data_exposure'],
19
+ description: 'Data exposure patterns that MUST be detected',
20
+ file: {
21
+ path: 'src/api/users/route.ts',
22
+ content: `
23
+ import { NextResponse } from 'next/server'
24
+
25
+ // Full error stack in response - HIGH
26
+ export async function GET() {
27
+ try {
28
+ const users = await db.user.findMany()
29
+ return NextResponse.json(users)
30
+ } catch (error) {
31
+ return NextResponse.json({
32
+ error: error.stack, // Stack trace exposed!
33
+ details: error
34
+ }, { status: 500 })
35
+ }
36
+ }
37
+
38
+ // Logging passwords - CRITICAL
39
+ export async function POST(request: Request) {
40
+ const { email, password } = await request.json()
41
+ console.log('Login attempt:', email, password) // Password logged!
42
+
43
+ return authenticate(email, password)
44
+ }
45
+
46
+ // Logging API keys - HIGH
47
+ export async function useKey(apiKey: string) {
48
+ console.log('Using API key:', apiKey) // Secret logged!
49
+ return callAPI(apiKey)
50
+ }
51
+
52
+ // Returning full user object with sensitive fields - MEDIUM
53
+ export async function getUser(userId: string) {
54
+ const user = await db.user.findUnique({
55
+ where: { id: userId },
56
+ include: {
57
+ apiKeys: true, // API keys exposed!
58
+ sessions: true, // Sessions exposed!
59
+ }
60
+ })
61
+ return NextResponse.json(user) // No field filtering!
62
+ }
63
+
64
+ // Debug endpoint in production - HIGH
65
+ export async function DEBUG() {
66
+ return NextResponse.json({
67
+ env: process.env, // All env vars exposed!
68
+ config: serverConfig,
69
+ })
70
+ }
71
+
72
+ // Verbose internal error details - MEDIUM
73
+ export async function handleError(error: any) {
74
+ return NextResponse.json({
75
+ error: error.message,
76
+ internalCode: error.code,
77
+ query: error.query, // SQL query exposed!
78
+ trace: error.trace,
79
+ })
80
+ }
81
+ `,
82
+ language: 'typescript',
83
+ size: 1400,
84
+ },
85
+ },
86
+ ],
87
+
88
+ falseNegatives: [
89
+ {
90
+ name: 'Data Exposure - False Negatives',
91
+ expectFindings: false,
92
+ description: 'Safe error handling patterns that should NOT be flagged',
93
+ allowedInfoFindings: [
94
+ {
95
+ category: 'ai_pattern',
96
+ maxCount: 2,
97
+ reason: 'AI boilerplate error messages are info-level findings',
98
+ },
99
+ {
100
+ category: 'data_exposure',
101
+ maxCount: 2,
102
+ reason: 'Exposing filtered user object is low/info-level, not a security issue',
103
+ },
104
+ ],
105
+ file: {
106
+ path: 'src/api/safe-handlers.ts',
107
+ content: `
108
+ import { NextResponse } from 'next/server'
109
+
110
+ // error.message only - SAFE (recommended pattern)
111
+ export async function GET() {
112
+ try {
113
+ const data = await fetchData()
114
+ return NextResponse.json(data)
115
+ } catch (error) {
116
+ console.error('Error:', error) // Logged for debugging - SAFE
117
+ return NextResponse.json({
118
+ error: error.message // Only message, not stack - SAFE
119
+ }, { status: 500 })
120
+ }
121
+ }
122
+
123
+ // Static error message - SAFE
124
+ export async function POST() {
125
+ try {
126
+ await doSomething()
127
+ } catch {
128
+ return NextResponse.json({
129
+ error: 'An error occurred' // Generic message - SAFE
130
+ }, { status: 500 })
131
+ }
132
+ }
133
+
134
+ // Logging non-sensitive data - SAFE
135
+ export async function logRequest(request: Request) {
136
+ const { method, url } = request
137
+ console.log(\`\${method} \${url}\`) // No secrets - SAFE
138
+ }
139
+
140
+ // Filtered user response - SAFE
141
+ export async function getUser(userId: string) {
142
+ const user = await db.user.findUnique({
143
+ where: { id: userId },
144
+ select: {
145
+ id: true,
146
+ name: true,
147
+ email: true,
148
+ // No sensitive fields selected
149
+ }
150
+ })
151
+ return NextResponse.json(user)
152
+ }
153
+
154
+ // Config check message - SAFE
155
+ export async function checkConfig() {
156
+ if (!process.env.OPENAI_API_KEY) {
157
+ return NextResponse.json({
158
+ error: 'OpenAI API key not configured' // Operational info - SAFE
159
+ }, { status: 500 })
160
+ }
161
+ }
162
+ `,
163
+ language: 'typescript',
164
+ size: 1200,
165
+ },
166
+ },
167
+ ],
168
+ }