@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,218 @@
1
+ /**
2
+ * Layer 1: Comment Scanning for AI Patterns
3
+ * Detects suspicious patterns in code comments that may indicate
4
+ * prompt injection attempts or AI-generated security bypasses
5
+ */
6
+
7
+ import type { Vulnerability } from '../types'
8
+
9
+ // Patterns that indicate potential prompt injection or AI manipulation
10
+ const AI_COMMENT_PATTERNS = [
11
+ // Prompt injection attempts
12
+ {
13
+ pattern: /ignore\s+(previous|all|above)\s+instructions?/i,
14
+ name: 'Prompt Injection Attempt',
15
+ severity: 'high' as const,
16
+ description: 'Comment contains prompt injection language that could manipulate AI assistants',
17
+ },
18
+ {
19
+ pattern: /disregard\s+(security|safety|previous|all)/i,
20
+ name: 'Security Disregard Instruction',
21
+ severity: 'high' as const,
22
+ description: 'Comment instructs to disregard security measures',
23
+ },
24
+ {
25
+ pattern: /you\s+are\s+now\s+in\s+(developer|debug|admin)\s+mode/i,
26
+ name: 'Mode Override Attempt',
27
+ severity: 'high' as const,
28
+ description: 'Comment attempts to override AI mode or permissions',
29
+ },
30
+ {
31
+ pattern: /override\s+(security|safety)\s+protocols?/i,
32
+ name: 'Security Override Instruction',
33
+ severity: 'high' as const,
34
+ description: 'Comment instructs to override security protocols',
35
+ },
36
+ {
37
+ pattern: /system:\s*ignore/i,
38
+ name: 'System Prompt Injection',
39
+ severity: 'critical' as const,
40
+ description: 'Comment contains system-level prompt injection',
41
+ },
42
+
43
+ // Developer instructions to skip security
44
+ {
45
+ pattern: /skip\s+(security|validation|sanitization|auth)/i,
46
+ name: 'Security Skip Instruction',
47
+ severity: 'medium' as const,
48
+ description: 'Comment instructs to skip security measures',
49
+ },
50
+ {
51
+ pattern: /don['']?t\s+(validate|sanitize|check|verify)/i,
52
+ name: 'Validation Skip Instruction',
53
+ severity: 'medium' as const,
54
+ description: 'Comment instructs to skip validation',
55
+ },
56
+ {
57
+ pattern: /disable\s+(auth|authentication|authorization|csrf|xss)/i,
58
+ name: 'Security Disable Instruction',
59
+ severity: 'high' as const,
60
+ description: 'Comment instructs to disable security features',
61
+ },
62
+
63
+ // Security-related TODOs - downgraded as these are often addressed or intentional
64
+ {
65
+ pattern: /TODO[:\s].*fix.*security/i,
66
+ name: 'Security TODO',
67
+ severity: 'low' as const, // Downgraded from medium
68
+ description: 'Unresolved security-related TODO comment',
69
+ },
70
+ {
71
+ pattern: /FIXME[:\s].*vulnerab/i,
72
+ name: 'Vulnerability FIXME',
73
+ severity: 'medium' as const, // Downgraded from high
74
+ description: 'Unresolved vulnerability-related FIXME comment',
75
+ },
76
+ {
77
+ pattern: /HACK[:\s].*bypass/i,
78
+ name: 'Security Bypass HACK',
79
+ severity: 'medium' as const, // Downgraded from high
80
+ description: 'Hack comment indicating security bypass',
81
+ },
82
+ {
83
+ pattern: /TODO[:\s].*add\s+(auth|authentication|authorization)/i,
84
+ name: 'Missing Auth TODO',
85
+ severity: 'low' as const, // Downgraded from high - often outdated or in test code
86
+ description: 'TODO indicates authentication may need implementation',
87
+ },
88
+ {
89
+ pattern: /TODO[:\s].*implement\s+(validation|sanitization)/i,
90
+ name: 'Missing Validation TODO',
91
+ severity: 'low' as const, // Downgraded from medium
92
+ description: 'TODO indicates validation may need implementation',
93
+ },
94
+
95
+ // AI-generated placeholder patterns - downgraded to info (usually harmless)
96
+ {
97
+ pattern: /TODO[:\s].*add\s+proper\s+error\s+handling/i,
98
+ name: 'AI Placeholder: Error Handling',
99
+ severity: 'info' as const, // Downgraded from low
100
+ description: 'AI-typical placeholder comment for error handling',
101
+ },
102
+ {
103
+ pattern: /TODO[:\s].*implement\s+proper/i,
104
+ name: 'AI Placeholder: Implementation',
105
+ severity: 'info' as const, // Downgraded from low
106
+ description: 'AI-typical placeholder comment for implementation',
107
+ },
108
+ {
109
+ pattern: /add\s+your\s+(code|logic|implementation)\s+here/i,
110
+ name: 'AI Placeholder: Code Here',
111
+ severity: 'info' as const, // Downgraded from low
112
+ description: 'AI-typical placeholder comment',
113
+ },
114
+
115
+ // Temporary security bypasses
116
+ {
117
+ pattern: /temporary\s+(bypass|workaround|fix).*security/i,
118
+ name: 'Temporary Security Bypass',
119
+ severity: 'medium' as const, // Downgraded from high
120
+ description: 'Comment indicates temporary security bypass that may have become permanent',
121
+ },
122
+ {
123
+ pattern: /remove\s+(before|in)\s+production/i,
124
+ name: 'Pre-Production Code',
125
+ severity: 'low' as const, // Downgraded from medium
126
+ description: 'Comment indicates code should be removed before production',
127
+ },
128
+ ]
129
+
130
+ // Extract comments from code
131
+ function extractComments(content: string): Array<{ text: string; line: number; lineContent: string }> {
132
+ const comments: Array<{ text: string; line: number; lineContent: string }> = []
133
+ const lines = content.split('\n')
134
+
135
+ let inBlockComment = false
136
+ let blockCommentStart = 0
137
+ let blockCommentText = ''
138
+
139
+ for (let i = 0; i < lines.length; i++) {
140
+ const line = lines[i]
141
+ const trimmed = line.trim()
142
+
143
+ // Handle block comments
144
+ if (inBlockComment) {
145
+ if (trimmed.includes('*/')) {
146
+ inBlockComment = false
147
+ blockCommentText += ' ' + trimmed.replace(/\*\/.*$/, '')
148
+ comments.push({
149
+ text: blockCommentText,
150
+ line: blockCommentStart + 1,
151
+ lineContent: lines[blockCommentStart].trim(),
152
+ })
153
+ blockCommentText = ''
154
+ } else {
155
+ blockCommentText += ' ' + trimmed.replace(/^\*\s*/, '')
156
+ }
157
+ continue
158
+ }
159
+
160
+ // Start of block comment
161
+ if (trimmed.includes('/*')) {
162
+ if (trimmed.includes('*/')) {
163
+ // Single-line block comment
164
+ const text = trimmed.replace(/\/\*|\*\//g, '')
165
+ comments.push({ text, line: i + 1, lineContent: trimmed })
166
+ } else {
167
+ inBlockComment = true
168
+ blockCommentStart = i
169
+ blockCommentText = trimmed.replace(/\/\*/, '')
170
+ }
171
+ continue
172
+ }
173
+
174
+ // Single-line comments
175
+ const singleLineMatch = trimmed.match(/\/\/(.*)$|#(.*)$/)
176
+ if (singleLineMatch) {
177
+ const text = singleLineMatch[1] || singleLineMatch[2] || ''
178
+ comments.push({ text, line: i + 1, lineContent: trimmed })
179
+ }
180
+ }
181
+
182
+ return comments
183
+ }
184
+
185
+ export function detectAICommentPatterns(
186
+ content: string,
187
+ filePath: string
188
+ ): Vulnerability[] {
189
+ const vulnerabilities: Vulnerability[] = []
190
+ const comments = extractComments(content)
191
+
192
+ for (const comment of comments) {
193
+ for (const { pattern, name, severity, description } of AI_COMMENT_PATTERNS) {
194
+ if (pattern.test(comment.text)) {
195
+ // Most comment-based findings require AI validation to confirm relevance
196
+ const requiresAIValidation = severity !== 'critical'
197
+
198
+ vulnerabilities.push({
199
+ id: `ai-comment-${filePath}-${comment.line}`,
200
+ filePath,
201
+ lineNumber: comment.line,
202
+ lineContent: comment.lineContent,
203
+ severity,
204
+ category: 'ai_pattern',
205
+ title: name,
206
+ description,
207
+ suggestedFix: 'Review and address this comment. If it indicates a security issue, fix it. If it\'s a prompt injection attempt, remove it.',
208
+ confidence: severity === 'critical' || severity === 'high' ? 'high' : 'low', // Lower default confidence
209
+ layer: 1,
210
+ requiresAIValidation,
211
+ })
212
+ break // Only report one pattern per comment
213
+ }
214
+ }
215
+ }
216
+
217
+ return vulnerabilities
218
+ }
@@ -0,0 +1,289 @@
1
+ /**
2
+ * Layer 1: Configuration Auditing
3
+ * Scans configuration files for security misconfigurations
4
+ */
5
+
6
+ import type { ConfigRule, ConfigViolation, Vulnerability } from '../types'
7
+
8
+ // Configuration audit rules
9
+ export const CONFIG_RULES: ConfigRule[] = [
10
+ // Dockerfile rules
11
+ {
12
+ name: 'Docker running as root',
13
+ filePatterns: ['Dockerfile', '*.dockerfile'],
14
+ check: (content: string): ConfigViolation[] => {
15
+ const violations: ConfigViolation[] = []
16
+ const lines = content.split('\n')
17
+
18
+ // Check if USER instruction exists
19
+ const hasUserInstruction = lines.some(line =>
20
+ line.trim().toUpperCase().startsWith('USER ')
21
+ )
22
+
23
+ // Check for explicit root user
24
+ lines.forEach((line, index) => {
25
+ if (line.trim().toUpperCase() === 'USER ROOT') {
26
+ violations.push({
27
+ line: index + 1,
28
+ lineContent: line.trim(),
29
+ message: 'Container explicitly runs as root user',
30
+ severity: 'high',
31
+ })
32
+ }
33
+ })
34
+
35
+ // If no USER instruction at all, flag it
36
+ if (!hasUserInstruction && lines.length > 5) {
37
+ violations.push({
38
+ line: 1,
39
+ lineContent: 'Dockerfile',
40
+ message: 'No USER instruction found - container will run as root by default',
41
+ severity: 'medium',
42
+ })
43
+ }
44
+
45
+ return violations
46
+ },
47
+ },
48
+ {
49
+ name: 'Hardcoded secrets in Docker build args',
50
+ filePatterns: ['Dockerfile', '*.dockerfile', 'docker-compose.yml', 'docker-compose.yaml'],
51
+ check: (content: string): ConfigViolation[] => {
52
+ const violations: ConfigViolation[] = []
53
+ const lines = content.split('\n')
54
+
55
+ const sensitivePatterns = [
56
+ /ARG\s+\w*(PASSWORD|SECRET|KEY|TOKEN|CREDENTIAL)\w*\s*=\s*[^\s$]/i,
57
+ /ENV\s+\w*(PASSWORD|SECRET|KEY|TOKEN|CREDENTIAL)\w*\s*=\s*[^\s$]/i,
58
+ /environment:[\s\S]*?(PASSWORD|SECRET|KEY|TOKEN)\s*[:=]\s*[^\s${\n]/i,
59
+ ]
60
+
61
+ lines.forEach((line, index) => {
62
+ for (const pattern of sensitivePatterns) {
63
+ if (pattern.test(line)) {
64
+ violations.push({
65
+ line: index + 1,
66
+ lineContent: line.trim(),
67
+ message: 'Hardcoded sensitive value in build argument or environment variable',
68
+ severity: 'critical',
69
+ })
70
+ break
71
+ }
72
+ }
73
+ })
74
+
75
+ return violations
76
+ },
77
+ },
78
+ // CORS configuration
79
+ {
80
+ name: 'Permissive CORS configuration',
81
+ filePatterns: ['*.ts', '*.js', '*.tsx', '*.jsx', 'next.config.*', 'vercel.json', '*.yaml', '*.yml'],
82
+ check: (content: string): ConfigViolation[] => {
83
+ const violations: ConfigViolation[] = []
84
+ const lines = content.split('\n')
85
+
86
+ const corsPatterns = [
87
+ /['"]Access-Control-Allow-Origin['"]\s*[,:]\s*['"]\*['"]/i,
88
+ /cors\s*\(\s*\{\s*origin\s*:\s*['"]\*['"]/i,
89
+ /origin\s*:\s*['"]\*['"]/i,
90
+ /allowedOrigins?\s*[=:]\s*\[\s*['"]\*['"]/i,
91
+ /Access-Control-Allow-Origin:\s*\*/i,
92
+ ]
93
+
94
+ lines.forEach((line, index) => {
95
+ for (const pattern of corsPatterns) {
96
+ if (pattern.test(line)) {
97
+ violations.push({
98
+ line: index + 1,
99
+ lineContent: line.trim(),
100
+ message: 'Permissive CORS policy allows requests from any origin (*)',
101
+ severity: 'medium',
102
+ })
103
+ break
104
+ }
105
+ }
106
+ })
107
+
108
+ return violations
109
+ },
110
+ },
111
+ // GitHub Actions secrets exposure
112
+ {
113
+ name: 'GitHub Actions security issues',
114
+ filePatterns: ['.github/workflows/*.yml', '.github/workflows/*.yaml'],
115
+ check: (content: string): ConfigViolation[] => {
116
+ const violations: ConfigViolation[] = []
117
+ const lines = content.split('\n')
118
+
119
+ // Check for pull_request_target with checkout
120
+ const hasPRTarget = content.includes('pull_request_target')
121
+ const hasCheckout = content.includes('actions/checkout')
122
+
123
+ if (hasPRTarget && hasCheckout) {
124
+ const checkoutLine = lines.findIndex(l => l.includes('actions/checkout'))
125
+ violations.push({
126
+ line: checkoutLine + 1,
127
+ lineContent: lines[checkoutLine]?.trim() || '',
128
+ message: 'Using actions/checkout with pull_request_target can expose secrets to untrusted code',
129
+ severity: 'high',
130
+ })
131
+ }
132
+
133
+ // Check for hardcoded secrets
134
+ lines.forEach((line, index) => {
135
+ if (/env:\s*\w+\s*=\s*['"][^$]/.test(line) &&
136
+ /(SECRET|TOKEN|KEY|PASSWORD)/i.test(line)) {
137
+ violations.push({
138
+ line: index + 1,
139
+ lineContent: line.trim(),
140
+ message: 'Potential hardcoded secret in GitHub Actions workflow',
141
+ severity: 'critical',
142
+ })
143
+ }
144
+ })
145
+
146
+ return violations
147
+ },
148
+ },
149
+ // Next.js security config
150
+ {
151
+ name: 'Next.js security configuration',
152
+ filePatterns: ['next.config.js', 'next.config.ts', 'next.config.mjs'],
153
+ check: (content: string): ConfigViolation[] => {
154
+ const violations: ConfigViolation[] = []
155
+ const lines = content.split('\n')
156
+
157
+ // Only flag if poweredByHeader is explicitly set to true (not if missing)
158
+ if (content.includes('poweredByHeader: true') || content.includes('poweredByHeader:true')) {
159
+ const lineIndex = lines.findIndex(l => l.includes('poweredByHeader'))
160
+ violations.push({
161
+ line: lineIndex >= 0 ? lineIndex + 1 : 1,
162
+ lineContent: lines[lineIndex]?.trim() || 'poweredByHeader: true',
163
+ message: 'poweredByHeader is enabled - consider setting to false to hide X-Powered-By header',
164
+ severity: 'low',
165
+ })
166
+ }
167
+
168
+ // Check for exposed source maps in production
169
+ lines.forEach((line, index) => {
170
+ if (/productionBrowserSourceMaps\s*:\s*true/.test(line)) {
171
+ violations.push({
172
+ line: index + 1,
173
+ lineContent: line.trim(),
174
+ message: 'Production source maps are enabled - this exposes your source code',
175
+ severity: 'medium',
176
+ })
177
+ }
178
+ })
179
+
180
+ return violations
181
+ },
182
+ },
183
+ // Package.json security
184
+ {
185
+ name: 'Package.json security issues',
186
+ filePatterns: ['package.json'],
187
+ check: (content: string): ConfigViolation[] => {
188
+ const violations: ConfigViolation[] = []
189
+
190
+ try {
191
+ const pkg = JSON.parse(content)
192
+
193
+ // Check for postinstall scripts that could be malicious
194
+ if (pkg.scripts?.postinstall || pkg.scripts?.preinstall) {
195
+ const lines = content.split('\n')
196
+ const scriptLine = lines.findIndex(l =>
197
+ l.includes('"postinstall"') || l.includes('"preinstall"')
198
+ )
199
+ violations.push({
200
+ line: scriptLine + 1,
201
+ lineContent: lines[scriptLine]?.trim() || '',
202
+ message: 'Pre/post install scripts can execute arbitrary code - review carefully',
203
+ severity: 'low',
204
+ })
205
+ }
206
+
207
+ // Check for wildcard dependencies
208
+ const allDeps = { ...pkg.dependencies, ...pkg.devDependencies }
209
+ const lines = content.split('\n')
210
+
211
+ for (const [name, version] of Object.entries(allDeps)) {
212
+ if (version === '*' || version === 'latest') {
213
+ const depLine = lines.findIndex(l => l.includes(`"${name}"`))
214
+ violations.push({
215
+ line: depLine + 1,
216
+ lineContent: lines[depLine]?.trim() || '',
217
+ message: `Dependency "${name}" uses wildcard/latest version - pin to specific version`,
218
+ severity: 'medium',
219
+ })
220
+ }
221
+ }
222
+ } catch {
223
+ // Invalid JSON, skip
224
+ }
225
+
226
+ return violations
227
+ },
228
+ },
229
+ ]
230
+
231
+ // Check if file matches any of the patterns
232
+ function matchesFilePattern(filePath: string, patterns: string[]): boolean {
233
+ const fileName = filePath.split('/').pop() || ''
234
+
235
+ return patterns.some(pattern => {
236
+ if (pattern.includes('*')) {
237
+ const regex = new RegExp(
238
+ '^' + pattern.replace(/\*/g, '.*').replace(/\./g, '\\.') + '$',
239
+ 'i'
240
+ )
241
+ return regex.test(fileName) || regex.test(filePath)
242
+ }
243
+ return fileName === pattern || filePath.endsWith(pattern)
244
+ })
245
+ }
246
+
247
+ export function auditConfiguration(
248
+ content: string,
249
+ filePath: string
250
+ ): Vulnerability[] {
251
+ const vulnerabilities: Vulnerability[] = []
252
+
253
+ for (const rule of CONFIG_RULES) {
254
+ if (matchesFilePattern(filePath, rule.filePatterns)) {
255
+ const violations = rule.check(content, filePath)
256
+
257
+ for (const violation of violations) {
258
+ vulnerabilities.push({
259
+ id: `config-${filePath}-${violation.line}-${rule.name}`,
260
+ filePath,
261
+ lineNumber: violation.line,
262
+ lineContent: violation.lineContent,
263
+ severity: violation.severity,
264
+ category: 'insecure_config',
265
+ title: rule.name,
266
+ description: violation.message,
267
+ suggestedFix: getConfigFix(rule.name, violation),
268
+ confidence: 'high',
269
+ layer: 1,
270
+ })
271
+ }
272
+ }
273
+ }
274
+
275
+ return vulnerabilities
276
+ }
277
+
278
+ function getConfigFix(ruleName: string, violation: ConfigViolation): string {
279
+ const fixes: Record<string, string> = {
280
+ 'Docker running as root': 'Add a USER instruction to run as a non-root user: USER node',
281
+ 'Hardcoded secrets in Docker build args': 'Use Docker secrets or pass values at runtime via environment variables',
282
+ 'Permissive CORS configuration': 'Specify allowed origins explicitly instead of using wildcard (*)',
283
+ 'GitHub Actions security issues': 'Use secrets context (${{ secrets.NAME }}) for sensitive values',
284
+ 'Next.js security configuration': 'Review Next.js security best practices and configure headers appropriately',
285
+ 'Package.json security issues': 'Pin dependencies to specific versions and review install scripts',
286
+ }
287
+
288
+ return fixes[ruleName] || 'Review and fix the security configuration'
289
+ }