Documentation
¶
Index ¶
- Constants
- func GetTotal(src InputSource) int64
- func IsEOF(err error) bool
- func IsTargetListFormat(name string) bool
- func ParseFileRecords(filePath, formatName string, max int) ([]*httpmsg.HttpRequestResponse, error)
- func SupportedFormatNames() []string
- func SupportedFormats() string
- type ConcurrentMultiSource
- type Countable
- type DeparosDiscoveryConfig
- type DeparosDiscoverySource
- type DiscoveryStats
- type ExternalHarvesterInputSource
- type FileSource
- type FileSourceConfig
- type FormatInfo
- type InputSource
- type MultiSource
- type RecordSaver
- type SingleSource
- type SliceSource
- type SourceConfig
- type StdinSource
- type TargetSource
Constants ¶
const DefaultDiscoveryMaxDuration = 1 * time.Hour
DefaultDiscoveryMaxDuration is the per-target wall-clock budget a discovery target gets when nothing configures one. Exported because the runner's banner and buildDeparosConfig have to report the same number this source will use; when the literal lived only here, the banner printed 0 while targets ran for an hour.
Variables ¶
This section is empty.
Functions ¶
func GetTotal ¶
func GetTotal(src InputSource) int64
GetTotal returns the total count from a source if it implements Countable, otherwise 0.
func IsTargetListFormat ¶
IsTargetListFormat reports whether the given -I/--input-mode name or alias names a format whose file is a list of target URLs. An empty name resolves to the "urls" default, matching resolveFormat; an unknown name is not a target list (resolveFormat rejects it separately).
Callers use it to decide whether a file's contents can be promoted into Options.Targets. It reads the same registry row resolveFormat does, so an alias added there is promoted without a second edit — a hand-copied alias list that missed one would parse the file fine and then leave every target-seeded phase with nothing, which is the bug this predicate exists to prevent.
func ParseFileRecords ¶
func ParseFileRecords(filePath, formatName string, max int) ([]*httpmsg.HttpRequestResponse, error)
ParseFileRecords parses the file at filePath using the named input format and returns the discovered HTTP records. It is the synchronous, pull-everything convenience wrapper over the format registry for callers that just want the records in a slice (e.g. the autopilot knowledge-base traffic loader) rather than the streaming FileSource/Next() API. formatName accepts any canonical name or alias resolveFormat understands ("har", "burpxml", "openapi", …); an unknown name is a hard error. When max > 0 parsing stops after max records. A non-nil parse error is returned alongside whatever records were gathered before it (a partially-parseable file still yields its good records).
func SupportedFormatNames ¶
func SupportedFormatNames() []string
SupportedFormatNames returns the canonical input-format names in display order.
func SupportedFormats ¶
func SupportedFormats() string
SupportedFormats returns a comma-separated list of the canonical input-format names, derived from the single formatRegistry source of truth so it can never drift from the set resolveFormat actually accepts.
Types ¶
type ConcurrentMultiSource ¶
type ConcurrentMultiSource struct {
// contains filtered or unexported fields
}
ConcurrentMultiSource merges multiple InputSources by reading from all concurrently. Unlike MultiSource which drains sources sequentially, ConcurrentMultiSource reads from all sources in parallel via goroutines pushing to a shared channel. This is required when some sources block indefinitely (e.g., queue sources).
func NewConcurrentMultiSource ¶
func NewConcurrentMultiSource(parent context.Context, sources ...InputSource) *ConcurrentMultiSource
NewConcurrentMultiSource creates a ConcurrentMultiSource that reads from all provided sources concurrently.
The reader goroutines are owned by ctx, so cancelling the caller's phase stops them without waiting for Close; a nil ctx means they outlive every caller, which is only ever right in a test. Close still cancels them and closes the children, so a caller that does not own a child source must not call it.
func (*ConcurrentMultiSource) Close ¶
func (cs *ConcurrentMultiSource) Close() error
Close cancels all source goroutines and closes all underlying sources.
type Countable ¶
type Countable interface {
Count() int64
}
Countable is an optional interface for sources that can report total item count.
type DeparosDiscoveryConfig ¶
type DeparosDiscoveryConfig struct {
Targets []string // Target URLs
Concurrency int // Worker threads (from -t flag); default: 25
MaxDuration time.Duration // default: 1h
// RateLimit caps each discovery engine's outgoing requests per second.
// 0 = unpaced (the historical behaviour; Concurrency is then the only
// throttle). Set it only from an EXPLICIT operator setting — see
// buildDeparosConfig in the runner — because imposing the global 100 rps
// default on a crawl changes the speed of every existing scan.
//
// Targets are discovered sequentially, so a per-engine bucket is the
// phase-wide rate.
RateLimit int
EnableModules []string // Module selection for WorkItems
// DrainTimeout bounds how long Close waits for the producer to finish
// persisting what it already collected. <=0 uses defaultDiscoveryDrainTimeout.
DrainTimeout time.Duration
// Full deparos settings (from YAML config)
Mode string // "files_and_dirs" | "files_only" | "dirs_only"
ScopeMode string // "any" | "subdomain" | "exact"
RecursionEnabled bool // default: true
RecursionDepth int // default: 5
SaveResponseBody bool // default: true
// Wordlists
ShortFilePath string
LongFilePath string
ShortDirPath string
LongDirPath string
FuzzWordlistPath string
UseObservedNames bool
UseObservedPaths bool
UseObservedFiles bool
EnableNumericFuzzing bool
// Extensions
TestCustom bool
CustomList []string
TestObserved bool
TestBackupExtensions bool
BackupExtensions []string
TestNoExtension bool
// Confirmation-gated extension fuzzing. When ConfirmRequired is set, a
// server-side extension (php/asp/aspx/jsp/action/cgi/…) is only wordlist-
// fuzzed once the app is confirmed to serve it as a valid route via the
// enabled sources below. Candidates/ProbeFilenames override the built-ins.
ConfirmRequired bool
ConfirmViaObserved bool
ConfirmViaFingerprint bool
ConfirmViaProbe bool
Candidates []string
ProbeFilenames []string
// JSBundleSweep enables the SPA-gated JS-bundle name sweep (main.js,
// admin.js, config.js, …) on monolith apps; hits are fed to jstangle.
// JSBundleNames overrides the curated name list (empty = built-in).
JSBundleSweep bool
JSBundleNames []string
// Engine
CaseSensitivity string // "auto_detect" | "sensitive" | "insensitive"
EngineTimeout time.Duration
CustomHeaders map[string]string
// BrowserSessions carries WAF/bot-cleared sessions harvested by the spidering
// browser, keyed by lowercased hostname. buildDeparosConfig injects the
// session matching each target host (Cookie + optional pinned User-Agent) into
// that target's request headers so content discovery crawls with the same
// cleared session — set-if-absent, so a configured header always wins.
BrowserSessions map[string]httpmsg.CarriedSession
EnableCookieJar bool
ProxyURL string // HTTP proxy URL for discovery requests
MaxConsecutiveErrors int
MaxConsecutiveWAFBlocks int
ObservedMaxItems int
JSTangle *deparosconfig.JSTangleConfig
// Per-prefix circuit breaker (zero values = use deparos defaults).
PrefixBreakerEnabled *bool // nil = default (true)
PrefixBreakerMinSamples int // 0 = default
PrefixBreakerTripRatio float64 // 0 = default
PrefixBreakerPrefixSegments int // 0 = default
PrefixBreakerLengthBucket int64 // 0 = default
// Malformed path probe
EnableMalformedPathProbe bool
// DedupClusterCap caps the number of near-identical responses kept per
// cluster (same host/status/content-type, body size & word count within
// 0.5%). 0 = use default (defaultDedupClusterCap); negative = disabled;
// positive = that cap. Resolved via resolveClusterCap.
DedupClusterCap int
// RequestFilter is the egress policy for every request the discovery engine
// makes: returning false refuses the request before it is sent, instead of
// discarding its response afterwards. The engine also derives its spider-queue
// exclusion from it, so a refused URL is never even queued.
//
// It carries the operator's EXPLICIT denials only (scope.host.exclude /
// scope.path.exclude); how wide the crawl goes is still ScopeMode's job.
// nil = no denials.
RequestFilter func(*url.URL) bool
// DB import: if set, results are saved to vigolium's http_records table
Repository RecordSaver
ProjectUUID string
}
DeparosDiscoveryConfig configures the deparos content discovery source.
type DeparosDiscoverySource ¶
type DeparosDiscoverySource struct {
// contains filtered or unexported fields
}
DeparosDiscoverySource uses the deparos library to discover content, then converts results to input for scanning.
func NewDeparosDiscoverySource ¶
func NewDeparosDiscoverySource(ctx context.Context, cfg DeparosDiscoveryConfig) (*DeparosDiscoverySource, error)
NewDeparosDiscoverySource creates a new DeparosDiscoverySource owned by ctx. Cancelling ctx stops the running engine and skips the remaining targets; a nil ctx means the source outlives every caller, which is only ever right in a test.
func (*DeparosDiscoverySource) Close ¶
func (d *DeparosDiscoverySource) Close() error
Close stops discovery and joins the producer.
The producer is given DrainTimeout to finish persisting what it already collected — those records cost real requests, and throwing them away on a cancel was the point of this change. If it has not exited by then, abort tells it to stop reading the local sitemap too, and after a further grace period the source reports the goroutine as abandoned rather than blocking the phase forever.
Idempotent, and never waits while holding d.mu: the producer takes that lock to record stats, so waiting under it would deadlock the thing we are waiting for.
func (*DeparosDiscoverySource) Next ¶
Next returns the next discovered item. It lazily starts the discovery process on first call.
func (*DeparosDiscoverySource) RequestsSent ¶ added in v0.5.2
func (d *DeparosDiscoverySource) RequestsSent() int64
RequestsSent reports how many HTTP attempts the discovery engines have made so far, retries included. Safe to call at any point in the source's life, from any goroutine.
It exists because deparos owns its own HTTP client: the runner's phase tracker reads a delta on the SHARED requester, which a discovery phase barely touches, so phase.started/progress/finished reported ≈0 requests for a crawl that had sent tens of thousands.
func (*DeparosDiscoverySource) Stats ¶
func (d *DeparosDiscoverySource) Stats() DiscoveryStats
Stats returns the discovery statistics (safe to call after the source is exhausted).
type DiscoveryStats ¶
type DiscoveryStats struct {
TotalDiscovered int
HardDedupRemoved int
FuzzyCappedRemoved int // records dropped by the near-identical cluster cap
ClusterCap int // effective per-cluster cap used (0 = disabled)
Imported int
AllCodes [5]int // index 0=1xx, 1=2xx, 2=3xx, 3=4xx, 4=5xx
DedupedCodes [5]int // status codes of hard-dedup removed records
CappedCodes [5]int // status codes of cluster-capped removed records
// TargetsFailed is the number of targets whose discovery returned an error.
TargetsFailed int
// TargetsTimedOut counts targets that exhausted their own MaxDuration. This
// is designed behavior (per-target time-boxing), not a failure.
TargetsTimedOut int
// TargetsSkipped is the number of targets never attempted because the phase
// was cancelled first.
TargetsSkipped int
// ImportFailed counts records that were collected but could not be persisted.
ImportFailed int
// TargetErrors holds up to maxReportedTargetErrors "<target>: <err>" strings.
TargetErrors []string
// Abandoned is set when Close gave up waiting for the producer to exit.
Abandoned bool
}
DiscoveryStats tracks status code statistics for discovered and deduplicated records.
type ExternalHarvesterInputSource ¶
type ExternalHarvesterInputSource struct {
// contains filtered or unexported fields
}
ExternalHarvesterInputSource adapts the external harvester into an InputSource. It lazily starts harvesting from external intelligence sources on the first Next() call.
func NewExternalHarvesterInputSource ¶
func NewExternalHarvesterInputSource(h *harvester.Harvester, domains []string, enableModules []string) *ExternalHarvesterInputSource
NewExternalHarvesterInputSource creates a new ExternalHarvesterInputSource.
func (*ExternalHarvesterInputSource) Close ¶
func (s *ExternalHarvesterInputSource) Close() error
Close releases resources and stops external harvesting.
type FileSource ¶
type FileSource struct {
// contains filtered or unexported fields
}
FileSource provides lazy-loading input from files using format parsers. It wraps the existing Format interface and converts push-based callback to pull-based Next().
func FirstFileSource ¶
func FirstFileSource(src InputSource) *FileSource
FirstFileSource returns the first *FileSource reachable from src, unwrapping a MultiSource (the shape NewInputSource produces when targets/-t and a file/-i are combined). Returns nil when there is none. Callers use it to configure format-specific options (OpenAPI BaseURL, WSDL endpoint) on the file parser after the source is built — a bare `inputSource.(*FileSource)` misses the parser whenever -t is also present, silently dropping the override.
func NewFileSource ¶
func NewFileSource(cfg FileSourceConfig) (*FileSource, error)
NewFileSource creates a new FileSource for the given file and format.
func (*FileSource) Close ¶
func (f *FileSource) Close() error
Close releases resources and stops parsing.
func (*FileSource) Count ¶
func (f *FileSource) Count() int64
Count returns the total item count if the underlying format supports counting.
func (*FileSource) Format ¶
func (f *FileSource) Format() formats.Format
Format returns the underlying format parser. This allows callers to configure format-specific options after creation.
type FileSourceConfig ¶
type FileSourceConfig struct {
FilePath string
Format string // canonical name or alias from formatRegistry ("urls", "nuclei", "openapi", …)
BufferSize int // Channel buffer size (default: 100)
EnableModules []string
FormatOptions formats.InputFormatOptions
}
FileSourceConfig configures FileSource behavior.
type FormatInfo ¶ added in v0.5.2
type FormatInfo struct {
Name string // canonical -I value
Aliases []string // accepted alternatives, in registry order
TargetList bool // the file is a list of target URLs (see IsTargetListFormat)
}
FormatInfo is the public view of one formatRegistry row: everything a caller outside this package needs to describe an input format, and nothing that would let it construct a parser of its own.
It exists so the CLI's -I help text and `--list-input-mode` table are derived from the registry rather than re-typed beside it. The hand-maintained copy they used to carry had already drifted: it advertised "nuclei-output" as the canonical name with "nuclei" as the alias, which is the reverse of what resolveFormat accepts, and it was missing burpscope's burp-project-config alias entirely.
func Formats ¶ added in v0.5.2
func Formats() []FormatInfo
Formats returns every supported input format in display order. The aliases slice is copied, so a caller cannot mutate the registry through it.
type InputSource ¶
type InputSource interface {
// Next returns the next work item from the source.
// It blocks until an item is available (for queue-based sources).
//
// Returns:
// - (*work.WorkItem, nil) - next item
// - (nil, io.EOF) - source exhausted, no more items
// - (nil, context.Canceled) - context was cancelled
// - (nil, error) - other error occurred
Next(ctx context.Context) (*work.WorkItem, error)
// Close releases any resources held by the source.
// After Close, Next will return io.EOF.
Close() error
}
InputSource provides a stream of work items for scanning. This is a pull-based interface where consumers call Next() to get items. Implementations must be safe for concurrent Next() calls from multiple goroutines.
func NewInputSource ¶
func NewInputSource(cfg SourceConfig) (InputSource, error)
NewInputSource creates appropriate InputSource based on config. Combines multiple sources if needed (e.g., -u flags + -l file + stdin).
type MultiSource ¶
type MultiSource struct {
// contains filtered or unexported fields
}
MultiSource combines multiple InputSource into one. It drains sources in order: exhausts the first source before moving to the next.
func NewMultiSource ¶
func NewMultiSource(sources ...InputSource) *MultiSource
NewMultiSource creates a MultiSource from multiple InputSources.
func (*MultiSource) Close ¶
func (m *MultiSource) Close() error
Close closes all underlying sources.
func (*MultiSource) Count ¶
func (m *MultiSource) Count() int64
Count returns the sum of counts from all sources that implement Countable.
type RecordSaver ¶
type RecordSaver interface {
SaveRecord(ctx context.Context, httpRR *httpmsg.HttpRequestResponse, source string, projectUUID string) (string, error)
SaveRecordBatch(ctx context.Context, records []*httpmsg.HttpRequestResponse, source string, projectUUID string) ([]string, error)
}
RecordSaver persists HTTP request/response pairs to a database. This avoids importing pkg/database directly.
type SingleSource ¶
type SingleSource struct {
// contains filtered or unexported fields
}
SingleSource is an InputSource that yields exactly one WorkItem, then returns io.EOF. Used by scan-url and scan-request commands for single-target scanning.
func NewSingleSource ¶
func NewSingleSource(rr *httpmsg.HttpRequestResponse, enableModules []string) *SingleSource
NewSingleSource creates a SingleSource from a single HttpRequestResponse.
func (*SingleSource) Close ¶
func (s *SingleSource) Close() error
Close is a no-op for SingleSource.
func (*SingleSource) Count ¶
func (s *SingleSource) Count() int64
Count returns 1 (implements Countable).
type SliceSource ¶
type SliceSource struct {
// contains filtered or unexported fields
}
SliceSource is an InputSource that yields work items from a slice of HttpRequestResponse. Implements InputSource and Countable.
func NewSliceSource ¶
func NewSliceSource(items []*httpmsg.HttpRequestResponse, enableModules []string) *SliceSource
NewSliceSource creates a SliceSource from a slice of HttpRequestResponse items.
func (*SliceSource) Count ¶
func (s *SliceSource) Count() int64
Count returns the number of items in the source (implements Countable).
type SourceConfig ¶
type SourceConfig struct {
// Direct targets (from -u flag)
Targets []string
// File-based input. FilePath is a single input file (e.g. -i/--input).
// FilePaths carries additional files (e.g. repeated -T/--target-file); every
// listed file is read and its items merged into the stream.
FilePath string
FilePaths []string
Format string // "urls", "nuclei", "openapi", etc.
// Stdin
UseStdin bool
Stdin io.Reader // defaults to os.Stdin
// Format options
SkipFormatValidation bool
FormatUseRequiredOnly bool
// Buffer size for channels
BufferSize int
// EnableModules for per-item module filtering (from -m flag)
EnableModules []string
}
SourceConfig holds configuration for creating an InputSource.
type StdinSource ¶
type StdinSource struct {
// contains filtered or unexported fields
}
StdinSource reads URLs line-by-line from a reader (typically stdin).
func NewStdinSource ¶
func NewStdinSource(reader io.Reader, enableModules []string) *StdinSource
NewStdinSource creates a StdinSource from an io.Reader.
type TargetSource ¶
type TargetSource struct {
// contains filtered or unexported fields
}
TargetSource provides input from direct URL targets (from -u flag).
func NewTargetSource ¶
func NewTargetSource(targets []string, enableModules []string) *TargetSource
NewTargetSource creates a TargetSource from a slice of URLs.
func (*TargetSource) Count ¶
func (t *TargetSource) Count() int64
Count returns the total number of targets (known upfront).