@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,500 @@
1
+ "use strict";
2
+ /**
3
+ * Layer 1: High-Entropy String Detection
4
+ * Uses Shannon entropy to detect potential secrets that don't match known patterns
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.calculateEntropy = calculateEntropy;
8
+ exports.detectHighEntropyStrings = detectHighEntropyStrings;
9
+ const context_helpers_1 = require("../utils/context-helpers");
10
+ // Shannon entropy calculation
11
+ function calculateEntropy(str) {
12
+ if (str.length === 0)
13
+ return 0;
14
+ const freq = {};
15
+ for (const char of str) {
16
+ freq[char] = (freq[char] || 0) + 1;
17
+ }
18
+ let entropy = 0;
19
+ const len = str.length;
20
+ for (const char in freq) {
21
+ const p = freq[char] / len;
22
+ entropy -= p * Math.log2(p);
23
+ }
24
+ return entropy;
25
+ }
26
+ // Extract string literals from code
27
+ function extractStringLiterals(content) {
28
+ const strings = [];
29
+ const lines = content.split('\n');
30
+ // Patterns for string literals
31
+ const patterns = [
32
+ /"([^"\\]|\\.){20,}"/g, // Double-quoted strings 20+ chars
33
+ /'([^'\\]|\\.){20,}'/g, // Single-quoted strings 20+ chars
34
+ /`([^`\\]|\\.){20,}`/g, // Template literals 20+ chars
35
+ ];
36
+ lines.forEach((line, index) => {
37
+ for (const pattern of patterns) {
38
+ let match;
39
+ const regex = new RegExp(pattern.source, pattern.flags);
40
+ while ((match = regex.exec(line)) !== null) {
41
+ // Remove quotes and get the actual string value
42
+ const value = match[0].slice(1, -1);
43
+ strings.push({
44
+ value,
45
+ line: index + 1,
46
+ lineContent: line.trim(),
47
+ });
48
+ }
49
+ }
50
+ });
51
+ return strings;
52
+ }
53
+ // Check if string looks like a known safe pattern (URLs, paths, etc.)
54
+ function isSafePattern(str) {
55
+ const safePatterns = [
56
+ /^https?:\/\//i, // URLs
57
+ /^\/[a-z0-9_/-]+$/i, // File paths
58
+ /^\d{4}-\d{2}-\d{2}/, // Dates
59
+ /^[a-f0-9]{32}$/i, // MD5 hashes (often used as IDs)
60
+ /^[a-f0-9]{40}$/i, // SHA1 hashes
61
+ /^[a-f0-9]{64}$/i, // SHA256 hashes
62
+ /^data:[a-z]+\/[a-z]+;base64,/i, // Data URLs
63
+ /^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$/i, // Emails
64
+ /^\s*$/, // Whitespace only
65
+ /^[a-z\s]+$/i, // Only letters and spaces (likely text)
66
+ /^\/?[\(\)\[\]\{\}\|\?\*\+\.\^\$\\:!_a-z0-9/-]+$/i, // Regex patterns (route matchers, etc.)
67
+ ];
68
+ return safePatterns.some(pattern => pattern.test(str));
69
+ }
70
+ // Check if string is a PEM header/footer (not an actual secret)
71
+ function isPEMHeader(str) {
72
+ const pemPatterns = [
73
+ /^-{3,}BEGIN\s+(PRIVATE|PUBLIC|RSA|DSA|EC|ENCRYPTED|CERTIFICATE)/i,
74
+ /^-{3,}END\s+(PRIVATE|PUBLIC|RSA|DSA|EC|ENCRYPTED|CERTIFICATE)/i,
75
+ /-----BEGIN\s+\w+\s+KEY-----/i,
76
+ /-----END\s+\w+\s+KEY-----/i,
77
+ ];
78
+ return pemPatterns.some(p => p.test(str));
79
+ }
80
+ // Check if string looks like encrypted/encoded content (not the key itself)
81
+ function isEncryptedContent(str, lineContent) {
82
+ // Patterns for encrypted content blocks (not the key)
83
+ const encryptedPatterns = [
84
+ /encrypted_content/i,
85
+ /ciphertext/i,
86
+ /encrypted_data/i,
87
+ /encrypted_value/i,
88
+ // Base64 encoded binary data (very long, uniform character set)
89
+ /^[A-Za-z0-9+/]{100,}={0,2}$/, // Long base64 strings are often encrypted payloads
90
+ ];
91
+ // Check line context for encrypted content indicators
92
+ const contextIndicators = [
93
+ /["']encrypted_content["']\s*:/i,
94
+ /["']ciphertext["']\s*:/i,
95
+ /gAAAA/, // Fernet encryption prefix
96
+ ];
97
+ return (encryptedPatterns.some(p => p.test(str)) ||
98
+ contextIndicators.some(p => p.test(lineContent)));
99
+ }
100
+ // Check if string looks like a JWT segment (base64url encoded, starts with eyJ)
101
+ function isJWTSegment(str) {
102
+ // JWT segments typically start with 'eyJ' (base64 for '{"')
103
+ // Full JWT format: header.payload.signature (all base64url)
104
+ if (str.startsWith('eyJ') && /^[A-Za-z0-9_-]+$/.test(str)) {
105
+ return true;
106
+ }
107
+ // Check for full JWT pattern (3 dot-separated base64url segments)
108
+ if (/^eyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(str)) {
109
+ return true;
110
+ }
111
+ return false;
112
+ }
113
+ // Check if string looks like a regex/route matcher pattern
114
+ function isRegexPattern(str) {
115
+ // Common regex metacharacters and patterns
116
+ const regexIndicators = ['(?', '(?!', '(?:', '(?=', '\\.', '\\.', '.*', '.+', '[^', '|', '$)', '^', '$'];
117
+ const indicatorCount = regexIndicators.filter(ind => str.includes(ind)).length;
118
+ // If it has multiple regex indicators, it's likely a regex pattern
119
+ return indicatorCount >= 2;
120
+ }
121
+ // Check if string is a template literal with code expressions
122
+ function isTemplateWithCode(str, lineContent) {
123
+ // Check if the line contains template literal syntax with expressions
124
+ if (!lineContent.includes('`') && !lineContent.includes('${')) {
125
+ return false;
126
+ }
127
+ // Common code patterns inside template literals that create high entropy
128
+ const codePatterns = [
129
+ /\$\{[^}]*\.(toString|padStart|padEnd|toFixed|toLocaleString)\s*\(/i, // Method calls
130
+ /\$\{[^}]*\?\.[^}]*\}/, // Optional chaining
131
+ /\$\{[^}]*\s*\?\s*[^:]+\s*:\s*[^}]+\}/, // Ternary operators
132
+ /var\s*\(\s*\$\{/, // CSS var() with template
133
+ /\$\{[^}]*\.find\s*\(/i, // Array methods
134
+ /\$\{[^}]*\.map\s*\(/i,
135
+ /\$\{[^}]*\.filter\s*\(/i,
136
+ /\$\{new\s+Date\(\)/i, // Date formatting
137
+ ];
138
+ return codePatterns.some(pattern => pattern.test(lineContent));
139
+ }
140
+ // Check if string is human-readable text/markdown content
141
+ function isHumanReadableContent(str) {
142
+ // Skip short strings
143
+ if (str.length < 30)
144
+ return false;
145
+ // Check for markdown indicators
146
+ const markdownIndicators = ['## ', '# ', '**', '- [ ]', '- ', '\n\n', '\\n'];
147
+ const hasMarkdown = markdownIndicators.some(ind => str.includes(ind));
148
+ // Check word-like pattern ratio (spaces between word-like tokens)
149
+ const words = str.split(/\s+/).filter(w => w.length > 0);
150
+ const wordLikeTokens = words.filter(w => /^[a-zA-Z][a-zA-Z0-9'-]*[:.!?,]?$/.test(w));
151
+ // If more than 50% of tokens look like words, it's probably text
152
+ const wordRatio = words.length > 0 ? wordLikeTokens.length / words.length : 0;
153
+ return hasMarkdown || wordRatio > 0.5;
154
+ }
155
+ // Check if string looks like a UI/display string (model names, descriptions, etc.)
156
+ function isUIString(str, lineContent) {
157
+ // Common UI string patterns
158
+ const uiPatterns = [
159
+ /['"`].*Claude.*['"`]/i,
160
+ /['"`].*GPT.*['"`]/i,
161
+ /['"`].*Sonnet.*['"`]/i,
162
+ /['"`].*for\s+(chat|embeddings|completion).*['"`]/i,
163
+ /['"`]Uses\s+/i,
164
+ /['"`]Note:\s*/i,
165
+ /placeholder['"`:]/i,
166
+ /description['"`:]/i,
167
+ /label['"`:]/i,
168
+ /title['"`:]/i,
169
+ /message['"`:]/i,
170
+ /tooltip['"`:]/i,
171
+ ];
172
+ return uiPatterns.some(pattern => pattern.test(lineContent));
173
+ }
174
+ // Check if string is in a React/JSX UI context (component props, JSX text)
175
+ function isJSXUIContext(lineContent) {
176
+ // JSX patterns that indicate UI context
177
+ const jsxUIPatterns = [
178
+ // Component props (common UI props)
179
+ /\b(placeholder|title|label|message|description|tooltip|alt|aria-label|name|id|className|testId|data-testid)\s*=\s*['"`]/i,
180
+ // JSX text children (text between tags)
181
+ />\s*['"`][^<]*['"`]\s*</,
182
+ // Common UI component names
183
+ /<(Button|Text|Label|Title|Heading|Paragraph|Span|Input|Tooltip|Badge|Alert|Toast)/i,
184
+ // Return statement with JSX template literal
185
+ /return\s+`[^`]*\$\{/,
186
+ // Template literals used for display
187
+ /['"`]Synced\s+/i,
188
+ /['"`]\d+\s*(h|hr|hour|m|min|minute|s|sec|second)s?\s+ago['"`]/i,
189
+ // Display formatting patterns
190
+ /\.toLocaleString\s*\(|\.toFixed\s*\(|\.padStart\s*\(/,
191
+ ];
192
+ return jsxUIPatterns.some(pattern => pattern.test(lineContent));
193
+ }
194
+ // Check if string is natural language (high ratio of common English words)
195
+ function isNaturalLanguage(str) {
196
+ // Skip short strings
197
+ if (str.length < 25)
198
+ return false;
199
+ // Common English words that appear in natural language
200
+ const commonWords = new Set([
201
+ 'the', 'a', 'an', 'is', 'are', 'was', 'were', 'be', 'been', 'being',
202
+ 'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would', 'could',
203
+ 'should', 'may', 'might', 'must', 'shall', 'can', 'need', 'to', 'of',
204
+ 'in', 'for', 'on', 'with', 'at', 'by', 'from', 'up', 'about', 'into',
205
+ 'through', 'during', 'before', 'after', 'above', 'below', 'between',
206
+ 'under', 'again', 'further', 'then', 'once', 'here', 'there', 'when',
207
+ 'where', 'why', 'how', 'all', 'each', 'few', 'more', 'most', 'other',
208
+ 'some', 'such', 'no', 'nor', 'not', 'only', 'own', 'same', 'so', 'than',
209
+ 'too', 'very', 'just', 'also', 'now', 'and', 'but', 'or', 'if', 'as',
210
+ 'your', 'you', 'this', 'that', 'it', 'they', 'we', 'he', 'she', 'my',
211
+ 'their', 'our', 'his', 'her', 'its', 'ago', 'synced', 'updated', 'created',
212
+ ]);
213
+ // Split into words and count common ones
214
+ const words = str.toLowerCase().split(/\s+/).filter(w => w.length > 1);
215
+ if (words.length < 3)
216
+ return false;
217
+ const commonWordCount = words.filter(w => commonWords.has(w.replace(/[^a-z]/g, ''))).length;
218
+ const commonWordRatio = commonWordCount / words.length;
219
+ // If more than 30% of words are common English words, it's likely natural language
220
+ return commonWordRatio > 0.3;
221
+ }
222
+ // Check if string looks like CSS/Tailwind classes
223
+ function isCSSClasses(str) {
224
+ // Tailwind/CSS class patterns
225
+ const cssIndicators = [
226
+ 'flex', 'grid', 'block', 'inline', 'hidden',
227
+ 'items-', 'justify-', 'gap-', 'space-',
228
+ 'text-', 'font-', 'bg-', 'border-', 'rounded',
229
+ 'px-', 'py-', 'pt-', 'pb-', 'pl-', 'pr-', 'p-',
230
+ 'mx-', 'my-', 'mt-', 'mb-', 'ml-', 'mr-', 'm-',
231
+ 'w-', 'h-', 'min-', 'max-',
232
+ 'hover:', 'focus:', 'active:', 'disabled:',
233
+ 'sm:', 'md:', 'lg:', 'xl:', '2xl:',
234
+ 'dark:', 'light:',
235
+ 'transition', 'duration-', 'ease-',
236
+ 'absolute', 'relative', 'fixed', 'sticky',
237
+ 'top-', 'bottom-', 'left-', 'right-',
238
+ 'z-', 'overflow-', 'opacity-',
239
+ 'ring-', 'shadow-', 'outline-',
240
+ ];
241
+ // Count how many CSS-like tokens are in the string
242
+ const tokens = str.toLowerCase().split(/\s+/);
243
+ const cssTokenCount = tokens.filter(token => cssIndicators.some(indicator => token.includes(indicator))).length;
244
+ // If more than 30% of tokens look like CSS classes, it's probably CSS
245
+ return cssTokenCount > 0 && (cssTokenCount / tokens.length) > 0.3;
246
+ }
247
+ // Check if string looks like CSS-in-JS (styled-components, emotion, etc.)
248
+ function isCSSInJS(lineContent) {
249
+ const cssInJSPatterns = [
250
+ /styled\./, // styled.div, styled.button
251
+ /styled\(/, // styled(Component)
252
+ /css`/, // css`` template literal
253
+ /keyframes`/, // keyframes`` template literal
254
+ /@emotion/, // @emotion imports
255
+ /createGlobalStyle/, // styled-components global
256
+ /\$\{\s*props\s*=>/, // ${props => ...} in styled
257
+ /\$\{\s*\(\s*\{/, // ${({ theme }) => ...}
258
+ ];
259
+ return cssInJSPatterns.some(p => p.test(lineContent));
260
+ }
261
+ // Check if file is documentation/README
262
+ function isDocumentationFile(filePath) {
263
+ const docPatterns = [
264
+ /README/i,
265
+ /CHANGELOG/i,
266
+ /CONTRIBUTING/i,
267
+ /LICENSE/i,
268
+ /CODE_OF_CONDUCT/i,
269
+ /SECURITY/i,
270
+ /AUTHORS/i,
271
+ /HISTORY/i,
272
+ /\.md$/i,
273
+ /\.mdx$/i,
274
+ /\.rst$/i, // reStructuredText
275
+ /\.adoc$/i, // AsciiDoc
276
+ /\.txt$/i, // Plain text docs
277
+ /\/docs\//i,
278
+ /\/documentation\//i,
279
+ /\/wiki\//i,
280
+ /\/guides?\//i,
281
+ /\/tutorials?\//i,
282
+ /\/examples?\//i, // Example directories often have sample configs
283
+ ];
284
+ return docPatterns.some(p => p.test(filePath));
285
+ }
286
+ // Check if string is a console.log/debug statement content
287
+ function isDebugLogContent(lineContent) {
288
+ const debugPatterns = [
289
+ /console\.(log|debug|info|warn|error)\s*\(/i,
290
+ /logger\.(log|debug|info|warn|error)\s*\(/i,
291
+ /\[.*Debug.*\]/i,
292
+ /\[.*Log.*\]/i,
293
+ ];
294
+ return debugPatterns.some(pattern => pattern.test(lineContent));
295
+ }
296
+ // Check if string is inline style (JSX or HTML)
297
+ function isInlineStyle(lineContent) {
298
+ // JSX inline styles
299
+ const jsxStylePatterns = [
300
+ /style\s*=\s*\{\{/, // style={{...}}
301
+ /style\s*=\s*\{[^}]*:/, // style={{ color: ... }}
302
+ /className\s*=\s*["`'][^"`']*gradient/i, // gradient classes
303
+ /className\s*=\s*["`'][^"`']*bg-/i, // bg- classes
304
+ ];
305
+ // HTML inline styles
306
+ const htmlStylePatterns = [
307
+ /style\s*=\s*["'][^"']*:/, // style="color: ..."
308
+ /<style[^>]*>/i, // <style> tags
309
+ /background:\s*linear-gradient/i, // CSS gradients
310
+ /background:\s*radial-gradient/i, // Radial gradients
311
+ ];
312
+ return [...jsxStylePatterns, ...htmlStylePatterns].some(p => p.test(lineContent));
313
+ }
314
+ // Check if string contains CSS tokens (colors, units, functions)
315
+ function hasCSSTokens(str) {
316
+ const cssTokens = [
317
+ // CSS units
318
+ /\d+px\b/, /\d+%\b/, /\d+em\b/, /\d+rem\b/, /\d+deg\b/, /\d+vh\b/, /\d+vw\b/,
319
+ // Hex colors (standalone or in context)
320
+ /#[0-9a-f]{3,8}\b/i,
321
+ // CSS color functions
322
+ /rgb\s*\(/, /rgba\s*\(/, /hsl\s*\(/, /hsla\s*\(/,
323
+ /oklab\s*\(/, /oklch\s*\(/, /lab\s*\(/, /lch\s*\(/, // Modern color functions
324
+ // CSS gradients (all types)
325
+ /linear-gradient/, /radial-gradient/, /conic-gradient/,
326
+ /repeating-linear-gradient/, /repeating-radial-gradient/,
327
+ // Gradient direction keywords (Tailwind-style)
328
+ /\bfrom-/, /\bto-/, /\bvia-/,
329
+ // CSS custom properties
330
+ /var\s*\(--/,
331
+ // Common CSS properties
332
+ /\bopacity\s*:\s*[\d.]+/,
333
+ /\btransform\s*:/,
334
+ /\btransition\s*:/,
335
+ /\banimation\s*:/,
336
+ // Box shadow patterns
337
+ /\bshadow-/, /box-shadow/,
338
+ /\d+px\s+\d+px\s+\d+px/, // Shadow offset pattern
339
+ // Color stops in gradients
340
+ /\b\d+%\s*(,|$)/, // Percentage color stops
341
+ ];
342
+ // Single strong indicators (only need 1 match)
343
+ const strongIndicators = [
344
+ /^#[0-9a-f]{6}$/i, // Standalone 6-digit hex color
345
+ /^#[0-9a-f]{8}$/i, // Standalone 8-digit hex color with alpha
346
+ /linear-gradient\s*\(/, // Gradient function
347
+ /radial-gradient\s*\(/,
348
+ /conic-gradient\s*\(/,
349
+ /rgba?\s*\(\s*\d/, // rgb/rgba with numbers
350
+ /hsla?\s*\(\s*\d/, // hsl/hsla with numbers
351
+ ];
352
+ // If any strong indicator matches, it's definitely CSS
353
+ if (strongIndicators.some(pattern => pattern.test(str))) {
354
+ return true;
355
+ }
356
+ // Must match at least 2 CSS indicators to be confident it's CSS
357
+ const tokenCount = cssTokens.filter(pattern => pattern.test(str)).length;
358
+ return tokenCount >= 2;
359
+ }
360
+ // Check if value/line contains environment variable placeholders (shell scripts, test files)
361
+ function isEnvVarPlaceholder(lineContent, value) {
362
+ // Shell script patterns
363
+ const shellEnvPatterns = [
364
+ /\$[A-Z_][A-Z0-9_]*/, // $VAR_NAME
365
+ /\$\{[A-Z_][A-Z0-9_]*\}/, // ${VAR_NAME}
366
+ /\bexport\s+[A-Z_][A-Z0-9_]*=["']?\$/, // export VAR=$OTHER
367
+ /:\s*\$\{[A-Z_][A-Z0-9_]*:-/, // ${VAR:-default}
368
+ ];
369
+ // Test file env var patterns (common placeholder names)
370
+ const testEnvPatterns = [
371
+ /FREE_KEY|PRO_KEY|ULTRA_KEY|TEST_KEY/i,
372
+ /BASE_URL|API_URL|ENDPOINT_URL/i,
373
+ /YOUR_[A-Z_]*KEY|REPLACE_[A-Z_]*KEY/i,
374
+ /\$\{?\w+\}?_KEY|\$\{?\w+\}?_TOKEN/i, // $SOME_KEY, ${SOME_TOKEN}
375
+ ];
376
+ return (shellEnvPatterns.some(p => p.test(lineContent)) ||
377
+ testEnvPatterns.some(p => p.test(value)) ||
378
+ testEnvPatterns.some(p => p.test(lineContent)));
379
+ }
380
+ function detectHighEntropyStrings(content, filePath) {
381
+ const vulnerabilities = [];
382
+ // Skip scanner/fixture files to avoid self-detection
383
+ if ((0, context_helpers_1.isScannerOrFixtureFile)(filePath)) {
384
+ return vulnerabilities;
385
+ }
386
+ // Skip fixture files (__fixtures__, .fixture., mock-data, etc.)
387
+ if ((0, context_helpers_1.isFixtureFile)(filePath)) {
388
+ return vulnerabilities;
389
+ }
390
+ // Skip example files
391
+ if ((0, context_helpers_1.isExampleFile)(filePath)) {
392
+ return vulnerabilities;
393
+ }
394
+ // Skip example directories (/examples/, /demos/, /tutorials/, etc.)
395
+ if ((0, context_helpers_1.isExampleDirectory)(filePath)) {
396
+ return vulnerabilities;
397
+ }
398
+ // Skip documentation/README files
399
+ if (isDocumentationFile(filePath)) {
400
+ return vulnerabilities;
401
+ }
402
+ const strings = extractStringLiterals(content);
403
+ for (const { value, line, lineContent } of strings) {
404
+ // Skip comments
405
+ if ((0, context_helpers_1.isComment)(lineContent))
406
+ continue;
407
+ // Skip PEM headers/footers (they look high-entropy but aren't secrets)
408
+ if (isPEMHeader(value))
409
+ continue;
410
+ // Skip encrypted content blocks (the payload, not the key)
411
+ if (isEncryptedContent(value, lineContent))
412
+ continue;
413
+ // Skip JWT segments (handled by patterns.ts for specific detection)
414
+ if (isJWTSegment(value))
415
+ continue;
416
+ // Skip inline styles (CSS/JSX style={{...}} or style="...")
417
+ if (isInlineStyle(lineContent))
418
+ continue;
419
+ // Skip strings with CSS tokens (colors, gradients, units)
420
+ if (hasCSSTokens(value))
421
+ continue;
422
+ // Skip environment variable placeholders (shell scripts, test files)
423
+ if (isEnvVarPlaceholder(lineContent, value))
424
+ continue;
425
+ // Skip safe patterns
426
+ if (isSafePattern(value))
427
+ continue;
428
+ // Skip CSS/Tailwind class strings
429
+ if (isCSSClasses(value))
430
+ continue;
431
+ // Skip CSS-in-JS patterns (styled-components, emotion)
432
+ if (isCSSInJS(lineContent))
433
+ continue;
434
+ // Skip debug log statements (they often contain env var names which look high-entropy)
435
+ if (isDebugLogContent(lineContent))
436
+ continue;
437
+ // Skip regex/route matcher patterns
438
+ if (isRegexPattern(value))
439
+ continue;
440
+ // Skip template literals with code expressions (they look high-entropy but aren't secrets)
441
+ if (isTemplateWithCode(value, lineContent))
442
+ continue;
443
+ // Skip human-readable text/markdown content
444
+ if (isHumanReadableContent(value))
445
+ continue;
446
+ // Skip UI strings (model names, descriptions, etc.)
447
+ if (isUIString(value, lineContent))
448
+ continue;
449
+ // Skip JSX UI context (component props, JSX text - like "Synced ${hours}h ago")
450
+ if (isJSXUIContext(lineContent))
451
+ continue;
452
+ // Skip natural language strings (high ratio of common English words)
453
+ if (isNaturalLanguage(value))
454
+ continue;
455
+ // Calculate entropy
456
+ const entropy = calculateEntropy(value);
457
+ // Determine if this is a test file (lower severity)
458
+ const inTestFile = (0, context_helpers_1.isTestOrMockFile)(filePath);
459
+ // Two thresholds:
460
+ // - entropy > 4.5 for strings > 20 chars (standard)
461
+ // - entropy > 4.2 for strings 16-20 chars (slightly stricter to reduce FPs)
462
+ const meetsThreshold = (entropy > 4.5 && value.length > 20) ||
463
+ (entropy > 4.2 && value.length >= 16 && value.length <= 20);
464
+ if (meetsThreshold) {
465
+ // Additional check: should have mix of character types
466
+ const hasLower = /[a-z]/.test(value);
467
+ const hasUpper = /[A-Z]/.test(value);
468
+ const hasDigit = /[0-9]/.test(value);
469
+ const hasSpecial = /[^a-zA-Z0-9]/.test(value);
470
+ const charTypes = [hasLower, hasUpper, hasDigit, hasSpecial].filter(Boolean).length;
471
+ // Only flag if it has at least 2 character types (looks like a secret)
472
+ if (charTypes >= 2) {
473
+ // Final check: skip CSS-like strings that passed earlier filters
474
+ const looksLikeCSS = /gradient|rgba?|hsla?|#[0-9a-f]{3,8}/i.test(value);
475
+ if (looksLikeCSS)
476
+ continue;
477
+ // Lower severity for test files
478
+ const baseSeverity = entropy > 5.0 ? 'high' : 'medium';
479
+ const severity = inTestFile ? 'low' : baseSeverity;
480
+ const confidence = inTestFile ? 'low' : (entropy > 5.0 ? 'high' : 'medium');
481
+ vulnerabilities.push({
482
+ id: `entropy-${filePath}-${line}`,
483
+ filePath,
484
+ lineNumber: line,
485
+ lineContent,
486
+ severity,
487
+ category: 'high_entropy_string',
488
+ title: 'Potential hardcoded secret detected',
489
+ description: `High-entropy string found (entropy: ${entropy.toFixed(2)}). This may be a hardcoded secret, API key, or password.${inTestFile ? ' (in test file)' : ''}`,
490
+ suggestedFix: 'Move this value to an environment variable and access it via process.env',
491
+ confidence,
492
+ layer: 1,
493
+ requiresAIValidation: true, // Entropy findings must be validated by AI
494
+ });
495
+ }
496
+ }
497
+ }
498
+ return vulnerabilities;
499
+ }
500
+ //# sourceMappingURL=entropy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entropy.js","sourceRoot":"","sources":["../../src/layer1/entropy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Layer 1: File Extension Red Flags
3
+ * Detects dangerous files that should not be in a repository
4
+ */
5
+ import type { Vulnerability } from '../types';
6
+ export declare function detectDangerousFiles(content: string, filePath: string): Vulnerability[];
7
+ //# sourceMappingURL=file-flags.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-flags.d.ts","sourceRoot":"","sources":["../../src/layer1/file-flags.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAqD7C,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,aAAa,EAAE,CAiEjB"}
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ /**
3
+ * Layer 1: File Extension Red Flags
4
+ * Detects dangerous files that should not be in a repository
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.detectDangerousFiles = detectDangerousFiles;
8
+ // Dangerous file extensions and names that should not be committed
9
+ const DANGEROUS_FILE_PATTERNS = [
10
+ // Private keys
11
+ { pattern: /\.pem$/i, name: 'PEM Private Key', severity: 'critical' },
12
+ { pattern: /\.key$/i, name: 'Private Key File', severity: 'critical' },
13
+ { pattern: /\.p12$/i, name: 'PKCS#12 Certificate', severity: 'critical' },
14
+ { pattern: /\.pfx$/i, name: 'PFX Certificate', severity: 'critical' },
15
+ { pattern: /\.p8$/i, name: 'PKCS#8 Private Key', severity: 'critical' },
16
+ // SSH keys
17
+ { pattern: /id_rsa$/i, name: 'RSA SSH Private Key', severity: 'critical' },
18
+ { pattern: /id_dsa$/i, name: 'DSA SSH Private Key', severity: 'critical' },
19
+ { pattern: /id_ecdsa$/i, name: 'ECDSA SSH Private Key', severity: 'critical' },
20
+ { pattern: /id_ed25519$/i, name: 'Ed25519 SSH Private Key', severity: 'critical' },
21
+ // Environment files (should be gitignored)
22
+ { pattern: /^\.env$/i, name: 'Environment File', severity: 'critical' },
23
+ { pattern: /^\.env\.local$/i, name: 'Local Environment File', severity: 'critical' },
24
+ { pattern: /^\.env\.production$/i, name: 'Production Environment File', severity: 'critical' },
25
+ { pattern: /^\.env\.development$/i, name: 'Development Environment File', severity: 'high' },
26
+ { pattern: /^\.env\.staging$/i, name: 'Staging Environment File', severity: 'high' },
27
+ // Credential files
28
+ { pattern: /\.pgpass$/i, name: 'PostgreSQL Password File', severity: 'critical' },
29
+ { pattern: /\.npmrc$/i, name: 'NPM Configuration (may contain tokens)', severity: 'high' },
30
+ { pattern: /\.pypirc$/i, name: 'PyPI Configuration (may contain tokens)', severity: 'high' },
31
+ { pattern: /\.netrc$/i, name: 'Netrc File (contains credentials)', severity: 'critical' },
32
+ { pattern: /\.htpasswd$/i, name: 'Apache Password File', severity: 'critical' },
33
+ // Database files
34
+ { pattern: /\.sqlite$/i, name: 'SQLite Database', severity: 'medium' },
35
+ { pattern: /\.sqlite3$/i, name: 'SQLite Database', severity: 'medium' },
36
+ { pattern: /\.db$/i, name: 'Database File', severity: 'medium' },
37
+ // Backup files that may contain secrets
38
+ { pattern: /\.bak$/i, name: 'Backup File', severity: 'low' },
39
+ { pattern: /\.backup$/i, name: 'Backup File', severity: 'low' },
40
+ { pattern: /\.old$/i, name: 'Old File Backup', severity: 'low' },
41
+ // Keystore files
42
+ { pattern: /\.jks$/i, name: 'Java Keystore', severity: 'high' },
43
+ { pattern: /\.keystore$/i, name: 'Keystore File', severity: 'high' },
44
+ ];
45
+ // Files that are okay in certain contexts but should be reviewed
46
+ const CONTEXT_SENSITIVE_PATTERNS = [
47
+ { pattern: /\.env\.example$/i, name: 'Environment Example File', checkContent: true },
48
+ { pattern: /\.env\.sample$/i, name: 'Environment Sample File', checkContent: true },
49
+ { pattern: /\.env\.template$/i, name: 'Environment Template File', checkContent: true },
50
+ ];
51
+ function detectDangerousFiles(content, filePath) {
52
+ const vulnerabilities = [];
53
+ const fileName = filePath.split('/').pop() || '';
54
+ // Check for dangerous file patterns
55
+ for (const { pattern, name, severity } of DANGEROUS_FILE_PATTERNS) {
56
+ if (pattern.test(fileName) || pattern.test(filePath)) {
57
+ vulnerabilities.push({
58
+ id: `file-flag-${filePath}`,
59
+ filePath,
60
+ lineNumber: 1,
61
+ lineContent: `File: ${fileName}`,
62
+ severity,
63
+ category: 'dangerous_file',
64
+ title: `Dangerous file detected: ${name}`,
65
+ description: `This file type (${name}) should not be committed to version control as it may contain sensitive information.`,
66
+ suggestedFix: 'Add this file to .gitignore and remove it from the repository. If it contains secrets, rotate them immediately.',
67
+ confidence: 'high',
68
+ layer: 1,
69
+ });
70
+ }
71
+ }
72
+ // Check context-sensitive files for actual secrets
73
+ for (const { pattern, name, checkContent } of CONTEXT_SENSITIVE_PATTERNS) {
74
+ if ((pattern.test(fileName) || pattern.test(filePath)) && checkContent) {
75
+ // Check if the example/sample file contains what looks like real values
76
+ const suspiciousPatterns = [
77
+ /[a-zA-Z0-9_]+=sk-[a-zA-Z0-9]{20,}/, // API keys
78
+ /[a-zA-Z0-9_]+=ghp_[a-zA-Z0-9]{36,}/, // GitHub tokens
79
+ /[a-zA-Z0-9_]+=eyJ[a-zA-Z0-9_-]+\./, // JWT tokens
80
+ /password\s*=\s*[^\s$]{8,}/i, // Passwords (not env vars)
81
+ ];
82
+ const lines = content.split('\n');
83
+ for (let i = 0; i < lines.length; i++) {
84
+ const line = lines[i];
85
+ // Skip lines that reference environment variables
86
+ if (line.includes('${') || line.includes('$env:') || line.includes('process.env')) {
87
+ continue;
88
+ }
89
+ for (const suspicious of suspiciousPatterns) {
90
+ if (suspicious.test(line)) {
91
+ vulnerabilities.push({
92
+ id: `file-flag-content-${filePath}-${i + 1}`,
93
+ filePath,
94
+ lineNumber: i + 1,
95
+ lineContent: line.trim(),
96
+ severity: 'high',
97
+ category: 'dangerous_file',
98
+ title: `${name} may contain real secrets`,
99
+ description: 'This example/sample file appears to contain real secret values instead of placeholders.',
100
+ suggestedFix: 'Replace real values with placeholders like YOUR_API_KEY_HERE or use environment variable references.',
101
+ confidence: 'medium',
102
+ layer: 1,
103
+ });
104
+ break;
105
+ }
106
+ }
107
+ }
108
+ }
109
+ }
110
+ return vulnerabilities;
111
+ }
112
+ //# sourceMappingURL=file-flags.js.map