midas-mcp 5.43.5 → 5.43.11
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/analyzer.d.ts +19 -0
- package/dist/analyzer.d.ts.map +1 -1
- package/dist/analyzer.js +95 -1
- package/dist/analyzer.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +5 -1
- package/dist/server.js.map +1 -1
- package/dist/state/phase.d.ts +8 -3
- package/dist/state/phase.d.ts.map +1 -1
- package/dist/state/phase.js +85 -7
- package/dist/state/phase.js.map +1 -1
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +2 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/vuln-scan.d.ts +74 -0
- package/dist/tools/vuln-scan.d.ts.map +1 -0
- package/dist/tools/vuln-scan.js +493 -0
- package/dist/tools/vuln-scan.js.map +1 -0
- package/dist/tracker.d.ts +22 -0
- package/dist/tracker.d.ts.map +1 -1
- package/dist/tracker.js +93 -16
- package/dist/tracker.js.map +1 -1
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +44 -32
- package/dist/tui.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/index.js
CHANGED
|
@@ -42,4 +42,6 @@ realityCheck, realityCheckSchema, realityUpdate, realityUpdateSchema, } from './
|
|
|
42
42
|
export { analyzeGameplanTool, analyzeGameplanSchema, getGameplanProgressTool, getProgressSchema, } from './gameplan.js';
|
|
43
43
|
// Code complexity analysis and simplification
|
|
44
44
|
export { analyzeComplexity, complexitySchema, analyzeSimplify, simplifySchema, } from './complexity.js';
|
|
45
|
+
// Vulnerability scanning
|
|
46
|
+
export { vulnScan, vulnScanSchema, vulnScanWithRegistry, } from './vuln-scan.js';
|
|
45
47
|
//# sourceMappingURL=index.js.map
|
package/dist/tools/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vulnerability Scanner
|
|
3
|
+
*
|
|
4
|
+
* Detects the top 5 reliably-detectable security anti-patterns:
|
|
5
|
+
* 1. Hardcoded secrets (API keys, tokens, passwords)
|
|
6
|
+
* 2. SQL injection (string concatenation in queries)
|
|
7
|
+
* 3. Command injection (exec/spawn with user input)
|
|
8
|
+
* 4. XSS vulnerabilities (innerHTML, dangerouslySetInnerHTML)
|
|
9
|
+
* 5. Slopsquatting (AI-hallucinated package names that don't exist)
|
|
10
|
+
*
|
|
11
|
+
* Based on Sec-Context research: https://arcanum-sec.github.io/sec-context/
|
|
12
|
+
*/
|
|
13
|
+
import { z } from 'zod';
|
|
14
|
+
export declare const vulnScanSchema: z.ZodObject<{
|
|
15
|
+
projectPath: z.ZodOptional<z.ZodString>;
|
|
16
|
+
checkRegistry: z.ZodOptional<z.ZodBoolean>;
|
|
17
|
+
severity: z.ZodOptional<z.ZodEnum<["all", "critical", "high", "medium"]>>;
|
|
18
|
+
excludeTests: z.ZodOptional<z.ZodBoolean>;
|
|
19
|
+
excludePatterns: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
20
|
+
}, "strip", z.ZodTypeAny, {
|
|
21
|
+
projectPath?: string | undefined;
|
|
22
|
+
severity?: "critical" | "high" | "medium" | "all" | undefined;
|
|
23
|
+
checkRegistry?: boolean | undefined;
|
|
24
|
+
excludeTests?: boolean | undefined;
|
|
25
|
+
excludePatterns?: string[] | undefined;
|
|
26
|
+
}, {
|
|
27
|
+
projectPath?: string | undefined;
|
|
28
|
+
severity?: "critical" | "high" | "medium" | "all" | undefined;
|
|
29
|
+
checkRegistry?: boolean | undefined;
|
|
30
|
+
excludeTests?: boolean | undefined;
|
|
31
|
+
excludePatterns?: string[] | undefined;
|
|
32
|
+
}>;
|
|
33
|
+
export type VulnScanInput = z.infer<typeof vulnScanSchema>;
|
|
34
|
+
export type VulnSeverity = 'critical' | 'high' | 'medium' | 'low';
|
|
35
|
+
export type VulnType = 'hardcoded-secret' | 'sql-injection' | 'command-injection' | 'xss' | 'slopsquatting';
|
|
36
|
+
export interface Vulnerability {
|
|
37
|
+
type: VulnType;
|
|
38
|
+
severity: VulnSeverity;
|
|
39
|
+
file: string;
|
|
40
|
+
line: number;
|
|
41
|
+
code: string;
|
|
42
|
+
description: string;
|
|
43
|
+
recommendation: string;
|
|
44
|
+
}
|
|
45
|
+
export interface SlopsquattingResult {
|
|
46
|
+
package: string;
|
|
47
|
+
exists: boolean;
|
|
48
|
+
similarTo?: string;
|
|
49
|
+
error?: string;
|
|
50
|
+
}
|
|
51
|
+
export interface VulnScanReport {
|
|
52
|
+
summary: {
|
|
53
|
+
filesScanned: number;
|
|
54
|
+
vulnerabilitiesFound: number;
|
|
55
|
+
critical: number;
|
|
56
|
+
high: number;
|
|
57
|
+
medium: number;
|
|
58
|
+
low: number;
|
|
59
|
+
};
|
|
60
|
+
vulnerabilities: Vulnerability[];
|
|
61
|
+
slopsquatting: SlopsquattingResult[];
|
|
62
|
+
suggestedPrompt: string;
|
|
63
|
+
}
|
|
64
|
+
export declare function vulnScan(input: VulnScanInput): VulnScanReport;
|
|
65
|
+
/**
|
|
66
|
+
* Check if packages exist on npm registry
|
|
67
|
+
* This requires network access and should be used with checkRegistry: true
|
|
68
|
+
*/
|
|
69
|
+
export declare function checkNpmRegistry(packages: string[]): Promise<SlopsquattingResult[]>;
|
|
70
|
+
/**
|
|
71
|
+
* Enhanced scan with npm registry verification
|
|
72
|
+
*/
|
|
73
|
+
export declare function vulnScanWithRegistry(input: VulnScanInput): Promise<VulnScanReport>;
|
|
74
|
+
//# sourceMappingURL=vuln-scan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vuln-scan.d.ts","sourceRoot":"","sources":["../../src/tools/vuln-scan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAUxB,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;EAMzB,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AA6B3D,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAClE,MAAM,MAAM,QAAQ,GAAG,kBAAkB,GAAG,eAAe,GAAG,mBAAmB,GAAG,KAAK,GAAG,eAAe,CAAC;AAE5G,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,EAAE,YAAY,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE;QACP,YAAY,EAAE,MAAM,CAAC;QACrB,oBAAoB,EAAE,MAAM,CAAC;QAC7B,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;IACF,eAAe,EAAE,aAAa,EAAE,CAAC;IACjC,aAAa,EAAE,mBAAmB,EAAE,CAAC;IACrC,eAAe,EAAE,MAAM,CAAC;CACzB;AAgFD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,cAAc,CA6I7D;AA8MD;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC,CA6BzF;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC,CAmCxF"}
|
|
@@ -0,0 +1,493 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vulnerability Scanner
|
|
3
|
+
*
|
|
4
|
+
* Detects the top 5 reliably-detectable security anti-patterns:
|
|
5
|
+
* 1. Hardcoded secrets (API keys, tokens, passwords)
|
|
6
|
+
* 2. SQL injection (string concatenation in queries)
|
|
7
|
+
* 3. Command injection (exec/spawn with user input)
|
|
8
|
+
* 4. XSS vulnerabilities (innerHTML, dangerouslySetInnerHTML)
|
|
9
|
+
* 5. Slopsquatting (AI-hallucinated package names that don't exist)
|
|
10
|
+
*
|
|
11
|
+
* Based on Sec-Context research: https://arcanum-sec.github.io/sec-context/
|
|
12
|
+
*/
|
|
13
|
+
import { z } from 'zod';
|
|
14
|
+
import { existsSync, readFileSync, readdirSync } from 'fs';
|
|
15
|
+
import { join, relative, extname } from 'path';
|
|
16
|
+
import { sanitizePath } from '../security.js';
|
|
17
|
+
import { logger } from '../logger.js';
|
|
18
|
+
// ============================================================================
|
|
19
|
+
// SCHEMAS
|
|
20
|
+
// ============================================================================
|
|
21
|
+
export const vulnScanSchema = z.object({
|
|
22
|
+
projectPath: z.string().optional().describe('Path to project root'),
|
|
23
|
+
checkRegistry: z.boolean().optional().describe('Check npm registry for slopsquatting (requires network)'),
|
|
24
|
+
severity: z.enum(['all', 'critical', 'high', 'medium']).optional().describe('Minimum severity to report'),
|
|
25
|
+
excludeTests: z.boolean().optional().describe('Exclude test files (default: true)'),
|
|
26
|
+
excludePatterns: z.array(z.string()).optional().describe('Additional glob patterns to exclude'),
|
|
27
|
+
});
|
|
28
|
+
// ============================================================================
|
|
29
|
+
// EXCLUSION PATTERNS
|
|
30
|
+
// ============================================================================
|
|
31
|
+
// Default patterns to exclude from scanning
|
|
32
|
+
const DEFAULT_EXCLUDE_PATTERNS = [
|
|
33
|
+
// Scanner itself (self-referential detection is noise)
|
|
34
|
+
'vuln-scan.ts',
|
|
35
|
+
'vuln-scan.js',
|
|
36
|
+
];
|
|
37
|
+
// Test file patterns (excluded by default)
|
|
38
|
+
const TEST_FILE_PATTERNS = [
|
|
39
|
+
/\.test\.[jt]sx?$/,
|
|
40
|
+
/\.spec\.[jt]sx?$/,
|
|
41
|
+
/__tests__\//,
|
|
42
|
+
/\/test\//,
|
|
43
|
+
/\/tests\//,
|
|
44
|
+
];
|
|
45
|
+
// Inline ignore comment pattern: // midas-ignore or // midas-ignore: reason
|
|
46
|
+
const IGNORE_COMMENT_PATTERN = /\/\/\s*midas-ignore/;
|
|
47
|
+
// ============================================================================
|
|
48
|
+
// DETECTION PATTERNS
|
|
49
|
+
// ============================================================================
|
|
50
|
+
const SECRET_PATTERNS = [
|
|
51
|
+
// API Keys with common prefixes
|
|
52
|
+
{ pattern: /api[_-]?key\s*[:=]\s*['"][a-zA-Z0-9_\-]{20,}['"]/gi, name: 'API key', severity: 'critical' },
|
|
53
|
+
{ pattern: /secret[_-]?key\s*[:=]\s*['"][a-zA-Z0-9_\-]{20,}['"]/gi, name: 'Secret key', severity: 'critical' },
|
|
54
|
+
{ pattern: /auth[_-]?token\s*[:=]\s*['"][a-zA-Z0-9_\-]{20,}['"]/gi, name: 'Auth token', severity: 'critical' },
|
|
55
|
+
{ pattern: /access[_-]?token\s*[:=]\s*['"][a-zA-Z0-9_\-]{20,}['"]/gi, name: 'Access token', severity: 'critical' },
|
|
56
|
+
// Specific provider patterns - more flexible matching
|
|
57
|
+
{ pattern: /sk-[a-zA-Z0-9]{32,}/g, name: 'OpenAI API key', severity: 'critical' },
|
|
58
|
+
{ pattern: /ghp_[a-zA-Z0-9]{30,}/g, name: 'GitHub token', severity: 'critical' },
|
|
59
|
+
{ pattern: /gho_[a-zA-Z0-9]{30,}/g, name: 'GitHub OAuth token', severity: 'critical' },
|
|
60
|
+
{ pattern: /github_pat_[a-zA-Z0-9_]{20,}/g, name: 'GitHub PAT', severity: 'critical' },
|
|
61
|
+
{ pattern: /xoxb-[0-9]+-[a-zA-Z0-9]+/g, name: 'Slack bot token', severity: 'critical' },
|
|
62
|
+
{ pattern: /xoxp-[0-9]+-[a-zA-Z0-9]+/g, name: 'Slack user token', severity: 'critical' },
|
|
63
|
+
{ pattern: /AKIA[0-9A-Z]{12,}/g, name: 'AWS access key', severity: 'critical' },
|
|
64
|
+
{ pattern: /-----BEGIN (?:RSA |EC |DSA )?PRIVATE KEY-----/g, name: 'Private key', severity: 'critical' },
|
|
65
|
+
{ pattern: /-----BEGIN OPENSSH PRIVATE KEY-----/g, name: 'SSH private key', severity: 'critical' },
|
|
66
|
+
// Database passwords
|
|
67
|
+
{ pattern: /(?:password|passwd|pwd)\s*[:=]\s*['"][^'"]{8,}['"]/gi, name: 'Hardcoded password', severity: 'high' },
|
|
68
|
+
{ pattern: /(?:mongodb|postgres|mysql):\/\/[^:]+:[^@]+@/gi, name: 'Database connection with password', severity: 'high' },
|
|
69
|
+
// JWT secrets
|
|
70
|
+
{ pattern: /jwt[_-]?secret\s*[:=]\s*['"][^'"]{16,}['"]/gi, name: 'JWT secret', severity: 'critical' },
|
|
71
|
+
];
|
|
72
|
+
const SQL_INJECTION_PATTERNS = [
|
|
73
|
+
// String concatenation in queries - more flexible
|
|
74
|
+
{ pattern: /['"`]SELECT[^'"]*['"]\s*\+\s*(?:req\.|params)/gi, description: 'SQL query with request parameter concatenation' },
|
|
75
|
+
{ pattern: /query\s*\([^)]*\+\s*req\./gi, description: 'SQL query with request parameter' },
|
|
76
|
+
{ pattern: /query\s*\(\s*`[^`]*\$\{[^}]*req\./gi, description: 'SQL query with template literal injection' },
|
|
77
|
+
{ pattern: /execute\s*\(\s*['"`].*\+\s*(?:req\.|params\.|query\.)/gi, description: 'SQL execute with parameter concatenation' },
|
|
78
|
+
{ pattern: /\$queryRaw\s*`[^`]*\$\{/gi, description: 'Prisma raw query with interpolation' },
|
|
79
|
+
{ pattern: /\.raw\s*\(\s*`[^`]*\$\{/gi, description: 'ORM raw query with interpolation' },
|
|
80
|
+
// Dynamic table/column names
|
|
81
|
+
{ pattern: /query\s*\(\s*['"`]SELECT.*FROM\s*['"`]\s*\+/gi, description: 'Dynamic table name in query' },
|
|
82
|
+
];
|
|
83
|
+
const COMMAND_INJECTION_PATTERNS = [
|
|
84
|
+
// exec with user input
|
|
85
|
+
{ pattern: /exec\s*\(\s*['"`].*\+\s*(?:req\.|params\.|query\.|input|user)/gi, description: 'exec() with user input concatenation' },
|
|
86
|
+
{ pattern: /exec\s*\(\s*`[^`]*\$\{(?:req\.|params\.|query\.|input|user)/gi, description: 'exec() with template literal injection' },
|
|
87
|
+
{ pattern: /execSync\s*\(\s*['"`].*\+\s*(?:req\.|params\.|query\.|input|user)/gi, description: 'execSync() with user input' },
|
|
88
|
+
{ pattern: /execSync\s*\(\s*`[^`]*\$\{(?:req\.|params\.|query\.|input|user)/gi, description: 'execSync() with template literal' },
|
|
89
|
+
// spawn with shell
|
|
90
|
+
{ pattern: /spawn\s*\(\s*['"](?:sh|bash|cmd)['"]/gi, description: 'spawn() with shell - potential injection vector' },
|
|
91
|
+
{ pattern: /spawn\s*\([^)]*shell:\s*true/gi, description: 'spawn() with shell: true' },
|
|
92
|
+
// child_process with user input
|
|
93
|
+
{ pattern: /child_process.*\+\s*(?:req\.|params\.|query\.|input|user)/gi, description: 'child_process with user input' },
|
|
94
|
+
];
|
|
95
|
+
const XSS_PATTERNS = [
|
|
96
|
+
// React
|
|
97
|
+
{ pattern: /dangerouslySetInnerHTML\s*=\s*\{\s*\{\s*__html:/g, description: 'React dangerouslySetInnerHTML - XSS risk', severity: 'high' },
|
|
98
|
+
// Vanilla JS
|
|
99
|
+
{ pattern: /\.innerHTML\s*=\s*(?!['"`]<)/g, description: 'innerHTML assignment with dynamic content', severity: 'high' },
|
|
100
|
+
{ pattern: /\.outerHTML\s*=\s*(?!['"`]<)/g, description: 'outerHTML assignment with dynamic content', severity: 'high' },
|
|
101
|
+
// Vue
|
|
102
|
+
{ pattern: /v-html\s*=/g, description: 'Vue v-html directive - XSS risk', severity: 'medium' },
|
|
103
|
+
// jQuery
|
|
104
|
+
{ pattern: /\$\([^)]+\)\.html\s*\([^)]*(?:req\.|params\.|query\.|input|user)/gi, description: 'jQuery .html() with user input', severity: 'high' },
|
|
105
|
+
// document.write
|
|
106
|
+
{ pattern: /document\.write\s*\(/g, description: 'document.write() - XSS and performance issues', severity: 'medium' },
|
|
107
|
+
// eval
|
|
108
|
+
{ pattern: /eval\s*\(\s*(?:req\.|params\.|query\.|input|user)/gi, description: 'eval() with user input - critical XSS/RCE', severity: 'critical' },
|
|
109
|
+
];
|
|
110
|
+
const IGNORE_DIRS = ['node_modules', '.git', 'dist', 'build', '.midas', 'coverage', '.next', '__pycache__', 'vendor'];
|
|
111
|
+
const CODE_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs', '.py', '.rb', '.php', '.go', '.java'];
|
|
112
|
+
// ============================================================================
|
|
113
|
+
// MAIN SCAN FUNCTION
|
|
114
|
+
// ============================================================================
|
|
115
|
+
export function vulnScan(input) {
|
|
116
|
+
const projectPath = sanitizePath(input.projectPath);
|
|
117
|
+
const minSeverity = input.severity || 'all';
|
|
118
|
+
const excludeTests = input.excludeTests !== false; // Default: true
|
|
119
|
+
const userExcludePatterns = input.excludePatterns || [];
|
|
120
|
+
const vulnerabilities = [];
|
|
121
|
+
const slopsquatting = [];
|
|
122
|
+
let filesScanned = 0;
|
|
123
|
+
// Check if a file should be excluded
|
|
124
|
+
function shouldExclude(filePath, relativePath) {
|
|
125
|
+
// Check default exclusions (scanner itself)
|
|
126
|
+
for (const pattern of DEFAULT_EXCLUDE_PATTERNS) {
|
|
127
|
+
if (relativePath.includes(pattern)) {
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// Check test file exclusions
|
|
132
|
+
if (excludeTests) {
|
|
133
|
+
for (const pattern of TEST_FILE_PATTERNS) {
|
|
134
|
+
if (pattern.test(relativePath)) {
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
// Check user-specified exclusions
|
|
140
|
+
for (const pattern of userExcludePatterns) {
|
|
141
|
+
if (relativePath.includes(pattern)) {
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
// Scan all code files
|
|
148
|
+
function scanDir(dir, depth = 0) {
|
|
149
|
+
if (depth > 10)
|
|
150
|
+
return;
|
|
151
|
+
try {
|
|
152
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
153
|
+
for (const entry of entries) {
|
|
154
|
+
if (IGNORE_DIRS.includes(entry.name) || entry.name.startsWith('.'))
|
|
155
|
+
continue;
|
|
156
|
+
const fullPath = join(dir, entry.name);
|
|
157
|
+
const relativePath = relative(projectPath, fullPath);
|
|
158
|
+
if (entry.isDirectory()) {
|
|
159
|
+
scanDir(fullPath, depth + 1);
|
|
160
|
+
}
|
|
161
|
+
else if (entry.isFile()) {
|
|
162
|
+
const ext = extname(entry.name);
|
|
163
|
+
if (CODE_EXTENSIONS.includes(ext)) {
|
|
164
|
+
// Check exclusions
|
|
165
|
+
if (shouldExclude(fullPath, relativePath)) {
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
const fileVulns = scanFile(fullPath, projectPath);
|
|
169
|
+
vulnerabilities.push(...fileVulns);
|
|
170
|
+
filesScanned++;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
catch (error) {
|
|
176
|
+
logger.debug('Error scanning directory', { dir, error: String(error) });
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
scanDir(projectPath);
|
|
180
|
+
// Check package.json for slopsquatting (sync, no network by default)
|
|
181
|
+
const pkgPath = join(projectPath, 'package.json');
|
|
182
|
+
if (existsSync(pkgPath)) {
|
|
183
|
+
try {
|
|
184
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
|
|
185
|
+
const allDeps = {
|
|
186
|
+
...pkg.dependencies,
|
|
187
|
+
...pkg.devDependencies,
|
|
188
|
+
};
|
|
189
|
+
// Check for suspicious package names (typosquatting indicators)
|
|
190
|
+
for (const [name] of Object.entries(allDeps)) {
|
|
191
|
+
const suspicious = checkSuspiciousPackage(name);
|
|
192
|
+
if (suspicious) {
|
|
193
|
+
slopsquatting.push(suspicious);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
catch (error) {
|
|
198
|
+
logger.debug('Error reading package.json', { error: String(error) });
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
// Filter by severity
|
|
202
|
+
const severityOrder = { critical: 0, high: 1, medium: 2, low: 3 };
|
|
203
|
+
const minSeverityLevel = minSeverity === 'all' ? 3 : severityOrder[minSeverity];
|
|
204
|
+
const filteredVulns = vulnerabilities.filter(v => severityOrder[v.severity] <= minSeverityLevel);
|
|
205
|
+
// Sort by severity
|
|
206
|
+
filteredVulns.sort((a, b) => severityOrder[a.severity] - severityOrder[b.severity]);
|
|
207
|
+
// Count by severity
|
|
208
|
+
const critical = filteredVulns.filter(v => v.severity === 'critical').length;
|
|
209
|
+
const high = filteredVulns.filter(v => v.severity === 'high').length;
|
|
210
|
+
const medium = filteredVulns.filter(v => v.severity === 'medium').length;
|
|
211
|
+
const low = filteredVulns.filter(v => v.severity === 'low').length;
|
|
212
|
+
// Generate suggested prompt
|
|
213
|
+
let suggestedPrompt = 'No security vulnerabilities detected. Codebase looks secure!';
|
|
214
|
+
if (critical > 0) {
|
|
215
|
+
const topCritical = filteredVulns.find(v => v.severity === 'critical');
|
|
216
|
+
if (topCritical) {
|
|
217
|
+
suggestedPrompt = `CRITICAL: Fix ${topCritical.type} in ${topCritical.file}:${topCritical.line}. ${topCritical.recommendation}`;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
else if (high > 0) {
|
|
221
|
+
const topHigh = filteredVulns.find(v => v.severity === 'high');
|
|
222
|
+
if (topHigh) {
|
|
223
|
+
suggestedPrompt = `Fix ${topHigh.type} in ${topHigh.file}:${topHigh.line}. ${topHigh.recommendation}`;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
else if (slopsquatting.length > 0) {
|
|
227
|
+
const sus = slopsquatting[0];
|
|
228
|
+
suggestedPrompt = `Verify package "${sus.package}" exists on npm. ${sus.similarTo ? `Did you mean "${sus.similarTo}"?` : 'May be AI-hallucinated.'}`;
|
|
229
|
+
}
|
|
230
|
+
return {
|
|
231
|
+
summary: {
|
|
232
|
+
filesScanned,
|
|
233
|
+
vulnerabilitiesFound: filteredVulns.length,
|
|
234
|
+
critical,
|
|
235
|
+
high,
|
|
236
|
+
medium,
|
|
237
|
+
low,
|
|
238
|
+
},
|
|
239
|
+
vulnerabilities: filteredVulns.slice(0, 50), // Limit output
|
|
240
|
+
slopsquatting,
|
|
241
|
+
suggestedPrompt,
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
// ============================================================================
|
|
245
|
+
// FILE SCANNING
|
|
246
|
+
// ============================================================================
|
|
247
|
+
function scanFile(filePath, projectPath) {
|
|
248
|
+
const vulnerabilities = [];
|
|
249
|
+
try {
|
|
250
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
251
|
+
const lines = content.split('\n');
|
|
252
|
+
const relativePath = relative(projectPath, filePath);
|
|
253
|
+
// Helper to check if a line has midas-ignore comment (same line or previous line)
|
|
254
|
+
function hasIgnoreComment(lineNum) {
|
|
255
|
+
const line = lines[lineNum - 1] || '';
|
|
256
|
+
const prevLine = lines[lineNum - 2] || '';
|
|
257
|
+
return IGNORE_COMMENT_PATTERN.test(line) || IGNORE_COMMENT_PATTERN.test(prevLine);
|
|
258
|
+
}
|
|
259
|
+
// Check for hardcoded secrets
|
|
260
|
+
for (const { pattern, name, severity } of SECRET_PATTERNS) {
|
|
261
|
+
let match;
|
|
262
|
+
while ((match = pattern.exec(content)) !== null) {
|
|
263
|
+
const lineNum = content.slice(0, match.index).split('\n').length;
|
|
264
|
+
const line = lines[lineNum - 1] || '';
|
|
265
|
+
// Skip if it's clearly a placeholder or example
|
|
266
|
+
if (isPlaceholder(match[0]))
|
|
267
|
+
continue;
|
|
268
|
+
// Skip if line has midas-ignore comment
|
|
269
|
+
if (hasIgnoreComment(lineNum))
|
|
270
|
+
continue;
|
|
271
|
+
vulnerabilities.push({
|
|
272
|
+
type: 'hardcoded-secret',
|
|
273
|
+
severity,
|
|
274
|
+
file: relativePath,
|
|
275
|
+
line: lineNum,
|
|
276
|
+
code: truncateLine(line),
|
|
277
|
+
description: `${name} detected in source code`,
|
|
278
|
+
recommendation: 'Move to environment variable or secrets manager. Never commit secrets to version control.',
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
// Check for SQL injection
|
|
283
|
+
for (const { pattern, description } of SQL_INJECTION_PATTERNS) {
|
|
284
|
+
let match;
|
|
285
|
+
while ((match = pattern.exec(content)) !== null) {
|
|
286
|
+
const lineNum = content.slice(0, match.index).split('\n').length;
|
|
287
|
+
const line = lines[lineNum - 1] || '';
|
|
288
|
+
// Skip if line has midas-ignore comment
|
|
289
|
+
if (hasIgnoreComment(lineNum))
|
|
290
|
+
continue;
|
|
291
|
+
vulnerabilities.push({
|
|
292
|
+
type: 'sql-injection',
|
|
293
|
+
severity: 'high',
|
|
294
|
+
file: relativePath,
|
|
295
|
+
line: lineNum,
|
|
296
|
+
code: truncateLine(line),
|
|
297
|
+
description,
|
|
298
|
+
recommendation: 'Use parameterized queries or prepared statements. Never concatenate user input into SQL.',
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
// Check for command injection
|
|
303
|
+
for (const { pattern, description } of COMMAND_INJECTION_PATTERNS) {
|
|
304
|
+
let match;
|
|
305
|
+
while ((match = pattern.exec(content)) !== null) {
|
|
306
|
+
const lineNum = content.slice(0, match.index).split('\n').length;
|
|
307
|
+
const line = lines[lineNum - 1] || '';
|
|
308
|
+
// Skip if line has midas-ignore comment
|
|
309
|
+
if (hasIgnoreComment(lineNum))
|
|
310
|
+
continue;
|
|
311
|
+
vulnerabilities.push({
|
|
312
|
+
type: 'command-injection',
|
|
313
|
+
severity: 'critical',
|
|
314
|
+
file: relativePath,
|
|
315
|
+
line: lineNum,
|
|
316
|
+
code: truncateLine(line),
|
|
317
|
+
description,
|
|
318
|
+
recommendation: 'Avoid shell commands with user input. Use execFile() with explicit arguments, or sanitize/validate input strictly.',
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
// Check for XSS
|
|
323
|
+
for (const { pattern, description, severity } of XSS_PATTERNS) {
|
|
324
|
+
let match;
|
|
325
|
+
while ((match = pattern.exec(content)) !== null) {
|
|
326
|
+
const lineNum = content.slice(0, match.index).split('\n').length;
|
|
327
|
+
const line = lines[lineNum - 1] || '';
|
|
328
|
+
// Skip if line has midas-ignore comment
|
|
329
|
+
if (hasIgnoreComment(lineNum))
|
|
330
|
+
continue;
|
|
331
|
+
vulnerabilities.push({
|
|
332
|
+
type: 'xss',
|
|
333
|
+
severity,
|
|
334
|
+
file: relativePath,
|
|
335
|
+
line: lineNum,
|
|
336
|
+
code: truncateLine(line),
|
|
337
|
+
description,
|
|
338
|
+
recommendation: 'Sanitize HTML content with DOMPurify or similar. Prefer textContent over innerHTML when possible.',
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
catch (error) {
|
|
344
|
+
logger.debug('Error scanning file', { filePath, error: String(error) });
|
|
345
|
+
}
|
|
346
|
+
return vulnerabilities;
|
|
347
|
+
}
|
|
348
|
+
// ============================================================================
|
|
349
|
+
// HELPER FUNCTIONS
|
|
350
|
+
// ============================================================================
|
|
351
|
+
/**
|
|
352
|
+
* Check if a string looks like a placeholder rather than a real secret
|
|
353
|
+
*/
|
|
354
|
+
function isPlaceholder(value) {
|
|
355
|
+
const placeholderPatterns = [
|
|
356
|
+
/your[_-]?api[_-]?key/i,
|
|
357
|
+
/xxx+/i,
|
|
358
|
+
/placeholder/i,
|
|
359
|
+
/example/i,
|
|
360
|
+
/test[_-]?key/i,
|
|
361
|
+
/dummy/i,
|
|
362
|
+
/fake/i,
|
|
363
|
+
/\<[^>]+\>/, // <your-key-here>
|
|
364
|
+
/\[.*\]/, // [API_KEY]
|
|
365
|
+
/\{.*\}/, // {api_key}
|
|
366
|
+
/^sk-[x]+$/i, // sk-xxxx...
|
|
367
|
+
];
|
|
368
|
+
return placeholderPatterns.some(p => p.test(value));
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Truncate line for display
|
|
372
|
+
*/
|
|
373
|
+
function truncateLine(line, maxLen = 100) {
|
|
374
|
+
const trimmed = line.trim();
|
|
375
|
+
if (trimmed.length <= maxLen)
|
|
376
|
+
return trimmed;
|
|
377
|
+
return trimmed.slice(0, maxLen - 3) + '...';
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Check if a package name looks suspicious (potential typosquat/slopsquat)
|
|
381
|
+
*/
|
|
382
|
+
function checkSuspiciousPackage(name) {
|
|
383
|
+
// Common typosquatting targets and their typos
|
|
384
|
+
const knownPackages = {
|
|
385
|
+
'lodash': ['lodahs', 'lodasch', 'loadash', 'lodsh'],
|
|
386
|
+
'express': ['expresss', 'expres', 'exprss'],
|
|
387
|
+
'react': ['reacts', 'reactt', 'raect'],
|
|
388
|
+
'axios': ['axois', 'axio', 'axioss'],
|
|
389
|
+
'moment': ['momnet', 'momet', 'momen'],
|
|
390
|
+
'colors': ['colrs', 'colour', 'colorss'],
|
|
391
|
+
'chalk': ['challk', 'chalks', 'chak'],
|
|
392
|
+
'request': ['requst', 'requets', 'requet'],
|
|
393
|
+
'commander': ['comander', 'comanderr', 'commnder'],
|
|
394
|
+
'dotenv': ['dotenvv', 'dotnev', 'dotev'],
|
|
395
|
+
};
|
|
396
|
+
// Check if it's a known typo
|
|
397
|
+
for (const [correct, typos] of Object.entries(knownPackages)) {
|
|
398
|
+
if (typos.includes(name)) {
|
|
399
|
+
return {
|
|
400
|
+
package: name,
|
|
401
|
+
exists: false,
|
|
402
|
+
similarTo: correct,
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
// Check for suspicious patterns
|
|
407
|
+
const suspiciousPatterns = [
|
|
408
|
+
/^[a-z]+-[a-z]+-[a-z]+-[a-z]+$/, // Too many dashes (often AI-generated)
|
|
409
|
+
/^[a-z]{20,}$/, // Very long single word
|
|
410
|
+
/@[a-z]+\/[a-z]+-v\d+$/, // Fake scoped package with version
|
|
411
|
+
];
|
|
412
|
+
for (const pattern of suspiciousPatterns) {
|
|
413
|
+
if (pattern.test(name)) {
|
|
414
|
+
return {
|
|
415
|
+
package: name,
|
|
416
|
+
exists: false, // Unknown
|
|
417
|
+
error: 'Unusual package name pattern - verify it exists',
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
return null;
|
|
422
|
+
}
|
|
423
|
+
// ============================================================================
|
|
424
|
+
// ASYNC REGISTRY CHECK (for network-enabled scanning)
|
|
425
|
+
// ============================================================================
|
|
426
|
+
/**
|
|
427
|
+
* Check if packages exist on npm registry
|
|
428
|
+
* This requires network access and should be used with checkRegistry: true
|
|
429
|
+
*/
|
|
430
|
+
export async function checkNpmRegistry(packages) {
|
|
431
|
+
const results = [];
|
|
432
|
+
for (const pkg of packages.slice(0, 20)) { // Limit to 20 packages
|
|
433
|
+
try {
|
|
434
|
+
const response = await fetch(`https://registry.npmjs.org/${encodeURIComponent(pkg)}`, {
|
|
435
|
+
method: 'HEAD',
|
|
436
|
+
signal: AbortSignal.timeout(5000),
|
|
437
|
+
});
|
|
438
|
+
if (response.status === 404) {
|
|
439
|
+
results.push({
|
|
440
|
+
package: pkg,
|
|
441
|
+
exists: false,
|
|
442
|
+
error: 'Package does not exist on npm - may be AI-hallucinated',
|
|
443
|
+
});
|
|
444
|
+
}
|
|
445
|
+
else if (response.ok) {
|
|
446
|
+
// Package exists, no issue
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
catch (error) {
|
|
450
|
+
results.push({
|
|
451
|
+
package: pkg,
|
|
452
|
+
exists: false,
|
|
453
|
+
error: `Could not verify: ${String(error)}`,
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
return results;
|
|
458
|
+
}
|
|
459
|
+
/**
|
|
460
|
+
* Enhanced scan with npm registry verification
|
|
461
|
+
*/
|
|
462
|
+
export async function vulnScanWithRegistry(input) {
|
|
463
|
+
const basicReport = vulnScan(input);
|
|
464
|
+
if (!input.checkRegistry) {
|
|
465
|
+
return basicReport;
|
|
466
|
+
}
|
|
467
|
+
// Get all dependencies
|
|
468
|
+
const projectPath = sanitizePath(input.projectPath);
|
|
469
|
+
const pkgPath = join(projectPath, 'package.json');
|
|
470
|
+
if (existsSync(pkgPath)) {
|
|
471
|
+
try {
|
|
472
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
|
|
473
|
+
const allDeps = Object.keys({
|
|
474
|
+
...pkg.dependencies,
|
|
475
|
+
...pkg.devDependencies,
|
|
476
|
+
});
|
|
477
|
+
const registryResults = await checkNpmRegistry(allDeps);
|
|
478
|
+
basicReport.slopsquatting.push(...registryResults);
|
|
479
|
+
// Update suggested prompt if slopsquatting found
|
|
480
|
+
if (registryResults.length > 0 && basicReport.summary.critical === 0) {
|
|
481
|
+
const firstMissing = registryResults.find(r => !r.exists);
|
|
482
|
+
if (firstMissing) {
|
|
483
|
+
basicReport.suggestedPrompt = `Package "${firstMissing.package}" not found on npm. Remove or replace with correct package name.`;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
catch (error) {
|
|
488
|
+
logger.debug('Error checking npm registry', { error: String(error) });
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
return basicReport;
|
|
492
|
+
}
|
|
493
|
+
//# sourceMappingURL=vuln-scan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vuln-scan.js","sourceRoot":"","sources":["../../src/tools/vuln-scan.ts"],"names":[],"mappings":"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"}
|