verify

package
v0.5.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 18, 2026 License: MIT Imports: 22 Imported by: 0

Documentation

Overview

Package verify re-runs the module behind a stored finding against its target and reports whether the finding reproduces (`vigolium finding verify`).

A run has two halves. Reconstruct rebuilds what the module originally saw — the module, the baseline request it scanned and the insertion point it mutated — from the finding row: the replay columns first (origin_record_uuid, insertion_point), legacy heuristics second. Run then drives a one-item executor (no store, no dedup, a single module, the point filter) and turns its results into a verdict. Writing the verdict and any status change is the caller's job.

Index

Constants

View Source
const (
	// BaselineOriginRecord: findings.origin_record_uuid, written by the
	// executor since schema v3.
	BaselineOriginRecord = "origin_record"
	// BaselineLinkedRecord: the finding's linked http_record is a scanned
	// record (not the finding's own evidence), so it is what the module saw.
	BaselineLinkedRecord = "linked_record"
	// BaselineMatchedRecord: a scanned record on the same host, method and path
	// that differs from the finding's request in exactly one insertion point.
	BaselineMatchedRecord = "matched_record"
	// BaselineFindingRequest: the request stored on the finding itself (a
	// passive finding without a loadable record).
	BaselineFindingRequest = "finding_request"
)

Baseline sources, reported in Plan.Baseline.Source.

View Source
const (
	PointStored    = "stored"          // findings.insertion_point
	PointDiffering = "differing_point" // the one point where baseline and finding request differ
)

Insertion-point sources, reported in Plan.InsertionPointSource.

View Source
const DefaultTimeout = 2 * time.Minute

DefaultTimeout is the default bound on verifying one finding.

View Source
const ExtensionModulePrefix = "ext-"

ExtensionModulePrefix starts the ID of every JS/YAML extension module.

View Source
const HTTPTimeout = 15 * time.Second

HTTPTimeout caps one request of a verification; RunOptions.Timeout bounds the whole run.

Variables

This section is empty.

Functions

func DefaultModuleResolver

func DefaultModuleResolver(id string) modules.Module

DefaultModuleResolver looks the id up in the built-in registries.

func LoadExtensionModules

func LoadExtensionModules(cfg *config.ExtensionsConfig, requester *http.Requester) (map[string]modules.Module, error)

LoadExtensionModules loads the JS/YAML extensions cfg names and returns their modules by ID (active first when an ID is both).

func MarkStatus

func MarkStatus(verdict string) string

MarkStatus is the lifecycle status a verdict moves a finding to under RecordOptions.Mark ("" = none).

func NeedsExtensions

func NeedsExtensions(findings ...*database.Finding) bool

NeedsExtensions reports whether any finding was reported by an ext-* module.

func Record

func Record(ctx context.Context, repo *database.Repository, projectUUID string, f *database.Finding, res *Result, opts RecordOptions)

Record stores res's verdict on finding f (scoped to projectUUID) and, under opts.Mark, the status it implies. A failed write is reported in res.Reason; res.Written and res.Status say what landed.

Types

type Baseline

type Baseline struct {
	Source     string `json:"source"`
	RecordUUID string `json:"record_uuid,omitempty"`
	Method     string `json:"method,omitempty"`
	URL        string `json:"url,omitempty"`
	// Request is the raw baseline request, filled for --dry-run output.
	Request string `json:"request,omitempty"`
}

Baseline describes the request the module will be run against.

type HTTPConfig

type HTTPConfig struct {
	ProxyURL    string
	Verbose     bool
	Debug       bool
	DumpTraffic bool
	// Timeout is the run's bound; one request gets the smaller of it and
	// HTTPTimeout.
	Timeout time.Duration
	// RateLimit is requests/second across the verification (0 = unlimited;
	// fractions allowed).
	RateLimit float64
}

HTTPConfig configures NewHTTPStack.

type HTTPStack

type HTTPStack = httpstack.Stack

HTTPStack is the requester a verification runs modules with, behind an egress gate so the request count can be reported. Close releases it.

func NewHTTPStack

func NewHTTPStack(cfg HTTPConfig) (*HTTPStack, error)

