vettcode-cli 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.
@@ -0,0 +1,248 @@
1
+ "use strict";
2
+ /**
3
+ * Security Patterns - Comprehensive vulnerability detection patterns
4
+ * Adapted from Vettcode-engine for CLI use
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.ALL_PATTERNS = exports.SECURITY_HEADER_PATTERNS = exports.ERROR_HANDLING_PATTERNS = exports.DATABASE_PATTERNS = exports.CRYPTO_PATTERNS = exports.REACT_PATTERNS = exports.AUTH_PATTERNS = exports.PATH_TRAVERSAL_PATTERNS = exports.COMMAND_INJECTION_PATTERNS = exports.XSS_PATTERNS = exports.SQL_INJECTION_PATTERNS = void 0;
8
+ // SQL Injection Patterns
9
+ exports.SQL_INJECTION_PATTERNS = [
10
+ {
11
+ id: "sql-injection-template-literal",
12
+ regex: /(?:execute|query|raw)\s*\(\s*`[^`]*\$\{[^}]+\}[^`]*`/gi,
13
+ severity: "critical",
14
+ category: "security",
15
+ title: "SQL Injection via Template Literal",
16
+ description: "SQL query uses template literal with user input",
17
+ confidence: "high",
18
+ },
19
+ {
20
+ id: "sql-injection-string-concat-plus",
21
+ regex: /(?:execute|query|raw)\s*\(\s*['"][^'"]*['"]\s*\+\s*(?:req\.|params\.|query\.|body\.)/gi,
22
+ severity: "critical",
23
+ category: "security",
24
+ title: "SQL Injection via String Concatenation",
25
+ description: "SQL query concatenates user input directly",
26
+ confidence: "high",
27
+ },
28
+ {
29
+ id: "sql-injection-where-clause",
30
+ regex: /WHERE\s+[^=]+\s*=\s*['"]?\$\{|WHERE\s+[^=]+\s*=\s*['"]\s*\+/gi,
31
+ severity: "critical",
32
+ category: "security",
33
+ title: "SQL Injection in WHERE Clause",
34
+ description: "WHERE clause uses unsanitized user input",
35
+ confidence: "high",
36
+ },
37
+ ];
38
+ // XSS Patterns
39
+ exports.XSS_PATTERNS = [
40
+ {
41
+ id: "xss-react-dangerously-set-html",
42
+ regex: /dangerouslySetInnerHTML\s*=\s*\{\s*\{?\s*__html\s*:\s*(?!DOMPurify)/gi,
43
+ severity: "high",
44
+ category: "security",
45
+ title: "XSS via dangerouslySetInnerHTML Without Sanitization",
46
+ description: "React component uses dangerouslySetInnerHTML without DOMPurify",
47
+ confidence: "high",
48
+ },
49
+ {
50
+ id: "xss-dom-innerhtml",
51
+ regex: /\.innerHTML\s*=\s*(?!['"`]|DOMPurify)/gi,
52
+ severity: "high",
53
+ category: "security",
54
+ title: "XSS via innerHTML Assignment",
55
+ description: "Direct innerHTML assignment without sanitization",
56
+ confidence: "medium",
57
+ },
58
+ ];
59
+ // Command Injection Patterns
60
+ exports.COMMAND_INJECTION_PATTERNS = [
61
+ {
62
+ id: "command-injection-exec",
63
+ regex: /(?:exec|execSync|spawn|spawnSync)\s*\(\s*[`'"]?[^`'"]*\$\{/gi,
64
+ severity: "critical",
65
+ category: "security",
66
+ title: "Command Injection via exec/spawn",
67
+ description: "Shell command execution with user input",
68
+ confidence: "high",
69
+ },
70
+ {
71
+ id: "command-injection-eval",
72
+ regex: /eval\s*\(\s*(?:req\.|params\.|query\.|body\.)/gi,
73
+ severity: "critical",
74
+ category: "security",
75
+ title: "Code Injection via eval",
76
+ description: "eval() called with user input",
77
+ confidence: "high",
78
+ },
79
+ ];
80
+ // Path Traversal Patterns
81
+ exports.PATH_TRAVERSAL_PATTERNS = [
82
+ {
83
+ id: "path-traversal-fs-read",
84
+ regex: /fs\.(?:readFile|readFileSync|createReadStream)\s*\([^)]*(?:req\.|params\.|query\.)/gi,
85
+ severity: "critical",
86
+ category: "security",
87
+ title: "Path Traversal in File Read",
88
+ description: "File read operation with unsanitized user input",
89
+ confidence: "high",
90
+ },
91
+ {
92
+ id: "path-traversal-fs-write",
93
+ regex: /fs\.(?:writeFile|writeFileSync|createWriteStream)\s*\([^)]*(?:req\.|params\.|query\.)/gi,
94
+ severity: "critical",
95
+ category: "security",
96
+ title: "Path Traversal in File Write",
97
+ description: "File write operation with unsanitized user input",
98
+ confidence: "high",
99
+ },
100
+ ];
101
+ // Authentication Patterns
102
+ exports.AUTH_PATTERNS = [
103
+ {
104
+ id: "weak-jwt-secret",
105
+ regex: /jwt\.sign\s*\([^)]*,\s*['"](?:secret|password|123|test)['"]/gi,
106
+ severity: "critical",
107
+ category: "security",
108
+ title: "Weak JWT Secret",
109
+ description: "JWT signed with weak or hardcoded secret",
110
+ confidence: "high",
111
+ },
112
+ {
113
+ id: "bcrypt-low-rounds",
114
+ regex: /bcrypt\.hash\w*\s*\([^)]*,\s*([1-9]|10)\s*\)/gi,
115
+ severity: "high",
116
+ category: "security",
117
+ title: "Weak bcrypt Rounds",
118
+ description: "bcrypt rounds < 10 is too weak",
119
+ confidence: "high",
120
+ },
121
+ ];
122
+ // React Patterns
123
+ exports.REACT_PATTERNS = [
124
+ {
125
+ id: "react-useeffect-missing-deps",
126
+ regex: /useEffect\s*\([^)]*\)\s*,\s*\[\s*\]/gi,
127
+ severity: "medium",
128
+ category: "react",
129
+ title: "useEffect with Empty Dependency Array",
130
+ description: "useEffect may have missing dependencies",
131
+ confidence: "low",
132
+ },
133
+ {
134
+ id: "react-key-index",
135
+ regex: /key\s*=\s*\{\s*(?:index|i|idx)\s*\}/gi,
136
+ severity: "low",
137
+ category: "react",
138
+ title: "Using Array Index as React Key",
139
+ description: "Array index as key can cause rendering issues",
140
+ confidence: "medium",
141
+ },
142
+ ];
143
+ // Cryptography Patterns
144
+ exports.CRYPTO_PATTERNS = [
145
+ {
146
+ id: "crypto-weak-algorithm-md5",
147
+ regex: /crypto\.createHash\s*\(\s*['"]md5['"]\s*\)/gi,
148
+ severity: "high",
149
+ category: "security",
150
+ title: "Weak Cryptographic Algorithm: MD5",
151
+ description: "MD5 is cryptographically broken",
152
+ confidence: "high",
153
+ },
154
+ {
155
+ id: "crypto-weak-algorithm-sha1",
156
+ regex: /crypto\.createHash\s*\(\s*['"]sha1['"]\s*\)/gi,
157
+ severity: "high",
158
+ category: "security",
159
+ title: "Weak Cryptographic Algorithm: SHA1",
160
+ description: "SHA1 is deprecated and insecure",
161
+ confidence: "high",
162
+ },
163
+ {
164
+ id: "crypto-weak-random",
165
+ regex: /Math\.random\s*\(\s*\)/gi,
166
+ severity: "medium",
167
+ category: "security",
168
+ title: "Weak Random Number Generation",
169
+ description: "Math.random() is not cryptographically secure",
170
+ confidence: "low",
171
+ },
172
+ ];
173
+ // Database Patterns
174
+ exports.DATABASE_PATTERNS = [
175
+ {
176
+ id: "db-query-no-limit",
177
+ regex: /\.find\s*\(\s*\{[^}]*\}\s*\)(?![\s\S]{0,100}\.limit)/gi,
178
+ severity: "high",
179
+ category: "performance",
180
+ title: "Database Query Without Limit",
181
+ description: "Query can return unlimited results causing OOM",
182
+ confidence: "medium",
183
+ },
184
+ {
185
+ id: "db-n-plus-one",
186
+ regex: /for\s*\([^)]*\)\s*\{[^}]*(?:find|findOne|query)\s*\(/gi,
187
+ severity: "high",
188
+ category: "performance",
189
+ title: "Potential N+1 Query Problem",
190
+ description: "Database query inside loop causes N+1 problem",
191
+ confidence: "low",
192
+ },
193
+ ];
194
+ // Error Handling Patterns
195
+ exports.ERROR_HANDLING_PATTERNS = [
196
+ {
197
+ id: "empty-catch-block",
198
+ regex: /catch\s*\([^)]*\)\s*\{\s*\}/gi,
199
+ severity: "medium",
200
+ category: "production",
201
+ title: "Empty Catch Block",
202
+ description: "Error caught but not handled",
203
+ confidence: "high",
204
+ },
205
+ {
206
+ id: "throw-string",
207
+ regex: /throw\s+['"][^'"]+['"]/gi,
208
+ severity: "low",
209
+ category: "code-quality",
210
+ title: "Throwing String Instead of Error",
211
+ description: "Should throw Error objects, not strings",
212
+ confidence: "high",
213
+ },
214
+ ];
215
+ // Security Header Patterns
216
+ exports.SECURITY_HEADER_PATTERNS = [
217
+ {
218
+ id: "missing-helmet",
219
+ regex: /express\s*\(\s*\)(?![\s\S]{0,500}helmet)/gi,
220
+ severity: "high",
221
+ category: "security",
222
+ title: "Express App Without Helmet",
223
+ description: "Missing security headers middleware",
224
+ confidence: "medium",
225
+ },
226
+ {
227
+ id: "cors-allow-all",
228
+ regex: /Access-Control-Allow-Origin['"]?\s*:\s*['"]?\*/gi,
229
+ severity: "high",
230
+ category: "security",
231
+ title: "CORS Allows All Origins",
232
+ description: "Wildcard CORS policy is insecure",
233
+ confidence: "high",
234
+ },
235
+ ];
236
+ // Export all patterns combined
237
+ exports.ALL_PATTERNS = [
238
+ ...exports.SQL_INJECTION_PATTERNS,
239
+ ...exports.XSS_PATTERNS,
240
+ ...exports.COMMAND_INJECTION_PATTERNS,
241
+ ...exports.PATH_TRAVERSAL_PATTERNS,
242
+ ...exports.AUTH_PATTERNS,
243
+ ...exports.REACT_PATTERNS,
244
+ ...exports.CRYPTO_PATTERNS,
245
+ ...exports.DATABASE_PATTERNS,
246
+ ...exports.ERROR_HANDLING_PATTERNS,
247
+ ...exports.SECURITY_HEADER_PATTERNS,
248
+ ];
@@ -0,0 +1,144 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SYNTHESIS_SYSTEM_PROMPT = exports.BATCH_SYSTEM_PROMPT = void 0;
4
+ exports.buildSmartBatchUserPrompt = buildSmartBatchUserPrompt;
5
+ exports.buildSynthesisUserPrompt = buildSynthesisUserPrompt;
6
+ exports.getAnalysisPrompt = getAnalysisPrompt;
7
+ exports.BATCH_SYSTEM_PROMPT = `You are Vettcode Engine — a ruthless, expert application security and production-readiness auditor.
8
+
9
+ You receive:
10
+ 1. HIGH-RISK CODE SECTIONS extracted via AST analysis (not full files)
11
+ 2. STATIC ANALYSIS FINDINGS that need verification
12
+
13
+ Your job:
14
+ - Verify static findings (confirm if they're real vulnerabilities or false positives)
15
+ - Analyze the high-risk code sections for additional issues
16
+ - Report REAL issues only. Do not invent problems.
17
+ - Be harsh but accurate.
18
+
19
+ Detect and report:
20
+ - Security vulnerabilities (injection, XSS, CSRF, auth bypass, secrets in code, insecure crypto, SSRF, path traversal, IDOR, etc.)
21
+ - Production failures waiting to happen (missing error handling, unhandled promises, race conditions, memory leaks, missing timeouts, bad retries)
22
+ - Type/logic errors and wrong assumptions that can crash the app or corrupt data
23
+ - Database risks (SQL injection, N+1, missing transactions, connection leaks, migration hazards, missing indexes on hot paths)
24
+ - Misconfiguration (debug in prod, open CORS, weak session settings)
25
+ - Reliability and scalability issues
26
+
27
+ For static findings:
28
+ - If the code shows proper mitigation (parameterized queries, sanitization, auth middleware), mark as FALSE POSITIVE
29
+ - If the vulnerability is real, CONFIRM it and provide detailed evidence
30
+ - Add context the static analyzer couldn't see
31
+
32
+ Respond with ONLY valid JSON (no markdown fences):
33
+ {
34
+ "findings": [
35
+ {
36
+ "id": "unique-kebab-id",
37
+ "severity": "critical|high|medium|low|info",
38
+ "category": "security|production|typing|logic|database|performance|reliability|configuration|other",
39
+ "title": "short title",
40
+ "description": "detailed explanation",
41
+ "file": "relative/path",
42
+ "line": 0,
43
+ "evidence": "code snippet or behavior",
44
+ "mitigation": "how to fix now",
45
+ "prevention": "how to stop recurrence",
46
+ "confidence": "high|medium|low",
47
+ "source": "static-verified|static-rejected|ai-discovered"
48
+ }
49
+ ],
50
+ "notes": "brief batch-level observations",
51
+ "partialScore": 0
52
+ }
53
+
54
+ partialScore is 0-100 for THIS batch only, strict.`;
55
+ exports.SYNTHESIS_SYSTEM_PROMPT = `You are Vettcode Engine synthesizing a final audit report.
56
+
57
+ You receive:
58
+ 1. HIGH-CONFIDENCE static analysis findings (already verified)
59
+ 2. AI-analyzed findings (verified static + newly discovered)
60
+
61
+ Rules:
62
+ - Merge duplicate findings; keep the strongest severity
63
+ - Prioritize high-confidence findings
64
+ - The overall score (0-100) must be STRICT and HONEST. No sugar-coating.
65
+ - Critical blockers: 0-25
66
+ - Major issues: 25-50
67
+ - Moderate issues: 50-70
68
+ - Minor issues: 70-85
69
+ - Excellent: 85-95
70
+ - Perfect (rare): 95-100
71
+ - grade: letter A+ through F matching the score harshly
72
+ - executiveVerdict: 2-4 blunt sentences a CTO would read
73
+ - criticalBlockers: issues that MUST be fixed before any production deploy
74
+
75
+ Respond with ONLY valid JSON (no markdown):
76
+ {
77
+ "score": 0,
78
+ "grade": "F",
79
+ "summary": "overview",
80
+ "executiveVerdict": "blunt verdict",
81
+ "findings": [... same finding schema ...],
82
+ "strengths": ["only genuine strengths"],
83
+ "criticalBlockers": ["..."],
84
+ "methodology": {
85
+ "staticAnalysisFindings": 0,
86
+ "aiVerifiedFindings": 0,
87
+ "aiDiscoveredFindings": 0,
88
+ "falsePositivesRejected": 0
89
+ }
90
+ }`;
91
+ function buildSmartBatchUserPrompt(projectName, batchIndex, totalBatches, smartContext, staticFindings) {
92
+ let prompt = `Project: ${projectName}
93
+ Batch: ${batchIndex + 1} of ${totalBatches}
94
+
95
+ === STATIC ANALYSIS FINDINGS TO VERIFY ===
96
+ ${staticFindings.length > 0 ? JSON.stringify(staticFindings, null, 2) : "None in this batch"}
97
+
98
+ === HIGH-RISK CODE SECTIONS (AST-EXTRACTED) ===
99
+ ${smartContext}
100
+
101
+ INSTRUCTIONS:
102
+ 1. Verify each static finding - check if the vulnerability is real or mitigated
103
+ 2. Analyze the high-risk code sections for additional issues
104
+ 3. Report only confirmed, real vulnerabilities`;
105
+ return prompt;
106
+ }
107
+ function buildSynthesisUserPrompt(projectName, stats, staticFindings, batchResults) {
108
+ return `Project: ${projectName}
109
+
110
+ === SCAN STATISTICS ===
111
+ Files scanned: ${stats.files}
112
+ Total lines: ${stats.lines}
113
+ High-risk lines extracted: ${stats.extractedLines} (${stats.compressionRatio}% compression)
114
+ Paths ignored (deps/build): ${stats.ignored}
115
+
116
+ === HIGH-CONFIDENCE STATIC FINDINGS ===
117
+ ${JSON.stringify(staticFindings, null, 2)}
118
+
119
+ === AI BATCH ANALYSIS RESULTS ===
120
+ ${batchResults}
121
+
122
+ Produce the final merged Vettcode report with strict 0-100 score.`;
123
+ }
124
+ function getAnalysisPrompt(projectName, batch, batchIndex) {
125
+ let prompt = `Project: ${projectName}
126
+ Batch: ${batchIndex + 1}
127
+
128
+ === STATIC ANALYSIS FINDINGS TO VERIFY ===
129
+ ${batch.staticFindings.length > 0 ? JSON.stringify(batch.staticFindings, null, 2) : "None in this batch"}
130
+
131
+ === HIGH-RISK CODE SECTIONS (AST-EXTRACTED) ===
132
+ `;
133
+ for (const extracted of batch.sections) {
134
+ prompt += `\n--- ${extracted.file} ---\n`;
135
+ for (const section of extracted.sections) {
136
+ prompt += `\nLine ${section.startLine}-${section.endLine} (Type: ${section.type}):\n${section.code}\n`;
137
+ }
138
+ }
139
+ prompt += `\nINSTRUCTIONS:
140
+ 1. Verify each static finding - check if the vulnerability is real or mitigated
141
+ 2. Analyze the high-risk code sections for additional issues
142
+ 3. Report only confirmed, real vulnerabilities`;
143
+ return prompt;
144
+ }