@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.
Files changed (59) hide show
  1. package/README.md +198 -0
  2. package/dist/aggregator.d.ts +65 -0
  3. package/dist/aggregator.d.ts.map +1 -0
  4. package/dist/aggregator.js +546 -0
  5. package/dist/aggregator.js.map +1 -0
  6. package/dist/categories.d.ts +59 -0
  7. package/dist/categories.d.ts.map +1 -0
  8. package/dist/categories.js +278 -0
  9. package/dist/categories.js.map +1 -0
  10. package/dist/cli.d.ts +12 -0
  11. package/dist/cli.d.ts.map +1 -0
  12. package/dist/cli.js +457 -0
  13. package/dist/cli.js.map +1 -0
  14. package/dist/config.d.ts +19 -0
  15. package/dist/config.d.ts.map +1 -0
  16. package/dist/config.js +121 -0
  17. package/dist/config.js.map +1 -0
  18. package/dist/coverage.d.ts +49 -0
  19. package/dist/coverage.d.ts.map +1 -0
  20. package/dist/coverage.js +165 -0
  21. package/dist/coverage.js.map +1 -0
  22. package/dist/enrichers/nvd.d.ts +55 -0
  23. package/dist/enrichers/nvd.d.ts.map +1 -0
  24. package/dist/enrichers/nvd.js +326 -0
  25. package/dist/enrichers/nvd.js.map +1 -0
  26. package/dist/report.d.ts +12 -0
  27. package/dist/report.d.ts.map +1 -0
  28. package/dist/report.js +460 -0
  29. package/dist/report.js.map +1 -0
  30. package/dist/runners/nuclei.d.ts +59 -0
  31. package/dist/runners/nuclei.d.ts.map +1 -0
  32. package/dist/runners/nuclei.js +531 -0
  33. package/dist/runners/nuclei.js.map +1 -0
  34. package/dist/runners/testssl.d.ts +16 -0
  35. package/dist/runners/testssl.d.ts.map +1 -0
  36. package/dist/runners/testssl.js +179 -0
  37. package/dist/runners/testssl.js.map +1 -0
  38. package/dist/runners/zap.d.ts +30 -0
  39. package/dist/runners/zap.d.ts.map +1 -0
  40. package/dist/runners/zap.js +389 -0
  41. package/dist/runners/zap.js.map +1 -0
  42. package/dist/types.d.ts +172 -0
  43. package/dist/types.d.ts.map +1 -0
  44. package/dist/types.js +6 -0
  45. package/dist/types.js.map +1 -0
  46. package/package.json +54 -0
  47. package/templates/drupal-api-index-exposed.yaml +81 -0
  48. package/templates/drupal-api-user-detail.yaml +76 -0
  49. package/templates/drupal-api-user-listing.yaml +59 -0
  50. package/templates/drupal-dev-files-exposed.yaml +73 -0
  51. package/templates/drupal-file-path-disclosure.yaml +59 -0
  52. package/templates/drupal-files-listing.yaml +63 -0
  53. package/templates/drupal-install-error-disclosure.yaml +62 -0
  54. package/templates/drupal-theme-lockfiles.yaml +79 -0
  55. package/templates/drupal-version-detect.yaml +89 -0
  56. package/templates/http-options-enabled.yaml +56 -0
  57. package/templates/nextjs-version-detect.yaml +35 -0
  58. package/templates/php-version-detect.yaml +37 -0
  59. 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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -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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"}