scout

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jan 31, 2026 License: MIT Imports: 10 Imported by: 0

README

go-appsec/scout

license Build Status

A lightweight Go library for passive reconnaissance of domains, discovering subdomains and URLs by querying public APIs. Scout provides a minimal, dependency-light approach to target enumeration for security testing.

Features

  • Ergonomic iterator-based API
  • Concurrent source querying with configurable parallelism
  • Automatic deduplication across all sources
  • Context-aware with timeout support
  • Minimal dependencies

Supported Result Types

Scout can discover:

Type Description
Subdomains Subdomains of the target domain (e.g., api.example.com)
URLs Full URLs under the target domain (e.g., https://example.com/path)

Quick Start

go get github.com/go-appsec/scout@latest
package main

import (
    "context"
    "fmt"

    "github.com/go-appsec/scout"
)

func main() {
    ctx := context.Background()

    // Query all subdomain sources for a domain
    for sub, err := range scout.Subdomains(ctx, "example.com") {
        if err != nil {
            // Ignore or handle errors, usually rate limits
            continue
        }
        fmt.Println(sub)
    }
}

Usage Examples

Query All Sources
ctx := context.Background()

// Get both subdomains and URLs from all sources
for result, err := range scout.Query(ctx, "example.com") {
    if err != nil {
        // Ignore or handle errors, usually rate limits
        continue
    }
    fmt.Printf("[%s] %s: %s\n", result.Source, result.Type, result.Value)
}
Query URLs Only
// Get only URLs from URL-yielding sources
for url, err := range scout.URLs(ctx, "example.com") {
    if err == nil {
        fmt.Println(url)
    }
}
Parallelism and Timeouts
// Configure parallelism and timeout
for sub, err := range scout.Subdomains(ctx, "example.com",
    scout.WithParallelism(4),           // 4 sources at once
    scout.WithTimeout(30*time.Second),  // 30s per source
) {
    if err == nil {
        fmt.Println(sub)
    }
}
Rate Limiting
// Apply global and per-source rate limits
for sub, err := range scout.Subdomains(ctx, "example.com",
    scout.WithGlobalRateLimit(10),              // 10 req/sec globally
    scout.WithSourceRateLimit("commoncrawl", 0.25), // 15 req/min for commoncrawl
) {
    if err == nil {
        fmt.Println(sub)
    }
}
API Keys for Enhanced Limits
// Some sources support optional API keys for higher rate limits
for sub, err := range scout.Subdomains(ctx, "example.com",
    scout.WithAPIKey("virustotal", "your-api-key"),
    scout.WithAPIKey("shodan", "your-api-key"),
) {
    // Process results...
}

API Reference

Functions
Function Description
Query(ctx, domain, ...opts) Query sources and yield all results (subdomains and URLs)
Subdomains(ctx, domain, ...opts) Query sources and yield only subdomains
URLs(ctx, domain, ...opts) Query sources and yield only URLs
Options
Option Description
WithSources([]Source) Specify which sources to query
WithParallelism(n) Set concurrent source count (default: NumCPU×2)
WithTimeout(duration) Set per-source timeout (default: 30s)
WithGlobalRateLimit(rps) Set global rate limit (requests/second)
WithSourceRateLimit(name, rps) Set per-source rate limit
WithHTTPClient(client) Use custom HTTP client
WithAPIKey(source, key) Set API key for a source
Source Registry
Function Description
sources.All() Get all registered sources
sources.ByName(name) Get source by name
sources.ByNames(...names) Get multiple sources by name
sources.ByType(type) Get sources yielding specific result type
sources.Names() Get names of all registered sources
Types
// Result represents a discovery from a source
type Result struct {
    Type   ResultType // Subdomain or URL
    Value  string     // The discovered value
    Source string     // Which source found it
}

// ResultType indicates the kind of result
type ResultType uint8

const (
    Subdomain ResultType = 1 << iota // Subdomain result
    URL                              // URL result
)

Available Sources

No API Key Required (11 sources)
Source Yields Description
anubis Subdomain Anubis subdomain database
crtsh Subdomain Certificate transparency logs
commoncrawl Subdomain, URL Common Crawl web archive
digitorus Subdomain Certificate details database
hudsonrock Subdomain, URL Data breach information
rapiddns Subdomain DNS record aggregator
sitedossier Subdomain Domain analysis tool
thc Subdomain THC subdomain lookup API
alienvault URL AlienVault OTX URL list
hackertarget Subdomain Host search (limited without key)
reconeer Subdomain Subdomain enumeration (limited without key)

Documentation

Index

Constants

View Source
const Version = "0.1.0"

Variables

This section is empty.

Functions

func Collect

func Collect[T any](seq iter.Seq2[T, error]) ([]T, error)

Collect iterates over all results, collecting results without error. Returned are the collected non-error results, if any errors occurred they will be joined into a non-nil error result. Partial results are returned alongside errors.

func Query

func Query(ctx context.Context, domain string, opts ...Option) iter.Seq2[sources.Result, error]

Query runs sources against a domain and yields results. By default all registered sources are queried; use WithSources to override. Results are deduplicated across all sources.

func Subdomains

func Subdomains(ctx context.Context, domain string, opts ...Option) iter.Seq2[string, error]

Subdomains is a convenience wrapper that filters for Subdomain results only. By default only subdomain-yielding sources are queried; use WithSources to override.

func URLs

func URLs(ctx context.Context, domain string, opts ...Option) iter.Seq2[string, error]

URLs is a convenience wrapper that filters for URL results only. By default only URL-yielding sources are queried; use WithSources to override.

Types

type Option

type Option func(*Options)

Option is a functional option for configuring Query.

func WithAPIKey

func WithAPIKey(source, key string) Option

WithAPIKey sets an API key for a specific source.

func WithGlobalRateLimit

func WithGlobalRateLimit(rps float64) Option

WithGlobalRateLimit sets a global rate limit (requests/second).

func WithHTTPClient

func WithHTTPClient(c *http.Client) Option

WithHTTPClient sets a custom HTTP client.

func WithParallelism

func WithParallelism(n int) Option

WithParallelism sets the number of concurrent sources.

func WithSourceRateLimit

func WithSourceRateLimit(source string, rps float64) Option

WithSourceRateLimit sets a rate limit for a specific source.

func WithSources

func WithSources(srcs []sources.Source) Option

WithSources sets the sources to query.

func WithTimeout

func WithTimeout(d time.Duration) Option

WithTimeout sets the per-source timeout.

type Options

type Options struct {
	// Sources specifies which sources to query. If nil, sensible default source selections are made.
	Sources []sources.Source

	// HTTPClient is the client used for all requests. If nil, a default client with sensible timeouts is used.
	HTTPClient *http.Client

	// Parallelism controls how many sources run concurrently. Set to 1 for sequential execution.
	Parallelism int

	// GlobalRateLimit limits requests/second across all sources. Default is 0 (unlimited).
	GlobalRateLimit rate.Limit

	// SourceRateLimits sets per-source rate limits. Key is source name, value is requests/second.
	SourceRateLimits map[string]rate.Limit

	// Timeout is the per-source timeout.
	Timeout time.Duration

	// APIKeys maps source names to their API keys. Optional keys improve rate limits for some sources.
	APIKeys map[string]string
}

Options configures the behavior of Query and related functions.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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