@voidagency/web-scanner 0.0.1
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/README.md +198 -0
- package/dist/aggregator.d.ts +65 -0
- package/dist/aggregator.d.ts.map +1 -0
- package/dist/aggregator.js +546 -0
- package/dist/aggregator.js.map +1 -0
- package/dist/categories.d.ts +59 -0
- package/dist/categories.d.ts.map +1 -0
- package/dist/categories.js +278 -0
- package/dist/categories.js.map +1 -0
- package/dist/cli.d.ts +12 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +457 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +19 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +121 -0
- package/dist/config.js.map +1 -0
- package/dist/coverage.d.ts +49 -0
- package/dist/coverage.d.ts.map +1 -0
- package/dist/coverage.js +165 -0
- package/dist/coverage.js.map +1 -0
- package/dist/enrichers/nvd.d.ts +55 -0
- package/dist/enrichers/nvd.d.ts.map +1 -0
- package/dist/enrichers/nvd.js +326 -0
- package/dist/enrichers/nvd.js.map +1 -0
- package/dist/report.d.ts +12 -0
- package/dist/report.d.ts.map +1 -0
- package/dist/report.js +460 -0
- package/dist/report.js.map +1 -0
- package/dist/runners/nuclei.d.ts +59 -0
- package/dist/runners/nuclei.d.ts.map +1 -0
- package/dist/runners/nuclei.js +531 -0
- package/dist/runners/nuclei.js.map +1 -0
- package/dist/runners/testssl.d.ts +16 -0
- package/dist/runners/testssl.d.ts.map +1 -0
- package/dist/runners/testssl.js +179 -0
- package/dist/runners/testssl.js.map +1 -0
- package/dist/runners/zap.d.ts +30 -0
- package/dist/runners/zap.d.ts.map +1 -0
- package/dist/runners/zap.js +389 -0
- package/dist/runners/zap.js.map +1 -0
- package/dist/types.d.ts +172 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/package.json +54 -0
- package/templates/drupal-api-index-exposed.yaml +81 -0
- package/templates/drupal-api-user-detail.yaml +76 -0
- package/templates/drupal-api-user-listing.yaml +59 -0
- package/templates/drupal-dev-files-exposed.yaml +73 -0
- package/templates/drupal-file-path-disclosure.yaml +59 -0
- package/templates/drupal-files-listing.yaml +63 -0
- package/templates/drupal-install-error-disclosure.yaml +62 -0
- package/templates/drupal-theme-lockfiles.yaml +79 -0
- package/templates/drupal-version-detect.yaml +89 -0
- package/templates/http-options-enabled.yaml +56 -0
- package/templates/nextjs-version-detect.yaml +35 -0
- package/templates/php-version-detect.yaml +37 -0
- package/zap.yaml +33 -0
package/dist/cli.js
ADDED
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* VoidSec Scanner CLI
|
|
4
|
+
* Security scanning orchestrator
|
|
5
|
+
*
|
|
6
|
+
* Architecture:
|
|
7
|
+
* - ZAP (primary): JS CVEs, Headers, CORS, CSRF, XSS hints
|
|
8
|
+
* - Nuclei (supplementary): CMS detection, exposed files, takeovers
|
|
9
|
+
* - testssl.sh: SSL/TLS analysis
|
|
10
|
+
*/
|
|
11
|
+
import { Command } from 'commander';
|
|
12
|
+
import { writeFile } from 'fs/promises';
|
|
13
|
+
import { execa } from 'execa';
|
|
14
|
+
import { runNuclei, isNucleiInstalled, getAvailableStacks, getStackTags, setSeverityOverrides, runDrupalDynamicScans } from './runners/nuclei.js';
|
|
15
|
+
import { loadConfig, generateExampleConfig } from './config.js';
|
|
16
|
+
import { runTestssl, isTestsslInstalled } from './runners/testssl.js';
|
|
17
|
+
import { runZap, checkZapAvailable, pullZapImage } from './runners/zap.js';
|
|
18
|
+
import { aggregateFindings, mergeTechnologies } from './aggregator.js';
|
|
19
|
+
import { generateHtmlReport, generateJsonReport } from './report.js';
|
|
20
|
+
const program = new Command();
|
|
21
|
+
program
|
|
22
|
+
.name('voidsec')
|
|
23
|
+
.description('Security scanning CLI - ZAP primary with Nuclei supplementary')
|
|
24
|
+
.version('0.0.1');
|
|
25
|
+
const availableStacks = getAvailableStacks();
|
|
26
|
+
program
|
|
27
|
+
.command('scan')
|
|
28
|
+
.description('Scan a target URL for security vulnerabilities')
|
|
29
|
+
.argument('<target>', 'Target URL to scan')
|
|
30
|
+
.option('-p, --profile <profile>', 'Scan profile: quick, standard, deep', 'standard')
|
|
31
|
+
.option('-s, --stack <stack>', `Tech stack: ${availableStacks.join(', ')}`, 'generic')
|
|
32
|
+
.option('-o, --output <file>', 'Output file path')
|
|
33
|
+
.option('--json', 'Output JSON instead of HTML')
|
|
34
|
+
.option('--rate-limit <n>', 'Rate limit for requests per second', '50')
|
|
35
|
+
.option('--enrich', 'Full NVD enrichment (slower, queries API for all findings)')
|
|
36
|
+
.option('--no-cve', 'Disable CVE lookups for detected technologies')
|
|
37
|
+
.option('--tech <specs...>', 'Specify known technologies for CVE lookup (e.g., drupal:10.5.3 php:8.3)')
|
|
38
|
+
.option('--no-zap', 'Skip ZAP scan (use Nuclei only)')
|
|
39
|
+
.option('--no-nuclei', 'Skip Nuclei scan (use ZAP only)')
|
|
40
|
+
.option('--ssl', 'Enable SSL/TLS analysis (testssl.sh)')
|
|
41
|
+
.action(async (target, options) => {
|
|
42
|
+
const profile = options.profile;
|
|
43
|
+
const stack = options.stack;
|
|
44
|
+
const runZapScan = options.zap !== false;
|
|
45
|
+
const runNucleiScan = options.nuclei !== false;
|
|
46
|
+
const runSslScan = options.ssl === true;
|
|
47
|
+
if (!['quick', 'standard', 'deep'].includes(profile)) {
|
|
48
|
+
console.error('❌ Invalid profile. Use: quick, standard, or deep');
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
if (!availableStacks.includes(stack)) {
|
|
52
|
+
console.error(`❌ Invalid stack. Use: ${availableStacks.join(', ')}`);
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
const tags = getStackTags(stack);
|
|
56
|
+
// Load config
|
|
57
|
+
const config = await loadConfig();
|
|
58
|
+
// Apply severity overrides from config
|
|
59
|
+
if (config.severity_overrides) {
|
|
60
|
+
setSeverityOverrides(config.severity_overrides);
|
|
61
|
+
console.log('📋 Loaded severity overrides from config');
|
|
62
|
+
}
|
|
63
|
+
console.log('🔍 VoidSec Security Scanner v0.2');
|
|
64
|
+
console.log('━'.repeat(40));
|
|
65
|
+
console.log(`Target: ${target}`);
|
|
66
|
+
console.log(`Profile: ${profile}`);
|
|
67
|
+
console.log(`Stack: ${stack}`);
|
|
68
|
+
console.log(`Scanners: ${[runZapScan && 'ZAP', runNucleiScan && 'Nuclei', runSslScan && 'testssl'].filter(Boolean).join(', ')}`);
|
|
69
|
+
console.log(`CVE lookup: ${options.cve === false ? 'disabled' : options.enrich ? 'full (NVD)' : 'auto (nginx, drupal, php, nextjs)'}`);
|
|
70
|
+
console.log('');
|
|
71
|
+
// Check tool availability
|
|
72
|
+
console.log('Checking tools...');
|
|
73
|
+
const [zapOk, nucleiOk, testsslOk] = await Promise.all([
|
|
74
|
+
runZapScan ? checkZapAvailable() : Promise.resolve(false),
|
|
75
|
+
runNucleiScan ? isNucleiInstalled() : Promise.resolve(false),
|
|
76
|
+
runSslScan ? isTestsslInstalled() : Promise.resolve(false),
|
|
77
|
+
]);
|
|
78
|
+
if (runZapScan) {
|
|
79
|
+
if (!zapOk) {
|
|
80
|
+
console.error('❌ Docker not found. ZAP requires Docker.');
|
|
81
|
+
console.error(' Install OrbStack: https://orbstack.dev/');
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
console.log(' ✓ Docker (for ZAP)');
|
|
85
|
+
// Ensure ZAP image is available
|
|
86
|
+
await pullZapImage((msg) => console.log(` ${msg}`));
|
|
87
|
+
}
|
|
88
|
+
if (runNucleiScan) {
|
|
89
|
+
if (!nucleiOk) {
|
|
90
|
+
console.warn(' ⚠ Nuclei not found (supplementary scans will be skipped)');
|
|
91
|
+
console.warn(' Install with: brew install nuclei');
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
console.log(' ✓ Nuclei');
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (runSslScan) {
|
|
98
|
+
if (!testsslOk) {
|
|
99
|
+
console.warn(' ⚠ testssl.sh not found (SSL checks will be skipped)');
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
console.log(' ✓ testssl.sh');
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// macOS Keychain permission warning (show before scans start)
|
|
106
|
+
if (runNucleiScan && nucleiOk) {
|
|
107
|
+
console.log('');
|
|
108
|
+
console.log('\x1b[93m⚠️ macOS Keychain Permission:\x1b[0m');
|
|
109
|
+
console.log('\x1b[93m When Nuclei runs headless browser checks, macOS may prompt:\x1b[0m');
|
|
110
|
+
console.log('\x1b[93m "Chromium wants to use your keychain" → Click "Always Allow"\x1b[0m');
|
|
111
|
+
}
|
|
112
|
+
console.log('');
|
|
113
|
+
const startTime = new Date();
|
|
114
|
+
const allFindings = [];
|
|
115
|
+
const allTechnologies = [];
|
|
116
|
+
// 1. Run ZAP scan (PRIMARY)
|
|
117
|
+
if (runZapScan && zapOk) {
|
|
118
|
+
console.log('🔵 Running ZAP baseline scan (primary)...');
|
|
119
|
+
console.log(' This scans for: JS CVEs, Security Headers, CORS, CSRF, XSS');
|
|
120
|
+
try {
|
|
121
|
+
const { findings, technologies } = await runZap(target, {
|
|
122
|
+
outputDir: process.cwd(),
|
|
123
|
+
timeout: profile === 'quick' ? 180 : profile === 'standard' ? 300 : 600,
|
|
124
|
+
onProgress: (msg) => console.log(` ${msg}`),
|
|
125
|
+
});
|
|
126
|
+
allFindings.push(...findings);
|
|
127
|
+
allTechnologies.push(technologies);
|
|
128
|
+
console.log(` ✓ Found ${findings.length} issues`);
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
console.error(` ❌ ZAP scan failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
132
|
+
}
|
|
133
|
+
console.log('');
|
|
134
|
+
}
|
|
135
|
+
// 2. Run Nuclei scan (SUPPLEMENTARY)
|
|
136
|
+
if (runNucleiScan && nucleiOk) {
|
|
137
|
+
// Update templates before scanning (quick check, won't update if already latest)
|
|
138
|
+
try {
|
|
139
|
+
const { stdout } = await execa('nuclei', ['-update-templates'], {
|
|
140
|
+
stdio: 'pipe',
|
|
141
|
+
reject: false
|
|
142
|
+
});
|
|
143
|
+
// Only show message if there were actual updates (not just "No new updates found")
|
|
144
|
+
if (stdout && !stdout.includes('No new updates found')) {
|
|
145
|
+
console.log('Updating Nuclei templates...');
|
|
146
|
+
console.log(stdout);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
// Ignore errors, continue with scan
|
|
151
|
+
}
|
|
152
|
+
console.log('🟡 Running Nuclei scan (supplementary)...');
|
|
153
|
+
console.log(` Stack: ${stack} | Tags: ${tags.join(', ')}`);
|
|
154
|
+
try {
|
|
155
|
+
const { findings, technologies } = await runNuclei(target, profile, {
|
|
156
|
+
rateLimit: parseInt(options.rateLimit, 10),
|
|
157
|
+
stack,
|
|
158
|
+
});
|
|
159
|
+
allFindings.push(...findings);
|
|
160
|
+
allTechnologies.push(technologies);
|
|
161
|
+
console.log(` ✓ Found ${findings.length} issues`);
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
console.error(` ❌ Nuclei scan failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
165
|
+
}
|
|
166
|
+
console.log('');
|
|
167
|
+
// Run Drupal-specific dynamic scans (extracts themes from HTML, etc.)
|
|
168
|
+
if (stack === 'drupal') {
|
|
169
|
+
console.log('🟣 Running Drupal dynamic scans...');
|
|
170
|
+
try {
|
|
171
|
+
const drupalFindings = await runDrupalDynamicScans(target, (msg) => console.log(` ${msg}`));
|
|
172
|
+
allFindings.push(...drupalFindings);
|
|
173
|
+
console.log(` ✓ Found ${drupalFindings.length} theme-related issues`);
|
|
174
|
+
}
|
|
175
|
+
catch (error) {
|
|
176
|
+
console.error(` ❌ Drupal dynamic scan failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
177
|
+
}
|
|
178
|
+
console.log('');
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
// 3. Run testssl.sh scan
|
|
182
|
+
if (runSslScan && testsslOk && target.startsWith('https://')) {
|
|
183
|
+
console.log('🟢 Running SSL/TLS analysis...');
|
|
184
|
+
try {
|
|
185
|
+
const sslFindings = await runTestssl(target, profile, {
|
|
186
|
+
startIndex: allFindings.length,
|
|
187
|
+
});
|
|
188
|
+
allFindings.push(...sslFindings);
|
|
189
|
+
console.log(` ✓ Found ${sslFindings.length} issues`);
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
console.error(` ❌ testssl scan failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
193
|
+
}
|
|
194
|
+
console.log('');
|
|
195
|
+
}
|
|
196
|
+
const endTime = new Date();
|
|
197
|
+
// Parse manual tech specs (e.g., drupal:10.5.3)
|
|
198
|
+
const manualTech = [];
|
|
199
|
+
if (options.tech) {
|
|
200
|
+
for (const spec of options.tech) {
|
|
201
|
+
const [tech, version] = spec.split(':');
|
|
202
|
+
if (tech && version) {
|
|
203
|
+
manualTech.push({ tech: tech.toLowerCase(), version });
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
// Aggregate results
|
|
208
|
+
console.log('Aggregating results...');
|
|
209
|
+
const technologies = mergeTechnologies(allTechnologies);
|
|
210
|
+
const report = await aggregateFindings(target, profile, startTime, endTime, allFindings, technologies, {
|
|
211
|
+
enableNvd: options.enrich,
|
|
212
|
+
disableCve: options.cve === false,
|
|
213
|
+
manualTech,
|
|
214
|
+
onProgress: (msg) => console.log(` ${msg}`),
|
|
215
|
+
});
|
|
216
|
+
// Generate output
|
|
217
|
+
const output = options.json
|
|
218
|
+
? generateJsonReport(report)
|
|
219
|
+
: generateHtmlReport(report);
|
|
220
|
+
// Generate default filename from sanitized target + date
|
|
221
|
+
const sanitizeForFilename = (url) => {
|
|
222
|
+
return url
|
|
223
|
+
.replace(/^https?:\/\//, '') // Remove protocol
|
|
224
|
+
.replace(/[/:?#\[\]@!$&'()*+,;=]/g, '-') // Replace special chars
|
|
225
|
+
.replace(/-+/g, '-') // Collapse multiple dashes
|
|
226
|
+
.replace(/^-|-$/g, '') // Trim leading/trailing dashes
|
|
227
|
+
.toLowerCase();
|
|
228
|
+
};
|
|
229
|
+
const dateStr = startTime.toISOString().split('T')[0]; // YYYY-MM-DD
|
|
230
|
+
const defaultFilename = `${sanitizeForFilename(target)}-${dateStr}.${options.json ? 'json' : 'html'}`;
|
|
231
|
+
// Write or print output
|
|
232
|
+
if (options.output) {
|
|
233
|
+
await writeFile(options.output, output);
|
|
234
|
+
console.log(`✓ Report saved to: ${options.output}`);
|
|
235
|
+
}
|
|
236
|
+
else if (!options.json) {
|
|
237
|
+
// Only print to stdout if not saving and not JSON (HTML is too long)
|
|
238
|
+
await writeFile(defaultFilename, output);
|
|
239
|
+
console.log(`✓ Report saved to: ${defaultFilename}`);
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
console.log(output);
|
|
243
|
+
}
|
|
244
|
+
// Print summary
|
|
245
|
+
console.log('');
|
|
246
|
+
console.log('━'.repeat(40));
|
|
247
|
+
console.log('📊 Summary:');
|
|
248
|
+
if (report.summary.critical > 0)
|
|
249
|
+
console.log(` 🔴 Critical: ${report.summary.critical}`);
|
|
250
|
+
if (report.summary.high > 0)
|
|
251
|
+
console.log(` 🟠 High: ${report.summary.high}`);
|
|
252
|
+
if (report.summary.medium > 0)
|
|
253
|
+
console.log(` 🟡 Medium: ${report.summary.medium}`);
|
|
254
|
+
if (report.summary.low > 0)
|
|
255
|
+
console.log(` 🔵 Low: ${report.summary.low}`);
|
|
256
|
+
if (report.summary.info > 0)
|
|
257
|
+
console.log(` ⚪ Info: ${report.summary.info}`);
|
|
258
|
+
console.log(` 📋 Total: ${report.totalFindings}`);
|
|
259
|
+
console.log(` ⏱️ Duration: ${report.duration}`);
|
|
260
|
+
});
|
|
261
|
+
program
|
|
262
|
+
.command('check')
|
|
263
|
+
.description('Check if required tools are installed')
|
|
264
|
+
.action(async () => {
|
|
265
|
+
console.log('Checking installed tools...');
|
|
266
|
+
console.log('');
|
|
267
|
+
const [zapOk, nucleiOk, testsslOk] = await Promise.all([
|
|
268
|
+
checkZapAvailable(),
|
|
269
|
+
isNucleiInstalled(),
|
|
270
|
+
isTestsslInstalled(),
|
|
271
|
+
]);
|
|
272
|
+
console.log(`Docker/ZAP: ${zapOk ? '✓ Installed' : '✗ Not found'}`);
|
|
273
|
+
console.log(`Nuclei: ${nucleiOk ? '✓ Installed' : '✗ Not found'}`);
|
|
274
|
+
console.log(`testssl.sh: ${testsslOk ? '✓ Installed' : '✗ Not found'}`);
|
|
275
|
+
console.log('');
|
|
276
|
+
if (!zapOk || !nucleiOk || !testsslOk) {
|
|
277
|
+
console.log('Install missing tools:');
|
|
278
|
+
if (!zapOk)
|
|
279
|
+
console.log(' Docker: https://orbstack.dev/');
|
|
280
|
+
if (!nucleiOk)
|
|
281
|
+
console.log(' Nuclei: brew install nuclei');
|
|
282
|
+
if (!testsslOk)
|
|
283
|
+
console.log(' testssl: brew install testssl');
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
console.log('All tools ready! ✓');
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
program
|
|
290
|
+
.command('setup')
|
|
291
|
+
.description('Setup required tools (check brew, install nuclei, pull ZAP image)')
|
|
292
|
+
.option('--skip-brew-check', 'Skip Homebrew check')
|
|
293
|
+
.action(async (options) => {
|
|
294
|
+
console.log('🔧 VoidSec Setup');
|
|
295
|
+
console.log('━'.repeat(40));
|
|
296
|
+
console.log('');
|
|
297
|
+
// Check Homebrew
|
|
298
|
+
let brewAvailable = false;
|
|
299
|
+
if (!options.skipBrewCheck) {
|
|
300
|
+
console.log('Checking Homebrew...');
|
|
301
|
+
try {
|
|
302
|
+
await execa('brew', ['--version'], { reject: true });
|
|
303
|
+
brewAvailable = true;
|
|
304
|
+
console.log(' ✓ Homebrew installed');
|
|
305
|
+
}
|
|
306
|
+
catch {
|
|
307
|
+
console.log(' ✗ Homebrew not found');
|
|
308
|
+
console.log(' Install from: https://brew.sh');
|
|
309
|
+
console.log('');
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
brewAvailable = true; // Assume brew is available if skipping check
|
|
314
|
+
}
|
|
315
|
+
// Check Docker
|
|
316
|
+
console.log('Checking Docker...');
|
|
317
|
+
const dockerOk = await checkZapAvailable();
|
|
318
|
+
if (dockerOk) {
|
|
319
|
+
console.log(' ✓ Docker is running');
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
console.log(' ✗ Docker not running or not installed');
|
|
323
|
+
console.log(' Install OrbStack: https://orbstack.dev/');
|
|
324
|
+
console.log('');
|
|
325
|
+
}
|
|
326
|
+
// Check and install Nuclei
|
|
327
|
+
console.log('Checking Nuclei...');
|
|
328
|
+
const nucleiOk = await isNucleiInstalled();
|
|
329
|
+
if (nucleiOk) {
|
|
330
|
+
console.log(' ✓ Nuclei installed');
|
|
331
|
+
}
|
|
332
|
+
else {
|
|
333
|
+
if (brewAvailable) {
|
|
334
|
+
console.log(' ✗ Nuclei not found');
|
|
335
|
+
console.log(' Installing Nuclei via Homebrew...');
|
|
336
|
+
try {
|
|
337
|
+
await execa('brew', ['install', 'nuclei'], {
|
|
338
|
+
stdio: 'inherit',
|
|
339
|
+
reject: true
|
|
340
|
+
});
|
|
341
|
+
console.log(' ✓ Nuclei installed successfully');
|
|
342
|
+
}
|
|
343
|
+
catch (error) {
|
|
344
|
+
console.error(` ❌ Failed to install Nuclei: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
345
|
+
console.log(' Try manually: brew install nuclei');
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
else {
|
|
349
|
+
console.log(' ✗ Nuclei not found');
|
|
350
|
+
console.log(' Install manually: brew install nuclei');
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
// macOS Keychain permission note
|
|
354
|
+
if (nucleiOk || brewAvailable) {
|
|
355
|
+
console.log('');
|
|
356
|
+
console.log('\x1b[93m📋 macOS Keychain Permission:\x1b[0m');
|
|
357
|
+
console.log('\x1b[93m When Nuclei runs headless browser checks (e.g., Next.js detection),\x1b[0m');
|
|
358
|
+
console.log('\x1b[93m macOS may prompt: "Chromium wants to use your keychain"\x1b[0m');
|
|
359
|
+
console.log('\x1b[93m → Click "Always Allow" (only asked once)\x1b[0m');
|
|
360
|
+
console.log('');
|
|
361
|
+
}
|
|
362
|
+
// Update Nuclei templates
|
|
363
|
+
const nucleiInstalled = await isNucleiInstalled();
|
|
364
|
+
if (nucleiInstalled) {
|
|
365
|
+
console.log('Updating Nuclei templates...');
|
|
366
|
+
try {
|
|
367
|
+
await execa('nuclei', ['-update-templates'], {
|
|
368
|
+
stdio: 'inherit',
|
|
369
|
+
reject: false
|
|
370
|
+
});
|
|
371
|
+
console.log(' ✓ Nuclei templates updated');
|
|
372
|
+
}
|
|
373
|
+
catch (error) {
|
|
374
|
+
console.warn(` ⚠ Failed to update templates: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
375
|
+
}
|
|
376
|
+
console.log('');
|
|
377
|
+
}
|
|
378
|
+
// Pull ZAP Docker image
|
|
379
|
+
if (dockerOk) {
|
|
380
|
+
console.log('Checking ZAP Docker image...');
|
|
381
|
+
try {
|
|
382
|
+
await pullZapImage((msg) => console.log(` ${msg}`));
|
|
383
|
+
console.log('');
|
|
384
|
+
}
|
|
385
|
+
catch (error) {
|
|
386
|
+
console.error(` ❌ Failed to pull ZAP image: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
387
|
+
console.log('');
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
else {
|
|
391
|
+
console.log('Skipping ZAP image pull (Docker not available)');
|
|
392
|
+
console.log('');
|
|
393
|
+
}
|
|
394
|
+
// Final status
|
|
395
|
+
console.log('━'.repeat(40));
|
|
396
|
+
const finalNucleiOk = await isNucleiInstalled();
|
|
397
|
+
const finalDockerOk = await checkZapAvailable();
|
|
398
|
+
if (finalNucleiOk && finalDockerOk) {
|
|
399
|
+
console.log('✅ Setup complete! All tools ready.');
|
|
400
|
+
}
|
|
401
|
+
else {
|
|
402
|
+
console.log('⚠️ Setup incomplete:');
|
|
403
|
+
if (!finalNucleiOk)
|
|
404
|
+
console.log(' - Nuclei still missing');
|
|
405
|
+
if (!finalDockerOk)
|
|
406
|
+
console.log(' - Docker still not available');
|
|
407
|
+
}
|
|
408
|
+
});
|
|
409
|
+
program
|
|
410
|
+
.command('stacks')
|
|
411
|
+
.description('List available tech stacks and their tags')
|
|
412
|
+
.action(() => {
|
|
413
|
+
console.log('Available tech stacks:');
|
|
414
|
+
console.log('');
|
|
415
|
+
for (const stack of availableStacks) {
|
|
416
|
+
const tags = getStackTags(stack);
|
|
417
|
+
console.log(` ${stack}`);
|
|
418
|
+
console.log(` Tags: ${tags.join(', ')}`);
|
|
419
|
+
console.log('');
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
program
|
|
423
|
+
.command('init')
|
|
424
|
+
.description('Generate example config file')
|
|
425
|
+
.action(async () => {
|
|
426
|
+
const configContent = generateExampleConfig();
|
|
427
|
+
await writeFile('voidsec.config.yaml', configContent);
|
|
428
|
+
console.log('✓ Created voidsec.config.yaml');
|
|
429
|
+
console.log('');
|
|
430
|
+
console.log('Edit this file to customize severity overrides for your context.');
|
|
431
|
+
});
|
|
432
|
+
program
|
|
433
|
+
.command('test-drupal')
|
|
434
|
+
.description('Quick test: Run only Drupal-specific checks (themes, API, file IDOR)')
|
|
435
|
+
.argument('<target>', 'Target URL to test')
|
|
436
|
+
.action(async (target) => {
|
|
437
|
+
console.log(`🧪 Quick Drupal test: ${target}\n`);
|
|
438
|
+
const findings = await runDrupalDynamicScans(target, (msg) => console.log(` ${msg}`));
|
|
439
|
+
console.log('\n' + '━'.repeat(40));
|
|
440
|
+
if (findings.length === 0) {
|
|
441
|
+
console.log('✅ No issues found');
|
|
442
|
+
}
|
|
443
|
+
else {
|
|
444
|
+
console.log(`Found ${findings.length} issue(s):\n`);
|
|
445
|
+
for (const f of findings) {
|
|
446
|
+
console.log(`🔴 ${f.title} [${f.severity.toUpperCase()}]`);
|
|
447
|
+
console.log(` Target: ${f.target}`);
|
|
448
|
+
if (f.extracted?.length)
|
|
449
|
+
console.log(` Extracted: ${f.extracted.slice(0, 3).join(', ')}`);
|
|
450
|
+
if (f.affectedUrls?.length)
|
|
451
|
+
console.log(` Affected: ${f.affectedUrls.length} URLs`);
|
|
452
|
+
console.log('');
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
});
|
|
456
|
+
program.parse();
|
|
457
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration loader
|
|
3
|
+
* Reads voidsec.config.yaml or voidsec.config.json
|
|
4
|
+
*/
|
|
5
|
+
export interface VoidSecConfig {
|
|
6
|
+
severity_overrides?: Record<string, string>;
|
|
7
|
+
default_stack?: string;
|
|
8
|
+
default_profile?: string;
|
|
9
|
+
rate_limit?: number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Load config from file
|
|
13
|
+
*/
|
|
14
|
+
export declare function loadConfig(dir?: string): Promise<VoidSecConfig>;
|
|
15
|
+
/**
|
|
16
|
+
* Generate example config file
|
|
17
|
+
*/
|
|
18
|
+
export declare function generateExampleConfig(): string;
|
|
19
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,WAAW,aAAa;IAC5B,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAgED;;GAEG;AACH,wBAAsB,UAAU,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,aAAa,CAAC,CAqBpF;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CA+B9C"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration loader
|
|
3
|
+
* Reads voidsec.config.yaml or voidsec.config.json
|
|
4
|
+
*/
|
|
5
|
+
import { readFile } from 'fs/promises';
|
|
6
|
+
import { existsSync } from 'fs';
|
|
7
|
+
import { join } from 'path';
|
|
8
|
+
const CONFIG_FILES = [
|
|
9
|
+
'voidsec.config.yaml',
|
|
10
|
+
'voidsec.config.yml',
|
|
11
|
+
'voidsec.config.json',
|
|
12
|
+
'.voidsec.yaml',
|
|
13
|
+
'.voidsec.json',
|
|
14
|
+
];
|
|
15
|
+
/**
|
|
16
|
+
* Simple YAML parser for our config format
|
|
17
|
+
* Only supports key: value pairs and nested objects
|
|
18
|
+
*/
|
|
19
|
+
function parseSimpleYaml(content) {
|
|
20
|
+
const result = {};
|
|
21
|
+
let currentSection = null;
|
|
22
|
+
let currentObject = {};
|
|
23
|
+
const lines = content.split('\n');
|
|
24
|
+
for (const line of lines) {
|
|
25
|
+
const trimmed = line.trim();
|
|
26
|
+
// Skip empty lines and comments
|
|
27
|
+
if (!trimmed || trimmed.startsWith('#'))
|
|
28
|
+
continue;
|
|
29
|
+
// Check indentation
|
|
30
|
+
const indent = line.length - line.trimStart().length;
|
|
31
|
+
if (indent === 0 && trimmed.includes(':')) {
|
|
32
|
+
// Top-level key
|
|
33
|
+
if (currentSection && Object.keys(currentObject).length > 0) {
|
|
34
|
+
result[currentSection] = currentObject;
|
|
35
|
+
currentObject = {};
|
|
36
|
+
}
|
|
37
|
+
const [key, ...valueParts] = trimmed.split(':');
|
|
38
|
+
const value = valueParts.join(':').trim();
|
|
39
|
+
if (value) {
|
|
40
|
+
// Simple key: value
|
|
41
|
+
result[key.trim()] = value;
|
|
42
|
+
currentSection = null;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
// Section header
|
|
46
|
+
currentSection = key.trim();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
else if (indent > 0 && currentSection && trimmed.includes(':')) {
|
|
50
|
+
// Nested key: value
|
|
51
|
+
const [key, ...valueParts] = trimmed.split(':');
|
|
52
|
+
const value = valueParts.join(':').trim();
|
|
53
|
+
currentObject[key.trim()] = value;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// Save last section
|
|
57
|
+
if (currentSection && Object.keys(currentObject).length > 0) {
|
|
58
|
+
result[currentSection] = currentObject;
|
|
59
|
+
}
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Load config from file
|
|
64
|
+
*/
|
|
65
|
+
export async function loadConfig(dir = process.cwd()) {
|
|
66
|
+
for (const filename of CONFIG_FILES) {
|
|
67
|
+
const filepath = join(dir, filename);
|
|
68
|
+
if (existsSync(filepath)) {
|
|
69
|
+
try {
|
|
70
|
+
const content = await readFile(filepath, 'utf-8');
|
|
71
|
+
if (filename.endsWith('.json')) {
|
|
72
|
+
return JSON.parse(content);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
return parseSimpleYaml(content);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
console.warn(`Warning: Failed to parse ${filename}: ${error}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// No config file found, return defaults
|
|
84
|
+
return {};
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Generate example config file
|
|
88
|
+
*/
|
|
89
|
+
export function generateExampleConfig() {
|
|
90
|
+
return `# VoidSec Scanner Configuration
|
|
91
|
+
# Place this file as voidsec.config.yaml in your project root
|
|
92
|
+
|
|
93
|
+
# Default settings
|
|
94
|
+
default_stack: generic
|
|
95
|
+
default_profile: standard
|
|
96
|
+
rate_limit: 50
|
|
97
|
+
|
|
98
|
+
# Severity overrides
|
|
99
|
+
# Map template patterns to custom severities
|
|
100
|
+
# Available: critical, high, medium, low, info
|
|
101
|
+
severity_overrides:
|
|
102
|
+
# Dependency files - enables CVE targeting
|
|
103
|
+
composer-config: high
|
|
104
|
+
package-json: high
|
|
105
|
+
|
|
106
|
+
# Credential exposure
|
|
107
|
+
env-file: critical
|
|
108
|
+
dotenv: critical
|
|
109
|
+
git-credentials: critical
|
|
110
|
+
aws-credentials: critical
|
|
111
|
+
|
|
112
|
+
# Source code exposure
|
|
113
|
+
exposed-git: critical
|
|
114
|
+
git-config: high
|
|
115
|
+
|
|
116
|
+
# Architecture disclosure
|
|
117
|
+
phpinfo: high
|
|
118
|
+
docker-compose: medium
|
|
119
|
+
`;
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|