NewHTTPStack builds the HTTP stack for a verification. It takes a reference on the process network dialer (network.Init) that Close returns.

type ModuleResolver

type ModuleResolver func(id string) modules.Module

ModuleResolver returns the module with the given id, or nil when no such module is loaded. The CLI wraps DefaultModuleResolver to add ext-* modules loaded from --ext.

func Resolver

func Resolver(loadExt func() map[string]modules.Module) ModuleResolver

Resolver returns a ModuleResolver over the built-in registries plus ext, asking loadExt for the extension modules on the first ext-* lookup only. A nil loadExt (or one returning nil) leaves ext-* modules unresolved, which Reconstruct reports as unsupported.

type Plan

type Plan struct {
	FindingID   int64  `json:"id"`
	FindingHash string `json:"finding_hash"`
	ModuleID    string `json:"module_id"`
	ModuleType  string `json:"module_type,omitempty"` // active | passive

	Baseline             *Baseline                       `json:"baseline,omitempty"`
	InsertionPoint       *database.FindingInsertionPoint `json:"insertion_point,omitempty"`
	InsertionPointSource string                          `json:"insertion_point_source,omitempty"`
	Payload              string                          `json:"payload,omitempty"`
	// Network is true when running the plan sends requests to the target.
	Network bool `json:"network"`

	// Verdict is set when reconstruction already decides the outcome
	// (unsupported, or inconclusive for lack of a baseline); Run returns it
	// without executing anything.
	Verdict string `json:"-"`
	Reason  string `json:"-"`
	// contains filtered or unexported fields
}

Plan is a reconstructed finding: what verify will run, or why it will not.

func Reconstruct

func Reconstruct(ctx context.Context, repo *database.Repository, projectUUID string, f *database.Finding, resolve ModuleResolver) *Plan

Reconstruct rebuilds the plan for one finding. repo may be nil, in which case only the request stored on the finding is available.

func (*Plan) NeedsNetwork

func (p *Plan) NeedsNetwork(refetch bool) bool

NeedsNetwork reports whether running p sends requests: an active module, or a passive one asked to refetch.

type RecordOptions

type RecordOptions struct {
	// Mark also moves the lifecycle status: not_reproduced → false_positive,
	// confirmed → confirmed, through the audited status path.
	Mark bool
	// Actor is recorded on a status change Mark makes.
	Actor string
	// ModuleVersion is stored with the verdict (the binary's version).
	ModuleVersion string
}

RecordOptions configures Record.

type Result

type Result struct {
	ID          int64  `json:"id"`
	FindingHash string `json:"finding_hash"`
	ModuleID    string `json:"module_id"`
	Verdict     string `json:"verdict"`
	Reason      string `json:"reason,omitempty"`

	Plan *Plan `json:"plan,omitempty"`

	// Results counts what the re-run module reported; Matched how many of
	// those are this finding.
	Results    int   `json:"results"`
	Matched    int   `json:"matched"`
	Requests   int64 `json:"requests"`
	DurationMs int64 `json:"duration_ms"`

	// Written is true once the verdict is stored on the finding; Status is the
	// status change --mark made, when it made one.
	Written bool                          `json:"written"`
	Status  *database.FindingStatusChange `json:"status_change,omitempty"`
}

Result is one finding's verify outcome: the JSON item `finding verify -j` emits.

func DryRun

func DryRun(plan *Plan, refetch bool) *Result

DryRun returns the result a dry run reports for plan: the reconstruction, with nothing sent and nothing written.

func Run

func Run(ctx context.Context, p *Plan, opts RunOptions) *Result

Run executes a reconstructed plan and returns the verdict. It writes nothing.

type RunOptions

type RunOptions struct {
	// Requester and Services carry the HTTP stack. Services may be nil; a
	// fresh dedup manager is used per run either way so one finding's
	// module-internal dedup never hides another's.
	Requester *http.Requester
	Services  *services.Services
	// Refetch makes a passive verify fetch a fresh response instead of
	// re-reading the stored one (the default sends nothing).
	Refetch bool
	// Timeout bounds one finding's run (0 = no bound beyond the module's own).
	Timeout time.Duration
}

RunOptions configures Run.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL