@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.
- package/dist/formatters/cli-terminal.d.ts +27 -0
- package/dist/formatters/cli-terminal.d.ts.map +1 -0
- package/dist/formatters/cli-terminal.js +412 -0
- package/dist/formatters/cli-terminal.js.map +1 -0
- package/dist/formatters/github-comment.d.ts +41 -0
- package/dist/formatters/github-comment.d.ts.map +1 -0
- package/dist/formatters/github-comment.js +306 -0
- package/dist/formatters/github-comment.js.map +1 -0
- package/dist/formatters/grouping.d.ts +52 -0
- package/dist/formatters/grouping.d.ts.map +1 -0
- package/dist/formatters/grouping.js +152 -0
- package/dist/formatters/grouping.js.map +1 -0
- package/dist/formatters/index.d.ts +9 -0
- package/dist/formatters/index.d.ts.map +1 -0
- package/dist/formatters/index.js +35 -0
- package/dist/formatters/index.js.map +1 -0
- package/dist/formatters/vscode-diagnostic.d.ts +103 -0
- package/dist/formatters/vscode-diagnostic.d.ts.map +1 -0
- package/dist/formatters/vscode-diagnostic.js +151 -0
- package/dist/formatters/vscode-diagnostic.js.map +1 -0
- package/dist/index.d.ts +52 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +648 -0
- package/dist/index.js.map +1 -0
- package/dist/layer1/comments.d.ts +8 -0
- package/dist/layer1/comments.d.ts.map +1 -0
- package/dist/layer1/comments.js +203 -0
- package/dist/layer1/comments.js.map +1 -0
- package/dist/layer1/config-audit.d.ts +8 -0
- package/dist/layer1/config-audit.d.ts.map +1 -0
- package/dist/layer1/config-audit.js +252 -0
- package/dist/layer1/config-audit.js.map +1 -0
- package/dist/layer1/entropy.d.ts +8 -0
- package/dist/layer1/entropy.d.ts.map +1 -0
- package/dist/layer1/entropy.js +500 -0
- package/dist/layer1/entropy.js.map +1 -0
- package/dist/layer1/file-flags.d.ts +7 -0
- package/dist/layer1/file-flags.d.ts.map +1 -0
- package/dist/layer1/file-flags.js +112 -0
- package/dist/layer1/file-flags.js.map +1 -0
- package/dist/layer1/index.d.ts +36 -0
- package/dist/layer1/index.d.ts.map +1 -0
- package/dist/layer1/index.js +132 -0
- package/dist/layer1/index.js.map +1 -0
- package/dist/layer1/patterns.d.ts +8 -0
- package/dist/layer1/patterns.d.ts.map +1 -0
- package/dist/layer1/patterns.js +482 -0
- package/dist/layer1/patterns.js.map +1 -0
- package/dist/layer1/urls.d.ts +8 -0
- package/dist/layer1/urls.d.ts.map +1 -0
- package/dist/layer1/urls.js +296 -0
- package/dist/layer1/urls.js.map +1 -0
- package/dist/layer1/weak-crypto.d.ts +7 -0
- package/dist/layer1/weak-crypto.d.ts.map +1 -0
- package/dist/layer1/weak-crypto.js +291 -0
- package/dist/layer1/weak-crypto.js.map +1 -0
- package/dist/layer2/ai-agent-tools.d.ts +19 -0
- package/dist/layer2/ai-agent-tools.d.ts.map +1 -0
- package/dist/layer2/ai-agent-tools.js +528 -0
- package/dist/layer2/ai-agent-tools.js.map +1 -0
- package/dist/layer2/ai-endpoint-protection.d.ts +36 -0
- package/dist/layer2/ai-endpoint-protection.d.ts.map +1 -0
- package/dist/layer2/ai-endpoint-protection.js +332 -0
- package/dist/layer2/ai-endpoint-protection.js.map +1 -0
- package/dist/layer2/ai-execution-sinks.d.ts +18 -0
- package/dist/layer2/ai-execution-sinks.d.ts.map +1 -0
- package/dist/layer2/ai-execution-sinks.js +496 -0
- package/dist/layer2/ai-execution-sinks.js.map +1 -0
- package/dist/layer2/ai-fingerprinting.d.ts +7 -0
- package/dist/layer2/ai-fingerprinting.d.ts.map +1 -0
- package/dist/layer2/ai-fingerprinting.js +654 -0
- package/dist/layer2/ai-fingerprinting.js.map +1 -0
- package/dist/layer2/ai-prompt-hygiene.d.ts +19 -0
- package/dist/layer2/ai-prompt-hygiene.d.ts.map +1 -0
- package/dist/layer2/ai-prompt-hygiene.js +356 -0
- package/dist/layer2/ai-prompt-hygiene.js.map +1 -0
- package/dist/layer2/ai-rag-safety.d.ts +21 -0
- package/dist/layer2/ai-rag-safety.d.ts.map +1 -0
- package/dist/layer2/ai-rag-safety.js +459 -0
- package/dist/layer2/ai-rag-safety.js.map +1 -0
- package/dist/layer2/ai-schema-validation.d.ts +25 -0
- package/dist/layer2/ai-schema-validation.d.ts.map +1 -0
- package/dist/layer2/ai-schema-validation.js +375 -0
- package/dist/layer2/ai-schema-validation.js.map +1 -0
- package/dist/layer2/auth-antipatterns.d.ts +20 -0
- package/dist/layer2/auth-antipatterns.d.ts.map +1 -0
- package/dist/layer2/auth-antipatterns.js +333 -0
- package/dist/layer2/auth-antipatterns.js.map +1 -0
- package/dist/layer2/byok-patterns.d.ts +12 -0
- package/dist/layer2/byok-patterns.d.ts.map +1 -0
- package/dist/layer2/byok-patterns.js +299 -0
- package/dist/layer2/byok-patterns.js.map +1 -0
- package/dist/layer2/dangerous-functions.d.ts +7 -0
- package/dist/layer2/dangerous-functions.d.ts.map +1 -0
- package/dist/layer2/dangerous-functions.js +1375 -0
- package/dist/layer2/dangerous-functions.js.map +1 -0
- package/dist/layer2/data-exposure.d.ts +16 -0
- package/dist/layer2/data-exposure.d.ts.map +1 -0
- package/dist/layer2/data-exposure.js +279 -0
- package/dist/layer2/data-exposure.js.map +1 -0
- package/dist/layer2/framework-checks.d.ts +7 -0
- package/dist/layer2/framework-checks.d.ts.map +1 -0
- package/dist/layer2/framework-checks.js +388 -0
- package/dist/layer2/framework-checks.js.map +1 -0
- package/dist/layer2/index.d.ts +58 -0
- package/dist/layer2/index.d.ts.map +1 -0
- package/dist/layer2/index.js +380 -0
- package/dist/layer2/index.js.map +1 -0
- package/dist/layer2/logic-gates.d.ts +7 -0
- package/dist/layer2/logic-gates.d.ts.map +1 -0
- package/dist/layer2/logic-gates.js +182 -0
- package/dist/layer2/logic-gates.js.map +1 -0
- package/dist/layer2/risky-imports.d.ts +7 -0
- package/dist/layer2/risky-imports.d.ts.map +1 -0
- package/dist/layer2/risky-imports.js +161 -0
- package/dist/layer2/risky-imports.js.map +1 -0
- package/dist/layer2/variables.d.ts +8 -0
- package/dist/layer2/variables.d.ts.map +1 -0
- package/dist/layer2/variables.js +152 -0
- package/dist/layer2/variables.js.map +1 -0
- package/dist/layer3/anthropic.d.ts +83 -0
- package/dist/layer3/anthropic.d.ts.map +1 -0
- package/dist/layer3/anthropic.js +1745 -0
- package/dist/layer3/anthropic.js.map +1 -0
- package/dist/layer3/index.d.ts +24 -0
- package/dist/layer3/index.d.ts.map +1 -0
- package/dist/layer3/index.js +119 -0
- package/dist/layer3/index.js.map +1 -0
- package/dist/layer3/openai.d.ts +25 -0
- package/dist/layer3/openai.d.ts.map +1 -0
- package/dist/layer3/openai.js +238 -0
- package/dist/layer3/openai.js.map +1 -0
- package/dist/layer3/package-check.d.ts +63 -0
- package/dist/layer3/package-check.d.ts.map +1 -0
- package/dist/layer3/package-check.js +508 -0
- package/dist/layer3/package-check.js.map +1 -0
- package/dist/modes/incremental.d.ts +66 -0
- package/dist/modes/incremental.d.ts.map +1 -0
- package/dist/modes/incremental.js +200 -0
- package/dist/modes/incremental.js.map +1 -0
- package/dist/tiers.d.ts +125 -0
- package/dist/tiers.d.ts.map +1 -0
- package/dist/tiers.js +234 -0
- package/dist/tiers.js.map +1 -0
- package/dist/types.d.ts +175 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +50 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/auth-helper-detector.d.ts +56 -0
- package/dist/utils/auth-helper-detector.d.ts.map +1 -0
- package/dist/utils/auth-helper-detector.js +360 -0
- package/dist/utils/auth-helper-detector.js.map +1 -0
- package/dist/utils/context-helpers.d.ts +96 -0
- package/dist/utils/context-helpers.d.ts.map +1 -0
- package/dist/utils/context-helpers.js +493 -0
- package/dist/utils/context-helpers.js.map +1 -0
- package/dist/utils/diff-detector.d.ts +53 -0
- package/dist/utils/diff-detector.d.ts.map +1 -0
- package/dist/utils/diff-detector.js +104 -0
- package/dist/utils/diff-detector.js.map +1 -0
- package/dist/utils/diff-parser.d.ts +80 -0
- package/dist/utils/diff-parser.d.ts.map +1 -0
- package/dist/utils/diff-parser.js +202 -0
- package/dist/utils/diff-parser.js.map +1 -0
- package/dist/utils/imported-auth-detector.d.ts +37 -0
- package/dist/utils/imported-auth-detector.d.ts.map +1 -0
- package/dist/utils/imported-auth-detector.js +251 -0
- package/dist/utils/imported-auth-detector.js.map +1 -0
- package/dist/utils/middleware-detector.d.ts +55 -0
- package/dist/utils/middleware-detector.d.ts.map +1 -0
- package/dist/utils/middleware-detector.js +260 -0
- package/dist/utils/middleware-detector.js.map +1 -0
- package/dist/utils/oauth-flow-detector.d.ts +41 -0
- package/dist/utils/oauth-flow-detector.d.ts.map +1 -0
- package/dist/utils/oauth-flow-detector.js +202 -0
- package/dist/utils/oauth-flow-detector.js.map +1 -0
- package/dist/utils/path-exclusions.d.ts +55 -0
- package/dist/utils/path-exclusions.d.ts.map +1 -0
- package/dist/utils/path-exclusions.js +222 -0
- package/dist/utils/path-exclusions.js.map +1 -0
- package/dist/utils/project-context-builder.d.ts +119 -0
- package/dist/utils/project-context-builder.d.ts.map +1 -0
- package/dist/utils/project-context-builder.js +534 -0
- package/dist/utils/project-context-builder.js.map +1 -0
- package/dist/utils/registry-clients.d.ts +93 -0
- package/dist/utils/registry-clients.d.ts.map +1 -0
- package/dist/utils/registry-clients.js +273 -0
- package/dist/utils/registry-clients.js.map +1 -0
- package/dist/utils/trpc-analyzer.d.ts +78 -0
- package/dist/utils/trpc-analyzer.d.ts.map +1 -0
- package/dist/utils/trpc-analyzer.js +297 -0
- package/dist/utils/trpc-analyzer.js.map +1 -0
- package/package.json +45 -0
- package/src/__tests__/benchmark/fixtures/false-positives.ts +227 -0
- package/src/__tests__/benchmark/fixtures/index.ts +68 -0
- package/src/__tests__/benchmark/fixtures/layer1/config-audit.ts +364 -0
- package/src/__tests__/benchmark/fixtures/layer1/hardcoded-secrets.ts +173 -0
- package/src/__tests__/benchmark/fixtures/layer1/high-entropy.ts +234 -0
- package/src/__tests__/benchmark/fixtures/layer1/index.ts +31 -0
- package/src/__tests__/benchmark/fixtures/layer1/sensitive-urls.ts +90 -0
- package/src/__tests__/benchmark/fixtures/layer1/weak-crypto.ts +197 -0
- package/src/__tests__/benchmark/fixtures/layer2/ai-agent-tools.ts +170 -0
- package/src/__tests__/benchmark/fixtures/layer2/ai-endpoint-protection.ts +418 -0
- package/src/__tests__/benchmark/fixtures/layer2/ai-execution-sinks.ts +189 -0
- package/src/__tests__/benchmark/fixtures/layer2/ai-fingerprinting.ts +316 -0
- package/src/__tests__/benchmark/fixtures/layer2/ai-prompt-hygiene.ts +178 -0
- package/src/__tests__/benchmark/fixtures/layer2/ai-rag-safety.ts +184 -0
- package/src/__tests__/benchmark/fixtures/layer2/ai-schema-validation.ts +434 -0
- package/src/__tests__/benchmark/fixtures/layer2/auth-antipatterns.ts +159 -0
- package/src/__tests__/benchmark/fixtures/layer2/byok-patterns.ts +112 -0
- package/src/__tests__/benchmark/fixtures/layer2/dangerous-functions.ts +246 -0
- package/src/__tests__/benchmark/fixtures/layer2/data-exposure.ts +168 -0
- package/src/__tests__/benchmark/fixtures/layer2/framework-checks.ts +346 -0
- package/src/__tests__/benchmark/fixtures/layer2/index.ts +67 -0
- package/src/__tests__/benchmark/fixtures/layer2/injection-vulnerabilities.ts +239 -0
- package/src/__tests__/benchmark/fixtures/layer2/logic-gates.ts +246 -0
- package/src/__tests__/benchmark/fixtures/layer2/risky-imports.ts +231 -0
- package/src/__tests__/benchmark/fixtures/layer2/variables.ts +167 -0
- package/src/__tests__/benchmark/index.ts +29 -0
- package/src/__tests__/benchmark/run-benchmark.ts +144 -0
- package/src/__tests__/benchmark/run-depth-validation.ts +206 -0
- package/src/__tests__/benchmark/run-real-world-test.ts +243 -0
- package/src/__tests__/benchmark/security-benchmark-script.ts +1737 -0
- package/src/__tests__/benchmark/tier-integration-script.ts +177 -0
- package/src/__tests__/benchmark/types.ts +144 -0
- package/src/__tests__/benchmark/utils/test-runner.ts +475 -0
- package/src/__tests__/regression/known-false-positives.test.ts +467 -0
- package/src/__tests__/snapshots/__snapshots__/scan-depth.test.ts.snap +178 -0
- package/src/__tests__/snapshots/scan-depth.test.ts +258 -0
- package/src/__tests__/validation/analyze-results.ts +542 -0
- package/src/__tests__/validation/extract-for-triage.ts +146 -0
- package/src/__tests__/validation/fp-deep-analysis.ts +327 -0
- package/src/__tests__/validation/run-validation.ts +364 -0
- package/src/__tests__/validation/triage-template.md +132 -0
- package/src/formatters/cli-terminal.ts +446 -0
- package/src/formatters/github-comment.ts +382 -0
- package/src/formatters/grouping.ts +190 -0
- package/src/formatters/index.ts +47 -0
- package/src/formatters/vscode-diagnostic.ts +243 -0
- package/src/index.ts +823 -0
- package/src/layer1/comments.ts +218 -0
- package/src/layer1/config-audit.ts +289 -0
- package/src/layer1/entropy.ts +583 -0
- package/src/layer1/file-flags.ts +127 -0
- package/src/layer1/index.ts +181 -0
- package/src/layer1/patterns.ts +516 -0
- package/src/layer1/urls.ts +334 -0
- package/src/layer1/weak-crypto.ts +328 -0
- package/src/layer2/ai-agent-tools.ts +601 -0
- package/src/layer2/ai-endpoint-protection.ts +387 -0
- package/src/layer2/ai-execution-sinks.ts +580 -0
- package/src/layer2/ai-fingerprinting.ts +758 -0
- package/src/layer2/ai-prompt-hygiene.ts +411 -0
- package/src/layer2/ai-rag-safety.ts +511 -0
- package/src/layer2/ai-schema-validation.ts +421 -0
- package/src/layer2/auth-antipatterns.ts +394 -0
- package/src/layer2/byok-patterns.ts +336 -0
- package/src/layer2/dangerous-functions.ts +1563 -0
- package/src/layer2/data-exposure.ts +315 -0
- package/src/layer2/framework-checks.ts +433 -0
- package/src/layer2/index.ts +473 -0
- package/src/layer2/logic-gates.ts +206 -0
- package/src/layer2/risky-imports.ts +186 -0
- package/src/layer2/variables.ts +166 -0
- package/src/layer3/anthropic.ts +2030 -0
- package/src/layer3/index.ts +130 -0
- package/src/layer3/package-check.ts +604 -0
- package/src/modes/incremental.ts +293 -0
- package/src/tiers.ts +318 -0
- package/src/types.ts +284 -0
- package/src/utils/auth-helper-detector.ts +443 -0
- package/src/utils/context-helpers.ts +535 -0
- package/src/utils/diff-detector.ts +135 -0
- package/src/utils/diff-parser.ts +272 -0
- package/src/utils/imported-auth-detector.ts +320 -0
- package/src/utils/middleware-detector.ts +333 -0
- package/src/utils/oauth-flow-detector.ts +246 -0
- package/src/utils/path-exclusions.ts +266 -0
- package/src/utils/project-context-builder.ts +707 -0
- package/src/utils/registry-clients.ts +351 -0
- 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
|