Documentation
¶
Index ¶
- Constants
- Variables
- func ApplyNativePhaseSelection(opts *types.Options, enableExtensions func()) error
- func FormatBlockNoticeLine(n http.BlockNotice) string
- func FormatEdgePaceLine(n hostlimit.PreArmNotice) string
- func IsNativePhaseSpelling(s string) bool
- func IsProbeOnlyRun(opts *types.Options) bool
- func NormalizeNativePhase(phase string) string
- func OnlyPhaseSet(raw string) map[string]bool
- func PhaseNamesDesc(skippableOnly bool) string
- func PhaseVocabularyLines(skippableOnly bool) []string
- func SpiderFanOutReason(targetCount int) string
- func SpiderFanOutSuggestion(opts *types.Options, targetCount int) (flags string, ok bool)
- type HeuristicsResult
- type LaunchParams
- type LaunchResult
- type NativePhase
- type NativePhaseStep
- type NativeScanPlan
- type PhaseSpelling
- type Runner
- func (r *Runner) Close()
- func (r *Runner) Discard()
- func (r *Runner) Finalized() bool
- func (r *Runner) IsPaused() bool
- func (r *Runner) Pause()
- func (r *Runner) Resume()
- func (r *Runner) RunNativeScan() (err error)
- func (r *Runner) ScanLogger() *database.ScanLogger
- func (r *Runner) SetRepository(repo *database.Repository)
- func (r *Runner) SetSettings(s *config.Settings)
- func (r *Runner) SetSharedInfra(infra *SharedInfra)
- type SharedInfra
Constants ¶
const ( NoticeMarkerBlock = "[waf-block-detected]" NoticeMarkerPacing = "[waf-pacing-armed]" )
FormatBlockNoticeLine renders the one-line WAF/CDN block warning (with a trailing newline) shown when the edge starts filtering scan traffic. It is shared by every scan front-end so the message and the "unrecognized vendor" fallback stay identical whether the scan runs through the Runner or the direct scan-url/scan-request path. NoticeMarkerBlock and NoticeMarkerPacing are the bracketed tags the two operator notices are rendered with. Exported because a reader has to find them again in a rendered log (`vigolium log` reprints any that fell above the tail window) — matching on the marker rather than the prose is deliberate, since the prose is a sentence that gets reworded and the marker is what it tags.
Variables ¶
var ( ValidOnlyPhasesDesc = phaseVocabularyDesc(false) ValidSkipPhasesDesc = phaseVocabularyDesc(true) )
ValidOnlyPhasesDesc and ValidSkipPhasesDesc are the human-readable phase lists rendered in --only/--skip validation error messages. Derived from nativePhaseVocabulary rather than hand-written, so a spelling that works can never go unlisted and a listed one can never fail to resolve.
Functions ¶
func FormatBlockNoticeLine ¶
func FormatBlockNoticeLine(n http.BlockNotice) string
func FormatEdgePaceLine ¶
func FormatEdgePaceLine(n hostlimit.PreArmNotice) string
FormatEdgePaceLine renders the one-line notice shown when a host is fingerprinted behind a CDN/WAF edge and its active-scan concurrency is proactively paced to keep a burst from arming a rate-based WAF. It spells out the concurrency drop so the operator understands the scan will run slower against that host. Companion to FormatBlockNoticeLine — a caution, not a failure: the scan continues, just gentler.
func IsNativePhaseSpelling ¶
IsNativePhaseSpelling reports whether s names a native scan phase under any accepted spelling. Callers that need to branch on "is this a phase?" ask here rather than re-listing spellings, so a new alias reaches them for free.
func IsProbeOnlyRun ¶
IsProbeOnlyRun reports whether this invocation is a standalone host sweep: `vigolium run probe`, `scan --only probe`, or REST {"only":"probe"}.
The probe's own defaults apply only here. When the phase rides along inside a full scan, the scan's redirect and recording policy governs — silently swapping it out from under the other phases would be a surprise.
func NormalizeNativePhase ¶
NormalizeNativePhase maps every accepted spelling of a phase to its canonical id. Input is trimmed and lowercased first: --only already trimmed, --skip did not, so `--skip Discovery` (or ` discovery`) reached the switch verbatim, fell through to default, and was reported as an invalid phase. Aliases are extra surface for a driver to get subtly wrong; normalizing here means every caller — --only, --skip, `run <phase>`, the pace-flag qualifiers, and the scan.started event's canonical phase list — agrees on what a spelling means.
func OnlyPhaseSet ¶
OnlyPhaseSet returns the set of normalized phases listed in a comma-separated --only value. Callers use it to gate behavior that depends on which phases are active (e.g. validating that --format=html was scoped to phases that produce a report). Returns nil for empty input.
func PhaseNamesDesc ¶
PhaseNamesDesc renders the canonical phase ids alone, comma-separated. Flag help uses this (the full alias vocabulary is too long for one --help line); the error a wrong value produces quotes ValidOnlyPhasesDesc/ValidSkipPhasesDesc instead, which spells every accepted alias out.
func PhaseVocabularyLines ¶
PhaseVocabularyLines renders one "canonical (alias, alias)" entry per phase, for help text that lists them vertically. skippableOnly restricts it to the phases --skip accepts. Returned as lines rather than a joined string because the alias lists are themselves comma-separated — splitting the flat form on ", " to lay it out would break entries apart mid-list.
func SpiderFanOutReason ¶
SpiderFanOutReason states why a serial crawl is the wrong shape for this target list. Two readings of the same fact: past the budget cap the ceiling is the headline — targets are dropped outright — while below it the only cost is wall clock. Telling an operator with 2 targets that "most won't be reached" is untrue, and a hint that overstates once is discounted from then on.
Rendered here rather than in pkg/cli so it reads spideringPhaseBudgetCap directly: a hardcoded figure in the message would keep printing the old budget after the cap moved, and the operator sizes their fan-out against it.
func SpiderFanOutSuggestion ¶
SpiderFanOutSuggestion returns the flags that would fan a multi-target spidering run out across child processes, and whether the suggestion applies.
It exists because spidering is the one phase where the pace flags cannot help. It drives a browser rather than the executor, so -c/--concurrency (the executor's worker count) never reaches it, and its host loop is strictly serial — one crawl at a time, whatever the flags say. On top of that the phase stops after SpideringPhaseBudgetCap targets' worth of budget, so a long -T list is not merely slow, most of it is never reached: an operator who asked for 682 hosts gets about eight and a skip warning at the end. The only real parallelism available is the -P fan-out, which runs each target as its own process with its own browser and its own ceiling.
Every condition here mirrors one the -P fan-out itself enforces, because a hint naming a command that gets rejected — or silently degraded back to one serial scan — is worse than no hint. validateParallelScan admits -P > 1 only under --db-isolate or -S --split-by-host (anything else would share a database or an output file across concurrent scans), rejects --db-isolate alongside -S outright, and needs a -T file to split in the first place: a -t-only or piped run has nothing to fan out and is warned back down to Parallel = 1. Flags already present are not repeated back.
Lives here rather than in pkg/cli because both the pre-scan banner hint and the phase's own ceiling-reached line quote it, and pkg/cli imports this package (not the reverse) — one owner, so the two can never suggest different flags.
Types ¶
type HeuristicsResult ¶
type HeuristicsResult struct {
Target string
StatusCode int16
ContentType string // "blank", "html", "json", "xml", "text"
BodyLength int
LinkCount int // advanced only
IsSPA bool // advanced only
SkipSpidering bool
Reason string
}
HeuristicsResult holds the analysis of a single target's root page.
type LaunchParams ¶
type LaunchParams struct {
// Targets lists URLs / file paths the scan should ingest. Required.
Targets []string
// ProjectUUID scopes the scan. Empty leaves it unscoped — the same
// behavior as `vigolium scan-url` without --project.
ProjectUUID string
// Modules optionally narrows the active-module set. Empty = no
// restriction (CLI default).
Modules []string
// PassiveModules narrows the passive set. Empty = ["all"].
PassiveModules []string
// ExtensionPaths supplies extra JS extension files to load alongside
// any built-ins. Each path is appended to ExtensionsConfig.CustomDir
// before the runner builds its phase infra.
ExtensionPaths []string
// ExtensionsOnly skips all built-in Go modules; runs only JS
// extensions. Used by run_extension when the agent wants its supplied
// script to run in isolation.
ExtensionsOnly bool
// ScanningStrategy selects a named strategy ("lite", "balanced",
// "deep"). Empty inherits the settings default.
ScanningStrategy string
// ScanMaxDuration caps total wall-clock time for the whole native scan.
// Zero leaves the scan unbounded (it runs until ctx cancellation) — which
// is a foot-gun for library callers like the autopilot pre-scan that share
// a long-lived ctx: an unbounded scan will consume the entire budget and
// starve whatever runs after it. Set a bounded value for such callers.
ScanMaxDuration time.Duration
// EnableDiscovery turns on the discovery phase. Default false — most
// agent invocations want a targeted dynamic-assessment-only scan.
EnableDiscovery bool
// EnableSpidering turns on browser-based spidering. Default false.
EnableSpidering bool
// ConfigPath overrides the path to vigolium-configs.yaml. Empty =
// default search order.
ConfigPath string
// Repository is the DB handle used for persistence and final result
// readback. Nil is allowed — the scan still runs but results aren't
// persisted and LaunchResult fields will be zero.
Repository *database.Repository
// Concurrency overrides the worker count. 0 = settings default.
Concurrency int
// OnlyPhase, when non-empty, isolates one or more phases via the same
// comma-separated syntax `vigolium scan --only` accepts (e.g.
// "discovery", "dynamic-assessment", "discovery,dynamic-assessment").
// Phase aliases (deparos, dast, ext, etc.) are accepted and normalized.
// Empty preserves the default phase plan derived from settings.
OnlyPhase string
// SkipPhases disables one or more phases while keeping the rest of the
// plan intact. Mutually exclusive with OnlyPhase. Same alias normalization.
SkipPhases []string
// SkipIngestion skips the discovery ingestion phase. When you've already
// got records in the project and just want to (re)run dynamic-assessment
// against them, set this true and the runner will scan existing records
// instead of crawling new ones.
SkipIngestion bool
}
LaunchParams configures a one-shot scan started from a library caller. The intended consumer is the olium agent's run_scan / run_extension tools — anything that wants to drive a scan without rebuilding the full CLI option matrix. Only Targets is required; the rest fall back to sensible defaults.
type LaunchResult ¶
type LaunchResult struct {
ScanUUID string
Status string
FindingCount int64
TotalRequests int64
Critical int64
High int64
Medium int64
Low int64
Info int64
Suspect int64
DurationMs int64
}
LaunchResult summarizes a completed scan. Populated from the Scan DB row after RunNativeScan returns. When Repository is nil at launch time, only ScanUUID and DurationMs are populated.
func LaunchScan ¶
func LaunchScan(ctx context.Context, params LaunchParams) (*LaunchResult, error)
LaunchScan runs a single scan synchronously. Blocks until RunNativeScan returns (success, failure, or ctx cancellation).
The scan UUID is generated up-front so callers can correlate post-hoc even if the run errors before any work is recorded — the UUID is real and queryable from the moment LaunchScan is invoked.
type NativePhase ¶
type NativePhase string
const ( PhaseHeuristicsCheck NativePhase = "heuristics-check" PhasePortSweep NativePhase = "port-sweep" PhaseExternalHarvest NativePhase = "external-harvest" PhaseSpidering NativePhase = "spidering" PhaseProbe NativePhase = "probe" PhaseDiscovery NativePhase = "discovery" PhaseTargetedReSpider NativePhase = "targeted-respider" PhaseSeed NativePhase = "seed" PhaseKnownIssueScan NativePhase = "known-issue-scan" PhaseDynamicAssessment NativePhase = "dynamic-assessment" )
type NativePhaseStep ¶
type NativePhaseStep struct {
Phase NativePhase
Enabled bool
}
type NativeScanPlan ¶
type NativeScanPlan struct {
Steps []NativePhaseStep
}
func BuildNativeScanPlan ¶
func BuildNativeScanPlan(opts *types.Options) NativeScanPlan
type PhaseSpelling ¶
type PhaseSpelling struct {
Canonical string `json:"canonical"`
Aliases []string `json:"aliases,omitempty"`
Skippable bool `json:"skippable"`
}
PhaseSpelling is the public projection of one vocabulary entry, for callers that need the structure rather than a rendered line — notably the machine output of `vigolium strategy`, which is how a caller discovers what --only and --skip accept without parsing help text.
func PhaseVocabulary ¶
func PhaseVocabulary() []PhaseSpelling
PhaseVocabulary returns the accepted phase spellings, derived from the same single table every other consumer reads. Building the machine list here rather than restating it in pkg/cli is what keeps a new phase from being runnable but undiscoverable.
type Runner ¶
type Runner struct {
// contains filtered or unexported fields
}
Runner is a client for running the enumeration process.
func NewWithInputSource ¶
NewWithInputSource creates a new Runner with a custom InputSource. Used by server mode to provide queue-based input.
func (*Runner) Close ¶
func (r *Runner) Close()
Close cancels the run, waits (bounded) for RunNativeScan to finish, then releases resources. Safe to call concurrently and repeatedly — a stop handler and the background-completion path can both call it, so the resource release (which decrements the process-global network dialer refcount) is guarded by sync.Once to avoid a double teardown of the shared dialer.
func (*Runner) Discard ¶
func (r *Runner) Discard()
Discard releases a runner's resources without waiting for RunNativeScan. Used when a scan is rejected (queue full / project busy) before it ever starts: r.done is never closed in that case, so a normal Close would block for the full shutdown timeout. Shares closeOnce with Close so the network refcount is released exactly once.
func (*Runner) Finalized ¶
Finalized reports whether RunNativeScan already wrote the scan's terminal status. The API server uses this so its safety-net CompleteScan only runs when the runner never reached its finalizer (e.g. infrastructure setup failed), avoiding a second write that would clobber the runner's truthful outcome.
func (*Runner) Resume ¶
func (r *Runner) Resume()
Resume unblocks paused workers and continues scan processing.
func (*Runner) RunNativeScan ¶
RunNativeScan orchestrates the native scan plan:
HeuristicsCheck — optional root-page probe to optimize downstream phase selection ExternalHarvest — harvest URLs from external intelligence sources (opt-in) Spidering — browser-based crawling (opt-in) Discovery — ingest all input + deparos content discovery into DB (no modules) Seed — ingest CLI targets when discovery is skipped but DB-backed phases still need records KnownIssueScan — nuclei + secret scan (opt-in via --known-issue-scan) DynamicAssessment — modules + extensions scan DB records
func (*Runner) ScanLogger ¶
func (r *Runner) ScanLogger() *database.ScanLogger
ScanLogger returns the scan logger (may be nil if no repository is set).
func (*Runner) SetRepository ¶
func (r *Runner) SetRepository(repo *database.Repository)
SetRepository sets the database repository for storing scan results
func (*Runner) SetSettings ¶
SetSettings sets the configuration settings for notifications and other YAML-based config
func (*Runner) SetSharedInfra ¶
func (r *Runner) SetSharedInfra(infra *SharedInfra)
SetSharedInfra allows the runner to reuse pre-built infrastructure instead of building fresh.
type SharedInfra ¶
type SharedInfra struct {
}
SharedInfra holds reusable infrastructure components that can be shared across multiple scan runs (e.g., rescans in agent swarm mode). This avoids rebuilding expensive resources like HTTP requesters and scope matchers for each rescan.
func BuildSharedInfra ¶
func BuildSharedInfra(opts *types.Options, settings *config.Settings, repo *database.Repository) (*SharedInfra, error)
BuildSharedInfra creates a SharedInfra from the given options and settings. It extracts the reusable portions of buildInfrastructure.
func (*SharedInfra) Close ¶
func (s *SharedInfra) Close()
Close releases resources held by SharedInfra.
Source Files
¶
- extension_llm.go
- finding_grouper.go
- heuristics.go
- launch.go
- module_tiers.go
- native_plan.go
- port_sweep.go
- respider_eval.go
- runner.go
- runner_browser_auth.go
- runner_events.go
- runner_modules.go
- runner_output.go
- runner_phase_discovery.go
- runner_phase_probe.go
- runner_phase_respider.go
- runner_phases.go
- runner_sessions.go
- runner_targets.go
- spider_fanout.go
- tee_writer.go