cipher-security 2.0.4 → 2.0.5

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.
@@ -361,7 +361,10 @@ class NucleiRunner {
361
361
  if (effTags.length) cmd.push('-tags', effTags.join(','));
362
362
  if (effSev.length) cmd.push('-severity', effSev.join(','));
363
363
  cmd.push('-rl', String(sp.rateLimit), '-bs', String(sp.bulkSize));
364
+ if (sp.concurrency) cmd.push('-c', String(sp.concurrency));
365
+ if (sp.requestTimeout) cmd.push('-timeout', String(sp.requestTimeout));
364
366
  if (sp.headless) cmd.push('-headless');
367
+ if (sp.extraArgs) cmd.push(...sp.extraArgs);
365
368
 
366
369
  return this._execute(cmd, target, opts.timeout ?? DEFAULT_TIMEOUT);
367
370
  }
@@ -374,14 +377,75 @@ class NucleiRunner {
374
377
  * @param {number} [opts.timeout=600]
375
378
  * @returns {Promise<ScanResult>}
376
379
  */
380
+ /**
381
+ * Run Nuclei with explicit template paths (synchronous — for quick scans).
382
+ * Uses execFileSync to avoid Go pipe-buffering issues with spawn.
383
+ * @param {string} target
384
+ * @param {object} opts
385
+ * @param {string[]} [opts.templatePaths]
386
+ * @param {number} [opts.timeout=30]
387
+ * @param {number} [opts.rateLimit=150]
388
+ * @param {number} [opts.concurrency=25]
389
+ * @param {number} [opts.requestTimeout=10]
390
+ * @returns {Promise<ScanResult>}
391
+ */
377
392
  scanWithTemplates(target, opts = {}) {
378
393
  if (!this.available) return Promise.resolve(this._fail(target));
379
394
  const bin = this._resolved || this.nucleiPath;
380
- const cmd = [bin, '-jsonl', '-silent', '-u', target];
395
+ const args = ['-jsonl', '-silent', '-u', target];
381
396
  for (const tp of opts.templatePaths ?? []) {
382
- cmd.push('-t', tp);
397
+ args.push('-t', tp);
398
+ }
399
+ args.push('-rl', String(opts.rateLimit ?? 150));
400
+ args.push('-c', String(opts.concurrency ?? 25));
401
+ args.push('-timeout', String(opts.requestTimeout ?? 10));
402
+
403
+ const start = Date.now();
404
+ try {
405
+ const out = execFileSync(bin, args, {
406
+ encoding: 'utf-8',
407
+ timeout: (opts.timeout ?? 30) * 1000,
408
+ maxBuffer: 50 * 1024 * 1024,
409
+ stdio: ['pipe', 'pipe', 'pipe'],
410
+ });
411
+ const elapsed = (Date.now() - start) / 1000;
412
+ const findings = [];
413
+ for (const line of out.split('\n')) {
414
+ if (line.startsWith('{')) {
415
+ try { findings.push(Finding.fromNucleiJson(JSON.parse(line))); }
416
+ catch { /* skip parse errors */ }
417
+ }
418
+ }
419
+ const sevCounts = {};
420
+ for (const f of findings) sevCounts[f.severity] = (sevCounts[f.severity] || 0) + 1;
421
+ return Promise.resolve(new ScanResult({
422
+ target, findings,
423
+ stats: { total: findings.length, ...sevCounts },
424
+ command: `${bin} ${args.join(' ')}`,
425
+ durationSeconds: Math.round(elapsed * 100) / 100,
426
+ success: true,
427
+ }));
428
+ } catch (err) {
429
+ const elapsed = (Date.now() - start) / 1000;
430
+ const timedOut = err.killed || err.signal === 'SIGTERM';
431
+ // Even on timeout, capture any partial output
432
+ const out = err.stdout || '';
433
+ const findings = [];
434
+ for (const line of out.split('\n')) {
435
+ if (line.startsWith('{')) {
436
+ try { findings.push(Finding.fromNucleiJson(JSON.parse(line))); }
437
+ catch { /* skip */ }
438
+ }
439
+ }
440
+ return Promise.resolve(new ScanResult({
441
+ target, findings,
442
+ stats: { total: findings.length },
443
+ errors: timedOut ? [`Scan timed out after ${opts.timeout ?? 30}s`] : [err.message],
444
+ command: `${bin} ${args.join(' ')}`,
445
+ durationSeconds: Math.round(elapsed * 100) / 100,
446
+ success: !timedOut && findings.length > 0,
447
+ }));
383
448
  }
384
- return this._execute(cmd, target, opts.timeout ?? DEFAULT_TIMEOUT);
385
449
  }
386
450
 
387
451
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cipher-security",
3
- "version": "2.0.4",
3
+ "version": "2.0.5",
4
4
  "description": "CIPHER — AI Security Engineering Platform CLI",
5
5
  "type": "module",
6
6
  "engines": {