vibe-guard 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 (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +200 -0
  3. package/dist/bin/vibe-guard.d.ts +3 -0
  4. package/dist/bin/vibe-guard.d.ts.map +1 -0
  5. package/dist/bin/vibe-guard.js +119 -0
  6. package/dist/bin/vibe-guard.js.map +1 -0
  7. package/dist/index.d.ts +19 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +128 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/reporter.d.ts +13 -0
  12. package/dist/reporter.d.ts.map +1 -0
  13. package/dist/reporter.js +116 -0
  14. package/dist/reporter.js.map +1 -0
  15. package/dist/rules/directory-traversal.d.ts +14 -0
  16. package/dist/rules/directory-traversal.d.ts.map +1 -0
  17. package/dist/rules/directory-traversal.js +142 -0
  18. package/dist/rules/directory-traversal.js.map +1 -0
  19. package/dist/rules/exposed-secrets.d.ts +13 -0
  20. package/dist/rules/exposed-secrets.d.ts.map +1 -0
  21. package/dist/rules/exposed-secrets.js +137 -0
  22. package/dist/rules/exposed-secrets.js.map +1 -0
  23. package/dist/rules/hardcoded-sensitive-data.d.ts +13 -0
  24. package/dist/rules/hardcoded-sensitive-data.d.ts.map +1 -0
  25. package/dist/rules/hardcoded-sensitive-data.js +104 -0
  26. package/dist/rules/hardcoded-sensitive-data.js.map +1 -0
  27. package/dist/rules/index.d.ts +15 -0
  28. package/dist/rules/index.d.ts.map +1 -0
  29. package/dist/rules/index.js +54 -0
  30. package/dist/rules/index.js.map +1 -0
  31. package/dist/rules/insecure-dependencies.d.ts +16 -0
  32. package/dist/rules/insecure-dependencies.d.ts.map +1 -0
  33. package/dist/rules/insecure-dependencies.js +152 -0
  34. package/dist/rules/insecure-dependencies.js.map +1 -0
  35. package/dist/rules/insecure-http.d.ts +13 -0
  36. package/dist/rules/insecure-http.d.ts.map +1 -0
  37. package/dist/rules/insecure-http.js +91 -0
  38. package/dist/rules/insecure-http.js.map +1 -0
  39. package/dist/rules/missing-authentication.d.ts +14 -0
  40. package/dist/rules/missing-authentication.d.ts.map +1 -0
  41. package/dist/rules/missing-authentication.js +98 -0
  42. package/dist/rules/missing-authentication.js.map +1 -0
  43. package/dist/rules/missing-security-headers.d.ts +16 -0
  44. package/dist/rules/missing-security-headers.d.ts.map +1 -0
  45. package/dist/rules/missing-security-headers.js +158 -0
  46. package/dist/rules/missing-security-headers.js.map +1 -0
  47. package/dist/rules/open-cors.d.ts +11 -0
  48. package/dist/rules/open-cors.d.ts.map +1 -0
  49. package/dist/rules/open-cors.js +61 -0
  50. package/dist/rules/open-cors.js.map +1 -0
  51. package/dist/rules/sql-injection.d.ts +12 -0
  52. package/dist/rules/sql-injection.d.ts.map +1 -0
  53. package/dist/rules/sql-injection.js +95 -0
  54. package/dist/rules/sql-injection.js.map +1 -0
  55. package/dist/rules/unvalidated-input.d.ts +13 -0
  56. package/dist/rules/unvalidated-input.d.ts.map +1 -0
  57. package/dist/rules/unvalidated-input.js +128 -0
  58. package/dist/rules/unvalidated-input.js.map +1 -0
  59. package/dist/scanner.d.ts +15 -0
  60. package/dist/scanner.d.ts.map +1 -0
  61. package/dist/scanner.js +240 -0
  62. package/dist/scanner.js.map +1 -0
  63. package/dist/types/index.d.ts +66 -0
  64. package/dist/types/index.d.ts.map +1 -0
  65. package/dist/types/index.js +38 -0
  66. package/dist/types/index.js.map +1 -0
  67. package/package.json +72 -0
@@ -0,0 +1,14 @@
1
+ import { BaseRule, FileContent, SecurityIssue } from '../types';
2
+ export declare class DirectoryTraversalRule extends BaseRule {
3
+ readonly name = "directory-traversal";
4
+ readonly description = "Detects potential directory traversal vulnerabilities";
5
+ readonly severity: "high";
6
+ private readonly traversalPatterns;
7
+ private readonly safePatterns;
8
+ check(fileContent: FileContent): SecurityIssue[];
9
+ private hasSafePathHandling;
10
+ private isCommentOrTest;
11
+ private isImportStatement;
12
+ private isTestContext;
13
+ }
14
+ //# sourceMappingURL=directory-traversal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"directory-traversal.d.ts","sourceRoot":"","sources":["../../src/rules/directory-traversal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEhE,qBAAa,sBAAuB,SAAQ,QAAQ;IAClD,QAAQ,CAAC,IAAI,yBAAyB;IACtC,QAAQ,CAAC,WAAW,2DAA2D;IAC/E,QAAQ,CAAC,QAAQ,EAAG,MAAM,CAAU;IAEpC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CA+BhC;IAEF,OAAO,CAAC,QAAQ,CAAC,YAAY,CAe3B;IAEF,KAAK,CAAC,WAAW,EAAE,WAAW,GAAG,aAAa,EAAE;IAyChD,OAAO,CAAC,mBAAmB;IAY3B,OAAO,CAAC,eAAe;IA0BvB,OAAO,CAAC,iBAAiB;IAczB,OAAO,CAAC,aAAa;CAuBtB"}
@@ -0,0 +1,142 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DirectoryTraversalRule = void 0;
4
+ const types_1 = require("../types");
5
+ class DirectoryTraversalRule extends types_1.BaseRule {
6
+ constructor() {
7
+ super(...arguments);
8
+ this.name = 'directory-traversal';
9
+ this.description = 'Detects potential directory traversal vulnerabilities';
10
+ this.severity = 'high';
11
+ this.traversalPatterns = [
12
+ // Direct path traversal patterns
13
+ { pattern: /(?:readFile|writeFile|createReadStream|createWriteStream|unlink|rmdir|mkdir|stat|access)\s*\(\s*(?:req\.|request\.|input\.|params\.|query\.)[^)]*(?!\s*(?:path\.resolve|path\.join|path\.normalize))/gi, type: 'File operation with user input' },
14
+ // Express static file serving
15
+ { pattern: /express\.static\s*\(\s*(?:req\.|request\.|input\.|params\.|query\.)/gi, type: 'Express static serving with user input' },
16
+ { pattern: /res\.sendFile\s*\(\s*(?:req\.|request\.|input\.|params\.|query\.)/gi, type: 'Express sendFile with user input' },
17
+ // Path concatenation
18
+ { pattern: /['"`][^'"`]*\/['"`]\s*\+\s*(?:req\.|request\.|input\.|params\.|query\.)/gi, type: 'Path concatenation with user input' },
19
+ { pattern: /\$\{[^}]*(?:req\.|request\.|input\.|params\.|query\.)[^}]*\}/g, type: 'Template literal path with user input' },
20
+ // Dangerous path patterns (but not in imports/requires)
21
+ { pattern: /(?<!(?:import|require|from)\s+['"`][^'"`]*)\.\.\//g, type: 'Hardcoded directory traversal sequence' },
22
+ // Framework-specific patterns
23
+ { pattern: /File\s*\(\s*(?:req\.|request\.|input\.|params\.|query\.)/gi, type: 'File constructor with user input' },
24
+ { pattern: /FileInputStream\s*\(\s*(?:request\.getParameter|request\.getAttribute)/gi, type: 'Java FileInputStream with user input' },
25
+ { pattern: /fopen\s*\(\s*(?:\$_GET|\$_POST|\$_REQUEST)/gi, type: 'PHP fopen with user input' },
26
+ { pattern: /file_get_contents\s*\(\s*(?:\$_GET|\$_POST|\$_REQUEST)/gi, type: 'PHP file_get_contents with user input' },
27
+ // Python patterns
28
+ { pattern: /open\s*\(\s*(?:request\.|flask\.request\.)/gi, type: 'Python file open with user input' },
29
+ { pattern: /os\.path\.join\s*\([^)]*(?:request\.|flask\.request\.)/gi, type: 'Python path join with user input' },
30
+ // Node.js path operations
31
+ { pattern: /path\.join\s*\([^)]*(?:req\.|request\.|input\.|params\.|query\.)(?![^)]*(?:path\.resolve|path\.normalize))/gi, type: 'Path join without normalization' },
32
+ // Include/require with user input
33
+ { pattern: /(?:require|import)\s*\(\s*(?:req\.|request\.|input\.|params\.|query\.)/gi, type: 'Module import with user input' },
34
+ { pattern: /(?:include|require|include_once|require_once)\s*\(\s*(?:\$_GET|\$_POST|\$_REQUEST)/gi, type: 'PHP include with user input' }
35
+ ];
36
+ this.safePatterns = [
37
+ /path\.resolve/i,
38
+ /path\.normalize/i,
39
+ /path\.basename/i,
40
+ /sanitize/i,
41
+ /validate/i,
42
+ /whitelist/i,
43
+ /allowedPaths/i,
44
+ /isValidPath/i,
45
+ /checkPath/i,
46
+ /\.replace\s*\(\s*\/\.\.\//gi,
47
+ /\.replace\s*\(\s*\/\.\.\\/gi,
48
+ /filter/i,
49
+ /startsWith/i,
50
+ /includes.*allowed/i
51
+ ];
52
+ }
53
+ check(fileContent) {
54
+ const issues = [];
55
+ for (const { pattern, type } of this.traversalPatterns) {
56
+ const matches = this.findMatches(fileContent.content, pattern);
57
+ for (const { line, column, lineContent } of matches) {
58
+ // Skip if safe path handling is present
59
+ if (this.hasSafePathHandling(fileContent.content, line)) {
60
+ continue;
61
+ }
62
+ // Skip if it's in a comment or test file
63
+ if (this.isCommentOrTest(lineContent, fileContent.path)) {
64
+ continue;
65
+ }
66
+ // Skip if it's an import/require statement
67
+ if (this.isImportStatement(lineContent)) {
68
+ continue;
69
+ }
70
+ // Skip if it's a hardcoded traversal in a test context
71
+ if (type === 'Hardcoded directory traversal sequence' && this.isTestContext(fileContent.content, line)) {
72
+ continue;
73
+ }
74
+ issues.push(this.createIssue(fileContent.path, line, column, lineContent, `Potential directory traversal vulnerability: ${type}`, `Validate and sanitize file paths. Use path.resolve(), path.normalize(), or whitelist allowed directories. Never trust user input for file paths.`));
75
+ }
76
+ }
77
+ return issues;
78
+ }
79
+ hasSafePathHandling(content, lineNumber) {
80
+ const lines = content.split('\n');
81
+ const contextRange = 5; // Check 5 lines before and after
82
+ const startLine = Math.max(0, lineNumber - contextRange - 1);
83
+ const endLine = Math.min(lines.length, lineNumber + contextRange);
84
+ const contextLines = lines.slice(startLine, endLine).join('\n');
85
+ return this.safePatterns.some(pattern => pattern.test(contextLines));
86
+ }
87
+ isCommentOrTest(line, filePath) {
88
+ // Check if line is a comment
89
+ const commentPatterns = [
90
+ /^\s*\/\//, // JavaScript comment
91
+ /^\s*#/, // Python/Shell comment
92
+ /^\s*\*/ // Multi-line comment
93
+ ];
94
+ if (commentPatterns.some(pattern => pattern.test(line))) {
95
+ return true;
96
+ }
97
+ // Check if it's a test file
98
+ const testPatterns = [
99
+ /test/i,
100
+ /spec/i,
101
+ /\.test\./i,
102
+ /\.spec\./i,
103
+ /__tests__/i,
104
+ /tests\//i,
105
+ /spec\//i
106
+ ];
107
+ return testPatterns.some(pattern => pattern.test(filePath));
108
+ }
109
+ isImportStatement(line) {
110
+ const importPatterns = [
111
+ /^\s*import\s+.*from\s+['"`]/,
112
+ /^\s*import\s+['"`]/,
113
+ /^\s*const\s+.*=\s+require\s*\(\s*['"`]/,
114
+ /^\s*let\s+.*=\s+require\s*\(\s*['"`]/,
115
+ /^\s*var\s+.*=\s+require\s*\(\s*['"`]/,
116
+ /^\s*export\s+.*from\s+['"`]/,
117
+ /^\s*from\s+['"`]/
118
+ ];
119
+ return importPatterns.some(pattern => pattern.test(line));
120
+ }
121
+ isTestContext(content, lineNumber) {
122
+ const lines = content.split('\n');
123
+ const contextRange = 3;
124
+ const startLine = Math.max(0, lineNumber - contextRange - 1);
125
+ const endLine = Math.min(lines.length, lineNumber + contextRange);
126
+ const contextLines = lines.slice(startLine, endLine).join('\n');
127
+ const testPatterns = [
128
+ /test/i,
129
+ /spec/i,
130
+ /describe/i,
131
+ /it\(/i,
132
+ /expect/i,
133
+ /assert/i,
134
+ /mock/i,
135
+ /example/i,
136
+ /demo/i
137
+ ];
138
+ return testPatterns.some(pattern => pattern.test(contextLines));
139
+ }
140
+ }
141
+ exports.DirectoryTraversalRule = DirectoryTraversalRule;
142
+ //# sourceMappingURL=directory-traversal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"directory-traversal.js","sourceRoot":"","sources":["../../src/rules/directory-traversal.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { BaseRule, FileContent, SecurityIssue } from '../types';
2
+ export declare class ExposedSecretsRule extends BaseRule {
3
+ readonly name = "exposed-secrets";
4
+ readonly description = "Detects exposed API keys, tokens, and credentials";
5
+ readonly severity: "critical";
6
+ private readonly secretPatterns;
7
+ private readonly falsePositivePatterns;
8
+ check(fileContent: FileContent): SecurityIssue[];
9
+ private isFalsePositive;
10
+ private isValidBase64Secret;
11
+ private maskSecret;
12
+ }
13
+ //# sourceMappingURL=exposed-secrets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exposed-secrets.d.ts","sourceRoot":"","sources":["../../src/rules/exposed-secrets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEhE,qBAAa,kBAAmB,SAAQ,QAAQ;IAC9C,QAAQ,CAAC,IAAI,qBAAqB;IAClC,QAAQ,CAAC,WAAW,uDAAuD;IAC3E,QAAQ,CAAC,QAAQ,EAAG,UAAU,CAAU;IAExC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAiC7B;IAEF,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAoBpC;IAEF,KAAK,CAAC,WAAW,EAAE,WAAW,GAAG,aAAa,EAAE;IAiChD,OAAO,CAAC,eAAe;IAyBvB,OAAO,CAAC,mBAAmB;IAiC3B,OAAO,CAAC,UAAU;CAWnB"}
@@ -0,0 +1,137 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ExposedSecretsRule = void 0;
4
+ const types_1 = require("../types");
5
+ class ExposedSecretsRule extends types_1.BaseRule {
6
+ constructor() {
7
+ super(...arguments);
8
+ this.name = 'exposed-secrets';
9
+ this.description = 'Detects exposed API keys, tokens, and credentials';
10
+ this.severity = 'critical';
11
+ this.secretPatterns = [
12
+ // API Keys
13
+ { pattern: /(?:api[_-]?key|apikey)\s*[:=]\s*['"`]([a-zA-Z0-9_\-]{20,})/gi, type: 'API Key' },
14
+ { pattern: /(?:secret[_-]?key|secretkey)\s*[:=]\s*['"`]([a-zA-Z0-9_\-]{20,})/gi, type: 'Secret Key' },
15
+ { pattern: /(?:access[_-]?token|accesstoken)\s*[:=]\s*['"`]([a-zA-Z0-9_\-]{20,})/gi, type: 'Access Token' },
16
+ // AWS
17
+ { pattern: /AKIA[0-9A-Z]{16}/g, type: 'AWS Access Key' },
18
+ { pattern: /(?:aws[_-]?secret|AWS_SECRET)\s*[:=]\s*['"`]([a-zA-Z0-9/+=]{40})/gi, type: 'AWS Secret' },
19
+ // GitHub
20
+ { pattern: /ghp_[a-zA-Z0-9]{36}/g, type: 'GitHub Personal Access Token' },
21
+ { pattern: /ghs_[a-zA-Z0-9]{36}/g, type: 'GitHub App Token' },
22
+ { pattern: /ghr_[a-zA-Z0-9]{36}/g, type: 'GitHub Refresh Token' },
23
+ // Google
24
+ { pattern: /AIza[0-9A-Za-z_\-]{35}/g, type: 'Google API Key' },
25
+ // Slack
26
+ { pattern: /xox[baprs]-[0-9a-zA-Z\-]{10,}/g, type: 'Slack Token' },
27
+ // JWT
28
+ { pattern: /eyJ[a-zA-Z0-9_\-]*\.eyJ[a-zA-Z0-9_\-]*\.[a-zA-Z0-9_\-]*/g, type: 'JWT Token' },
29
+ // Database URLs
30
+ { pattern: /(?:mongodb|mysql|postgres|redis):\/\/[^\s'"]+/gi, type: 'Database URL' },
31
+ // Base64 encoded secrets (more specific pattern)
32
+ { pattern: /(?:secret|token|key|auth|password)\s*[:=]\s*['"`]([A-Za-z0-9+/]{40,}={0,2})['"`]/gi, type: 'Base64 Encoded Secret' },
33
+ // Generic patterns (more specific to avoid variable names)
34
+ { pattern: /(?:password|passwd|pwd)\s*[:=]\s*['"`]([^'"`\s]{8,})/gi, type: 'Password' },
35
+ { pattern: /(?:^|[^a-zA-Z0-9_])(?:token|auth)\s*[:=]\s*['"`]([a-zA-Z0-9_\-]{20,})/gi, type: 'Auth Token' }
36
+ ];
37
+ this.falsePositivePatterns = [
38
+ /example/i,
39
+ /demo/i,
40
+ /placeholder/i,
41
+ /your[_-]?key/i,
42
+ /your[_-]?token/i,
43
+ /your[_-]?secret/i,
44
+ /\$\{.*\}/, // Environment variables
45
+ /%.*%/, // Windows environment variables
46
+ /\{\{.*\}\}/, // Template variables
47
+ /^xxx+$/i, // Only xxx repeated
48
+ /^aaa+$/i, // Only aaa repeated
49
+ /^000+$/, // Only zeros repeated
50
+ /^111+$/, // Only ones repeated
51
+ /^123+$/, // Only 123 repeated
52
+ /test/i, // Test values
53
+ /mock/i, // Mock values
54
+ /sample/i, // Sample values
55
+ /dummy/i, // Dummy values
56
+ /^(.)\1{7,}$/ // Any character repeated 8+ times
57
+ ];
58
+ }
59
+ check(fileContent) {
60
+ const issues = [];
61
+ for (const { pattern, type } of this.secretPatterns) {
62
+ const matches = this.findMatches(fileContent.content, pattern);
63
+ for (const { match, line, column, lineContent } of matches) {
64
+ const matchedText = match[0];
65
+ // Skip false positives
66
+ if (this.isFalsePositive(matchedText)) {
67
+ continue;
68
+ }
69
+ // Additional validation for Base64 secrets
70
+ if (type === 'Base64 Encoded Secret' && !this.isValidBase64Secret(matchedText)) {
71
+ continue;
72
+ }
73
+ issues.push(this.createIssue(fileContent.path, line, column, lineContent, `Exposed ${type} detected: ${this.maskSecret(matchedText)}`, `Remove hardcoded secrets and use environment variables or secure secret management instead. Consider using tools like dotenv for local development.`));
74
+ }
75
+ }
76
+ return issues;
77
+ }
78
+ isFalsePositive(text) {
79
+ // Check against false positive patterns first
80
+ if (this.falsePositivePatterns.some(pattern => pattern.test(text))) {
81
+ return true;
82
+ }
83
+ // Extract the actual secret value from the match
84
+ const secretMatch = text.match(/['"`]([^'"`]+)['"`]/);
85
+ if (secretMatch && secretMatch[1]) {
86
+ const secretValue = secretMatch[1];
87
+ // Check if it's all the same character repeated
88
+ if (/^(.)\1{7,}$/.test(secretValue)) {
89
+ return true;
90
+ }
91
+ // Check if it's a simple pattern like 123456789...
92
+ if (/^(012|123|234|345|456|567|678|789|890)+$/.test(secretValue)) {
93
+ return true;
94
+ }
95
+ }
96
+ return false;
97
+ }
98
+ isValidBase64Secret(text) {
99
+ try {
100
+ // Extract the base64 part from the match
101
+ const base64Match = text.match(/([A-Za-z0-9+/]{32,}={0,2})/);
102
+ if (!base64Match || !base64Match[1])
103
+ return false;
104
+ const base64String = base64Match[1];
105
+ // Check if it's valid base64
106
+ const decoded = Buffer.from(base64String, 'base64').toString('utf-8');
107
+ // Skip if it decodes to common false positives
108
+ if (/^(test|example|demo|placeholder|sample|dummy)/i.test(decoded)) {
109
+ return false;
110
+ }
111
+ // Skip if it's too short when decoded (likely not a real secret)
112
+ if (decoded.length < 8) {
113
+ return false;
114
+ }
115
+ // Skip if it contains only repeated characters
116
+ if (/^(.)\1+$/.test(decoded)) {
117
+ return false;
118
+ }
119
+ return true;
120
+ }
121
+ catch {
122
+ // If we can't decode it, it's probably not valid base64
123
+ return false;
124
+ }
125
+ }
126
+ maskSecret(secret) {
127
+ if (secret.length <= 8) {
128
+ return '*'.repeat(secret.length);
129
+ }
130
+ const start = secret.substring(0, 4);
131
+ const end = secret.substring(secret.length - 4);
132
+ const middle = '*'.repeat(Math.min(secret.length - 8, 10));
133
+ return `${start}${middle}${end}`;
134
+ }
135
+ }
136
+ exports.ExposedSecretsRule = ExposedSecretsRule;
137
+ //# sourceMappingURL=exposed-secrets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exposed-secrets.js","sourceRoot":"","sources":["../../src/rules/exposed-secrets.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { BaseRule, FileContent, SecurityIssue } from '../types';
2
+ export declare class HardcodedSensitiveDataRule extends BaseRule {
3
+ readonly name = "hardcoded-sensitive-data";
4
+ readonly description = "Detects hardcoded sensitive information in configuration files";
5
+ readonly severity: "critical";
6
+ private readonly sensitivePatterns;
7
+ private readonly falsePositivePatterns;
8
+ check(fileContent: FileContent): SecurityIssue[];
9
+ private isSensitiveFile;
10
+ private isFalsePositive;
11
+ private maskSensitiveData;
12
+ }
13
+ //# sourceMappingURL=hardcoded-sensitive-data.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hardcoded-sensitive-data.d.ts","sourceRoot":"","sources":["../../src/rules/hardcoded-sensitive-data.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEhE,qBAAa,0BAA2B,SAAQ,QAAQ;IACtD,QAAQ,CAAC,IAAI,8BAA8B;IAC3C,QAAQ,CAAC,WAAW,oEAAoE;IACxF,QAAQ,CAAC,QAAQ,EAAG,UAAU,CAAU;IAExC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAwBhC;IAEF,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAgBpC;IAEF,KAAK,CAAC,WAAW,EAAE,WAAW,GAAG,aAAa,EAAE;IAiChD,OAAO,CAAC,eAAe;IAwBvB,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,iBAAiB;CAW1B"}
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HardcodedSensitiveDataRule = void 0;
4
+ const types_1 = require("../types");
5
+ class HardcodedSensitiveDataRule extends types_1.BaseRule {
6
+ constructor() {
7
+ super(...arguments);
8
+ this.name = 'hardcoded-sensitive-data';
9
+ this.description = 'Detects hardcoded sensitive information in configuration files';
10
+ this.severity = 'critical';
11
+ this.sensitivePatterns = [
12
+ // Database connections
13
+ { pattern: /(?:database_url|db_url|connection_string)\s*[:=]\s*['"`]([^'"`\s]+)['"`]/gi, type: 'Database Connection' },
14
+ { pattern: /(?:mongodb|mysql|postgres|redis):\/\/[^'"`\s]+/gi, type: 'Database URL' },
15
+ // Encryption keys
16
+ { pattern: /(?:encryption_key|secret_key|private_key)\s*[:=]\s*['"`]([a-zA-Z0-9+/=]{20,})['"`]/gi, type: 'Encryption Key' },
17
+ { pattern: /-----BEGIN\s+(?:RSA\s+)?PRIVATE\s+KEY-----/gi, type: 'Private Key' },
18
+ // Configuration secrets
19
+ { pattern: /(?:app_secret|session_secret|jwt_secret)\s*[:=]\s*['"`]([^'"`\s]{16,})['"`]/gi, type: 'Application Secret' },
20
+ { pattern: /(?:salt|hash_salt)\s*[:=]\s*['"`]([^'"`\s]{8,})['"`]/gi, type: 'Cryptographic Salt' },
21
+ // Third-party service keys
22
+ { pattern: /(?:stripe_secret|stripe_key)\s*[:=]\s*['"`](sk_[a-zA-Z0-9_]+)['"`]/gi, type: 'Stripe Secret Key' },
23
+ { pattern: /(?:sendgrid_api_key)\s*[:=]\s*['"`](SG\.[a-zA-Z0-9_\-\.]+)['"`]/gi, type: 'SendGrid API Key' },
24
+ { pattern: /(?:twilio_auth_token)\s*[:=]\s*['"`]([a-zA-Z0-9]{32})['"`]/gi, type: 'Twilio Auth Token' },
25
+ // Generic sensitive patterns
26
+ { pattern: /(?:admin_password|root_password|db_password)\s*[:=]\s*['"`]([^'"`\s]{6,})['"`]/gi, type: 'Admin Password' },
27
+ { pattern: /(?:webhook_secret|signing_secret)\s*[:=]\s*['"`]([^'"`\s]{16,})['"`]/gi, type: 'Webhook Secret' },
28
+ // Configuration file patterns
29
+ { pattern: /password\s*[:=]\s*['"`](?!.*(?:password|secret|key|token))[^'"`\s]{8,}['"`]/gi, type: 'Configuration Password' }
30
+ ];
31
+ this.falsePositivePatterns = [
32
+ /example/i,
33
+ /sample/i,
34
+ /demo/i,
35
+ /placeholder/i,
36
+ /your[_-]?(?:key|secret|password)/i,
37
+ /\$\{.*\}/, // Environment variables
38
+ /%.*%/, // Windows environment variables
39
+ /\{\{.*\}\}/, // Template variables
40
+ /^[x]+$/i, // Only x's
41
+ /^[*]+$/, // Only asterisks
42
+ /^[0]+$/, // Only zeros
43
+ /^[1]+$/, // Only ones
44
+ /test/i,
45
+ /mock/i,
46
+ /fake/i
47
+ ];
48
+ }
49
+ check(fileContent) {
50
+ const issues = [];
51
+ // Focus on configuration files and certain code files
52
+ if (!this.isSensitiveFile(fileContent.path)) {
53
+ return issues;
54
+ }
55
+ for (const { pattern, type } of this.sensitivePatterns) {
56
+ const matches = this.findMatches(fileContent.content, pattern);
57
+ for (const { match, line, column, lineContent } of matches) {
58
+ const matchedText = match[0];
59
+ // Skip false positives
60
+ if (this.isFalsePositive(matchedText)) {
61
+ continue;
62
+ }
63
+ issues.push(this.createIssue(fileContent.path, line, column, lineContent, `Hardcoded ${type} found: ${this.maskSensitiveData(matchedText)}`, `Move sensitive data to environment variables or secure configuration management. Use process.env.VARIABLE_NAME or a secrets management service.`));
64
+ }
65
+ }
66
+ return issues;
67
+ }
68
+ isSensitiveFile(filePath) {
69
+ const sensitiveFiles = [
70
+ /\.env/i,
71
+ /\.config/i,
72
+ /\.conf/i,
73
+ /\.ini/i,
74
+ /\.properties/i,
75
+ /\.yaml/i,
76
+ /\.yml/i,
77
+ /\.json/i,
78
+ /\.toml/i,
79
+ /config\./i,
80
+ /settings\./i,
81
+ /constants\./i,
82
+ /\.js$/i,
83
+ /\.ts$/i,
84
+ /\.py$/i,
85
+ /\.php$/i,
86
+ /\.rb$/i
87
+ ];
88
+ return sensitiveFiles.some(pattern => pattern.test(filePath));
89
+ }
90
+ isFalsePositive(text) {
91
+ return this.falsePositivePatterns.some(pattern => pattern.test(text));
92
+ }
93
+ maskSensitiveData(data) {
94
+ if (data.length <= 8) {
95
+ return '*'.repeat(data.length);
96
+ }
97
+ const start = data.substring(0, 4);
98
+ const end = data.substring(data.length - 4);
99
+ const middle = '*'.repeat(Math.min(data.length - 8, 10));
100
+ return `${start}${middle}${end}`;
101
+ }
102
+ }
103
+ exports.HardcodedSensitiveDataRule = HardcodedSensitiveDataRule;
104
+ //# sourceMappingURL=hardcoded-sensitive-data.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hardcoded-sensitive-data.js","sourceRoot":"","sources":["../../src/rules/hardcoded-sensitive-data.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { BaseRule } from '../types';
2
+ import { ExposedSecretsRule } from './exposed-secrets';
3
+ import { MissingAuthenticationRule } from './missing-authentication';
4
+ import { OpenCorsRule } from './open-cors';
5
+ import { HardcodedSensitiveDataRule } from './hardcoded-sensitive-data';
6
+ import { InsecureHttpRule } from './insecure-http';
7
+ import { SqlInjectionRule } from './sql-injection';
8
+ import { UnvalidatedInputRule } from './unvalidated-input';
9
+ import { DirectoryTraversalRule } from './directory-traversal';
10
+ import { InsecureDependenciesRule } from './insecure-dependencies';
11
+ import { MissingSecurityHeadersRule } from './missing-security-headers';
12
+ export declare function getAllRules(): BaseRule[];
13
+ export { ExposedSecretsRule, MissingAuthenticationRule, OpenCorsRule, HardcodedSensitiveDataRule, InsecureHttpRule, SqlInjectionRule, UnvalidatedInputRule, DirectoryTraversalRule, InsecureDependenciesRule, MissingSecurityHeadersRule, };
14
+ export * from '../types';
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rules/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAExE,wBAAgB,WAAW,IAAI,QAAQ,EAAE,CAaxC;AAED,OAAO,EACL,kBAAkB,EAClB,yBAAyB,EACzB,YAAY,EACZ,0BAA0B,EAC1B,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,EACpB,sBAAsB,EACtB,wBAAwB,EACxB,0BAA0B,GAE3B,CAAC;AAEF,cAAc,UAAU,CAAC"}
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.MissingSecurityHeadersRule = exports.InsecureDependenciesRule = exports.DirectoryTraversalRule = exports.UnvalidatedInputRule = exports.SqlInjectionRule = exports.InsecureHttpRule = exports.HardcodedSensitiveDataRule = exports.OpenCorsRule = exports.MissingAuthenticationRule = exports.ExposedSecretsRule = void 0;
18
+ exports.getAllRules = getAllRules;
19
+ const exposed_secrets_1 = require("./exposed-secrets");
20
+ Object.defineProperty(exports, "ExposedSecretsRule", { enumerable: true, get: function () { return exposed_secrets_1.ExposedSecretsRule; } });
21
+ const missing_authentication_1 = require("./missing-authentication");
22
+ Object.defineProperty(exports, "MissingAuthenticationRule", { enumerable: true, get: function () { return missing_authentication_1.MissingAuthenticationRule; } });
23
+ const open_cors_1 = require("./open-cors");
24
+ Object.defineProperty(exports, "OpenCorsRule", { enumerable: true, get: function () { return open_cors_1.OpenCorsRule; } });
25
+ const hardcoded_sensitive_data_1 = require("./hardcoded-sensitive-data");
26
+ Object.defineProperty(exports, "HardcodedSensitiveDataRule", { enumerable: true, get: function () { return hardcoded_sensitive_data_1.HardcodedSensitiveDataRule; } });
27
+ const insecure_http_1 = require("./insecure-http");
28
+ Object.defineProperty(exports, "InsecureHttpRule", { enumerable: true, get: function () { return insecure_http_1.InsecureHttpRule; } });
29
+ const sql_injection_1 = require("./sql-injection");
30
+ Object.defineProperty(exports, "SqlInjectionRule", { enumerable: true, get: function () { return sql_injection_1.SqlInjectionRule; } });
31
+ const unvalidated_input_1 = require("./unvalidated-input");
32
+ Object.defineProperty(exports, "UnvalidatedInputRule", { enumerable: true, get: function () { return unvalidated_input_1.UnvalidatedInputRule; } });
33
+ const directory_traversal_1 = require("./directory-traversal");
34
+ Object.defineProperty(exports, "DirectoryTraversalRule", { enumerable: true, get: function () { return directory_traversal_1.DirectoryTraversalRule; } });
35
+ const insecure_dependencies_1 = require("./insecure-dependencies");
36
+ Object.defineProperty(exports, "InsecureDependenciesRule", { enumerable: true, get: function () { return insecure_dependencies_1.InsecureDependenciesRule; } });
37
+ const missing_security_headers_1 = require("./missing-security-headers");
38
+ Object.defineProperty(exports, "MissingSecurityHeadersRule", { enumerable: true, get: function () { return missing_security_headers_1.MissingSecurityHeadersRule; } });
39
+ function getAllRules() {
40
+ return [
41
+ new exposed_secrets_1.ExposedSecretsRule(),
42
+ new missing_authentication_1.MissingAuthenticationRule(),
43
+ new open_cors_1.OpenCorsRule(),
44
+ new hardcoded_sensitive_data_1.HardcodedSensitiveDataRule(),
45
+ new insecure_http_1.InsecureHttpRule(),
46
+ new sql_injection_1.SqlInjectionRule(),
47
+ new unvalidated_input_1.UnvalidatedInputRule(),
48
+ new directory_traversal_1.DirectoryTraversalRule(),
49
+ new insecure_dependencies_1.InsecureDependenciesRule(),
50
+ new missing_security_headers_1.MissingSecurityHeadersRule(),
51
+ ];
52
+ }
53
+ __exportStar(require("../types"), exports);
54
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rules/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAYA,kCAaC;AAxBD,uDAAuD;AA2BrD,mGA3BO,oCAAkB,OA2BP;AA1BpB,qEAAqE;AA2BnE,0GA3BO,kDAAyB,OA2BP;AA1B3B,2CAA2C;AA2BzC,6FA3BO,wBAAY,OA2BP;AA1Bd,yEAAwE;AA2BtE,2GA3BO,qDAA0B,OA2BP;AA1B5B,mDAAmD;AA2BjD,iGA3BO,gCAAgB,OA2BP;AA1BlB,mDAAmD;AA2BjD,iGA3BO,gCAAgB,OA2BP;AA1BlB,2DAA2D;AA2BzD,qGA3BO,wCAAoB,OA2BP;AA1BtB,+DAA+D;AA2B7D,uGA3BO,4CAAsB,OA2BP;AA1BxB,mEAAmE;AA2BjE,yGA3BO,gDAAwB,OA2BP;AA1B1B,yEAAwE;AA2BtE,2GA3BO,qDAA0B,OA2BP;AAzB5B,SAAgB,WAAW;IACzB,OAAO;QACL,IAAI,oCAAkB,EAAE;QACxB,IAAI,kDAAyB,EAAE;QAC/B,IAAI,wBAAY,EAAE;QAClB,IAAI,qDAA0B,EAAE;QAChC,IAAI,gCAAgB,EAAE;QACtB,IAAI,gCAAgB,EAAE;QACtB,IAAI,wCAAoB,EAAE;QAC1B,IAAI,4CAAsB,EAAE;QAC5B,IAAI,gDAAwB,EAAE;QAC9B,IAAI,qDAA0B,EAAE;KACjC,CAAC;AACJ,CAAC;AAgBD,2CAAyB"}
@@ -0,0 +1,16 @@
1
+ import { BaseRule, FileContent, SecurityIssue } from '../types';
2
+ export declare class InsecureDependenciesRule extends BaseRule {
3
+ readonly name = "insecure-dependencies";
4
+ readonly description = "Detects potentially insecure dependencies and packages";
5
+ readonly severity: "medium";
6
+ private readonly vulnerablePackages;
7
+ private readonly suspiciousPatterns;
8
+ check(fileContent: FileContent): SecurityIssue[];
9
+ private isDependencyFile;
10
+ private checkVulnerablePackages;
11
+ private checkSuspiciousPatterns;
12
+ private isVulnerableVersion;
13
+ private compareVersions;
14
+ private isInDevDependencies;
15
+ }
16
+ //# sourceMappingURL=insecure-dependencies.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"insecure-dependencies.d.ts","sourceRoot":"","sources":["../../src/rules/insecure-dependencies.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEhE,qBAAa,wBAAyB,SAAQ,QAAQ;IACpD,QAAQ,CAAC,IAAI,2BAA2B;IACxC,QAAQ,CAAC,WAAW,4DAA4D;IAChF,QAAQ,CAAC,QAAQ,EAAG,QAAQ,CAAU;IAEtC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAwBjC;IAEF,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAajC;IAEF,KAAK,CAAC,WAAW,EAAE,WAAW,GAAG,aAAa,EAAE;IAiBhD,OAAO,CAAC,gBAAgB;IAgBxB,OAAO,CAAC,uBAAuB;IAsB/B,OAAO,CAAC,uBAAuB;IAsB/B,OAAO,CAAC,mBAAmB;IAuB3B,OAAO,CAAC,eAAe;IAgBvB,OAAO,CAAC,mBAAmB;CA0B5B"}