Skip to main content

KnownIssueScan, Known Vulnerability and Secret Detection

KnownIssueScan checks targets for known CVEs, common misconfigurations, and exposed secrets using Nuclei templates and the Kingfisher secret detection engine. It runs after the Discovery phase, leveraging all paths and endpoints discovered in earlier phases to maximize coverage.

Why KnownIssueScan Matters

Many real-world breaches exploit publicly disclosed vulnerabilities (CVEs) that remain unpatched, or secrets accidentally committed to response bodies. KnownIssueScan systematically tests for these known issues across the entire discovered attack surface, catching low-hanging fruit that custom fuzzing-based modules are not designed to detect.

How It Works

Configuration

KnownIssueScan is configured in vigolium-configs.yaml under the known_issue_scan key:

Key Options

Runtime Defaults

These defaults changed in v0.4.5 (was 50 / 100 req/s). They apply when the operator says nothing, and they are this phase’s only protection in that case — the old values opened wide precisely because nobody passed a flag.

Pacing: why this phase is special

known-issue-scan runs Nuclei as an in-process library with its own HTTP stack, so it is the one active phase outside pkg/http.Requester: no per-host AIMD back-off, no proactive WAF pacing, no [waf-block-detected] notice. The failure mode was silent and misleading. An unknown target opened at up to 100 req/s with no way to slow down, the edge started filtering, and the phase returned a thin surface — indistinguishable from a clean target. Nuclei’s SDK exposes no response hook and no runtime-adjustable limiter, so v0.4.5 wires the phase to the shared objects instead:
  • A pre-flight probe per host goes through the shared requester before the phase starts. It is real traffic on the real path, so the block notice, the waf.block event and the limiter’s WAF auto-arm all fire exactly as they do in discovery. A host that answers with a block is dropped from the target list — pushing template traffic through a wall of challenge pages yields nothing and arms the limiter further. A probe error is a transport failure, not a block, and keeps the host.
  • Nuclei’s own concurrency/rate knobs are sized to the limiter’s per-host verdict, taking the minimum across hosts (one invocation drives one engine) and applying the back-off as a ratio so your --rate-limit stays meaningful.
  • A sentinel re-probes while the scan runs and curtails the phase when a majority of hosts start filtering. That mid-run case is the one a pre-flight can’t catch, and the one that silently hollows out results.
Cap this phase alone without capping the ~200 native modules, which pace themselves:
See Pace: per-phase rate limits.

Phase Execution Detail

  1. Queries distinct paths from the database via GetDistinctPaths().
  2. Builds target URLs, either path-enriched (default, enrich_targets: true) or host-level only.
  3. Pre-flight probes each target host through the shared requester; hosts whose edge is already filtering are dropped and reported as waf.block.
  4. Runs Nuclei templates against the surviving targets, with concurrency and rate sized to the per-host limiter verdict.
  5. Runs Kingfisher secret scanning on stored response bodies.
  6. Each finding is saved to the database with ModuleType: "known-issue-scan" and FindingSource: "known-issue-scan".
  7. Post-phase dedup: calls DeduplicateFindings() to group findings with identical (module_id, severity, matched_at URL).
The first run clones the nuclei-templates repository, which takes a while. Since v0.4.5 it announces itself instead of looking like a hung scan, and --templates-dir pins an existing checkout per run so the clone is skipped entirely.

CLI Usage

Run only the KnownIssueScan phase:
Skip the KnownIssueScan phase:

Integration

KnownIssueScan runs as Phase 5 in the native scan pipeline, after Discovery and before Audit. It consumes the HTTP records and discovered paths stored by earlier phases. Its findings are deduplicated before the Audit phase begins, preventing overlap with the active/passive module scanning that follows.