service

package
v0.1.19 Latest Latest
Warning

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

Go to latest
Published: Jul 14, 2026 License: MIT Imports: 61 Imported by: 0

Documentation

Index

Constants

View Source
const (
	SourceProxy  = "proxy"
	SourceReplay = "replay"
	SourceCrawl  = "crawl"
)

Flow source constants for display and sorting.

View Source
const (
	OutputModeFlows   = "flows"
	OutputModeSummary = "summary"
	OutputModeForms   = "forms"
	OutputModeErrors  = "errors"
)

Output mode constants for poll tools.

View Source
const DefaultMCPPort = 9119
View Source
const InternalToolPrefix = "_internal_"

InternalToolPrefix marks tools intended for CLI-only use. Tools with this prefix are excluded from tools/list via WithToolFilter, but remain callable by name through tools/call.

View Source
const MaxOastEventsPerSession = 2000

MaxOastEventsPerSession is the maximum number of events stored per session. Oldest events are dropped when this limit is exceeded.

Variables

View Source
var ErrConfigEditDisabled = errors.New("config editing disabled")

ErrConfigEditDisabled is returned when a write operation fails because config editing is not enabled.

View Source
var ErrLabelExists = errors.New("label already exists")

ErrLabelExists is returned when label conflicts with an existing entry (rule or OAST).

View Source
var ErrNotFound = errors.New("not found")

ErrNotFound is returned when a requested resource (rule, session, etc.) doesn't exist.

View Source
var ErrNotSupported = errors.New("not supported by backend")

ErrNotSupported is returned when a backend cannot perform an operation.

Functions

func BuildCaptureFilter added in v0.1.6

func BuildCaptureFilter(cfg config.ProxyConfig) (proxy.CaptureFilter, error)

BuildCaptureFilter compiles proxy exclusion patterns from config into a CaptureFilter.

func IsTimeoutError

func IsTimeoutError(err error) bool

IsTimeoutError returns true if the error is a timeout.

Types

type BurpBackend

type BurpBackend struct {
	// contains filtered or unexported fields
}

BurpBackend implements HttpBackend using Burp Suite via MCP.

func ConnectBurpBackend

func ConnectBurpBackend(ctx context.Context, url string, storage store.Provider, opts ...mcp.Option) (*BurpBackend, error)

ConnectBurpBackend creates a new Burp HttpBackend with the given MCP URL.

func NewBurpBackend

func NewBurpBackend(client *mcp.BurpClient, storage store.Provider) (*BurpBackend, error)

NewBurpBackend creates a new Burp HttpBackend with the given MCP client.

func (*BurpBackend) AddRule

func (b *BurpBackend) AddRule(ctx context.Context, input protocol.RuleEntry) (*protocol.RuleEntry, error)

func (*BurpBackend) Close

func (b *BurpBackend) Close() error

func (*BurpBackend) Connect

func (b *BurpBackend) Connect(ctx context.Context) error

func (*BurpBackend) DeleteProxyEntries added in v0.1.15

func (b *BurpBackend) DeleteProxyEntries(ctx context.Context, flowIDs []string) (int, error)

func (*BurpBackend) DeleteRule

func (b *BurpBackend) DeleteRule(ctx context.Context, idOrLabel string) error

func (*BurpBackend) GetProxyChildren added in v0.1.18

func (b *BurpBackend) GetProxyChildren(ctx context.Context, parentFlowID string) ([]ProxyEntry, error)

GetProxyChildren returns no children: the Burp backend has no nested flows.

func (*BurpBackend) GetProxyEntry added in v0.1.15

func (b *BurpBackend) GetProxyEntry(ctx context.Context, flowID string) (*ProxyEntry, error)

func (*BurpBackend) GetProxyHistory

func (b *BurpBackend) GetProxyHistory(ctx context.Context, count int, afterFlowID string) ([]ProxyEntry, error)

func (*BurpBackend) GetProxyHistoryMeta

func (b *BurpBackend) GetProxyHistoryMeta(ctx context.Context, count int, afterFlowID string) ([]ProxyEntryMeta, error)

func (*BurpBackend) ListRules

func (b *BurpBackend) ListRules(ctx context.Context, websocket bool) ([]protocol.RuleEntry, error)

func (*BurpBackend) SendRequest

func (b *BurpBackend) SendRequest(ctx context.Context, name string, req SendRequestInput) (*SendRequestResult, error)

func (*BurpBackend) SetInterceptState

func (b *BurpBackend) SetInterceptState(ctx context.Context, intercepting bool) error

SetInterceptState exposes Burp-specific intercept control. This is not part of the HttpBackend interface as it's Burp-specific.

func (*BurpBackend) Sidecars added in v0.1.18

func (b *BurpBackend) Sidecars() SidecarRegistry

Sidecars reports no sidecars; the Burp backend does not host the sidecar listener.

type CollyBackend

type CollyBackend struct {
	// contains filtered or unexported fields
}

CollyBackend implements CrawlerBackend using the Colly library.

func NewCollyBackend

func NewCollyBackend(cfg *config.Config, replayHistoryStore *store.ReplayHistoryStore, httpBackend HttpBackend) *CollyBackend

NewCollyBackend creates a new Colly-backed CrawlerBackend.

func (*CollyBackend) AddSeeds

func (b *CollyBackend) AddSeeds(ctx context.Context, sessionID string, seeds []CrawlSeed) error

func (*CollyBackend) Close

func (b *CollyBackend) Close() error

func (*CollyBackend) CreateSession

func (b *CollyBackend) CreateSession(ctx context.Context, opts CrawlOptions) (*CrawlSessionInfo, error)

func (*CollyBackend) GetFlow

func (b *CollyBackend) GetFlow(ctx context.Context, flowID string) (*CrawlFlow, error)

func (*CollyBackend) GetStatus

func (b *CollyBackend) GetStatus(ctx context.Context, sessionID string) (*CrawlStatus, error)

func (*CollyBackend) ListErrors

func (b *CollyBackend) ListErrors(ctx context.Context, sessionID string, limit int) ([]protocol.CrawlError, error)

func (*CollyBackend) ListFlows

func (b *CollyBackend) ListFlows(ctx context.Context, sessionID string, opts CrawlListOptions) ([]CrawlFlow, error)

func (*CollyBackend) ListForms

func (b *CollyBackend) ListForms(ctx context.Context, sessionID string, limit int) ([]protocol.CrawlForm, error)

func (*CollyBackend) ListSessions

func (b *CollyBackend) ListSessions(ctx context.Context, limit int) ([]CrawlSessionInfo, error)

func (*CollyBackend) StopSession

func (b *CollyBackend) StopSession(ctx context.Context, sessionID string) error

type CrawlFlow

type CrawlFlow struct {
	ID             string        // Short sectool ID
	SessionID      string        // Parent session ID
	URL            string        // Full URL visited
	Host           string        // Hostname (extracted from URL)
	Path           string        // Path with query string (extracted from URL)
	Method         string        // HTTP method
	FoundOn        string        // Parent URL where discovered
	Depth          int           // Crawl depth from seed
	StatusCode     int           // HTTP response status
	ContentType    string        // Response content type
	ResponseLength int           // Response body length in bytes
	Request        []byte        // Wire-format bytes from httputil.DumpRequestOut
	Response       []byte        // Wire-format bytes from httputil.DumpResponse
	Truncated      bool          // True if response exceeded max_response_body_bytes
	Duration       time.Duration // Request/response round-trip time
	DiscoveredAt   time.Time     // When this flow was captured
}

CrawlFlow represents a single captured request/response from crawling.

type CrawlListOptions

type CrawlListOptions struct {
	Host        string            // Glob pattern for host
	PathPattern string            // Glob pattern for path
	StatusCodes *StatusCodeFilter // Filter by status codes (supports ranges like 2XX)
	Methods     []string          // Filter by HTTP methods
	ExcludeHost string            // Exclude hosts matching glob
	ExcludePath string            // Exclude paths matching glob
	Since       string            // Only flows after this flow_id, or "last" for new flows
	Limit       int               // Max results (0 = no limit)
	Offset      int               // Skip first N results

	// Search regexes for header/body content matching.
	// Applied during filtering so the since=last cursor only advances
	// to the last flow that matches all filters including search.
	SearchHeaderRe *regexp.Regexp
	SearchBodyRe   *regexp.Regexp
}

CrawlListOptions contains filters for listing crawl flows. Mirrors ProxyListRequest filters for consistency.

type CrawlOptions

type CrawlOptions struct {
	Label           string            // Optional unique label for the session
	Seeds           []CrawlSeed       // Initial seeds (URLs and/or flow IDs)
	ExplicitDomains []string          // User-specified via --domain
	AllowedPaths    []string          // Glob patterns (default: all)
	DisallowedPaths []string          // Glob patterns (default from config)
	MaxDepth        int               // 0 = unlimited
	MaxRequests     int               // 0 = unlimited
	Delay           time.Duration     // Default: 200ms
	RandomDelay     time.Duration     // Additional random jitter
	Parallelism     int               // Default: 2
	IgnoreRobotsTxt bool              // Default: false
	SubmitForms     bool              // Default: false
	ExtractForms    *bool             // Default: true (from config)
	Headers         map[string]string // Custom headers
}

CrawlOptions contains parameters for creating a crawl session.

type CrawlSeed

type CrawlSeed struct {
	URL    string // Direct URL seed
	FlowID string // Or proxy flow ID - extracts URL and ALL headers
}

CrawlSeed represents a seed for starting a crawl.

type CrawlSessionInfo

type CrawlSessionInfo struct {
	ID        string    // Short sectool ID
	Label     string    // Optional user-provided label
	CreatedAt time.Time // When the session was created
	State     string    // "running", "stopped", "completed", "error"
}

CrawlSessionInfo represents metadata about a crawl session.

type CrawlStatus

type CrawlStatus struct {
	State           string        // "running", "stopped", "completed", "error"
	URLsQueued      int           // URLs waiting to be visited
	URLsVisited     int           // URLs successfully visited
	URLsErrored     int           // URLs that resulted in errors
	FormsDiscovered int           // Forms found during crawl
	Duration        time.Duration // Time since session started
	LastActivity    time.Time     // When last request was made
	ErrorMessage    string        // Error details if State is "error"
}

CrawlStatus contains progress metrics for a crawl session.

type CrawlerBackend

type CrawlerBackend interface {
	// CreateSession starts a new crawl session. Returns immediately; crawling is async.
	// Returns error if max concurrent sessions reached or no valid seeds/domains.
	CreateSession(ctx context.Context, opts CrawlOptions) (*CrawlSessionInfo, error)

	// AddSeeds adds URLs to an existing session (can be called while running).
	// sessionID can be the ID or label. Returns error if session is not running.
	AddSeeds(ctx context.Context, sessionID string, seeds []CrawlSeed) error

	// GetStatus returns session progress metrics.
	// sessionID can be the ID or label. Returns ErrNotFound if session doesn't exist.
	GetStatus(ctx context.Context, sessionID string) (*CrawlStatus, error)

	// ListFlows returns flows matching filters.
	// sessionID can be the ID or label.
	ListFlows(ctx context.Context, sessionID string, opts CrawlListOptions) ([]CrawlFlow, error)

	// ListForms returns forms discovered in a session.
	// sessionID can be the ID or label.
	ListForms(ctx context.Context, sessionID string, limit int) ([]protocol.CrawlForm, error)

	// ListErrors returns errors encountered in a session.
	// sessionID can be the ID or label.
	ListErrors(ctx context.Context, sessionID string, limit int) ([]protocol.CrawlError, error)

	// GetFlow returns a flow by ID. Returns ErrNotFound if flow doesn't exist.
	GetFlow(ctx context.Context, flowID string) (*CrawlFlow, error)

	// StopSession immediately stops a running crawl. In-flight requests are abandoned.
	// sessionID can be the ID or label.
	StopSession(ctx context.Context, sessionID string) error

	// ListSessions returns all sessions (active and completed), most recent first.
	// limit=0 means no limit.
	ListSessions(ctx context.Context, limit int) ([]CrawlSessionInfo, error)

	// Close cleans up all sessions (called on service shutdown).
	Close() error
}

CrawlerBackend defines the interface for web crawling operations.

type HttpBackend

type HttpBackend interface {
	// Close shuts down the HttpBackend.
	Close() error

	// GetProxyHistory retrieves proxy HTTP history entries oldest-first.
	// afterFlowID == "" starts from the beginning.
	GetProxyHistory(ctx context.Context, count int, afterFlowID string) ([]ProxyEntry, error)

	// GetProxyHistoryMeta retrieves lightweight metadata for proxy history entries oldest-first.
	// afterFlowID == "" starts from the beginning.
	GetProxyHistoryMeta(ctx context.Context, count int, afterFlowID string) ([]ProxyEntryMeta, error)

	// GetProxyEntry returns a single entry by flow_id.
	// Returns ErrNotFound if no entry exists for the flow_id.
	GetProxyEntry(ctx context.Context, flowID string) (*ProxyEntry, error)

	// GetProxyChildren returns the child flows of parentFlowID in emission order
	// (stream children, session inner flows). Empty on backends without nested
	// flows (Burp).
	GetProxyChildren(ctx context.Context, parentFlowID string) ([]ProxyEntry, error)

	// DeleteProxyEntries removes proxy history entries by flow_id and returns the number actually deleted.
	// Unknown flow_ids are silently ignored. Returns ErrNotSupported on backends without delete (Burp).
	DeleteProxyEntries(ctx context.Context, flowIDs []string) (int, error)

	// SendRequest sends an HTTP request and returns the response.
	// The request is raw HTTP bytes. Response is returned as headers and body.
	SendRequest(ctx context.Context, name string, req SendRequestInput) (*SendRequestResult, error)

	// ListRules returns all enabled find/replace rules managed by sectool.
	// websocket=true returns WebSocket rules, false returns HTTP rules.
	ListRules(ctx context.Context, websocket bool) ([]protocol.RuleEntry, error)

	// AddRule creates a new find/replace rule.
	// WebSocket vs HTTP is inferred from rule.Type (ws:* types are WebSocket).
	// RuleID is ignored on input and assigned by the backend.
	AddRule(ctx context.Context, rule protocol.RuleEntry) (*protocol.RuleEntry, error)

	// DeleteRule removes a rule by ID or label.
	// Searches both HTTP and WebSocket rules automatically.
	DeleteRule(ctx context.Context, idOrLabel string) error

	// Sidecars returns the connected sidecar registry, or nil on backends that
	// host no sidecars (Burp).
	Sidecars() SidecarRegistry
}

HttpBackend defines the interface for proxy history and request sending. This abstraction allows switching between the built-in proxy and Burp MCP.

type InteractshBackend

type InteractshBackend struct {
	// contains filtered or unexported fields
}

InteractshBackend implements OastBackend using Interactsh.

func NewInteractshBackend

func NewInteractshBackend(serverURL, authToken string) *InteractshBackend

NewInteractshBackend creates a new Interactsh-backed OastBackend.

func (*InteractshBackend) Close

func (b *InteractshBackend) Close() error

func (*InteractshBackend) CreateSession

func (b *InteractshBackend) CreateSession(ctx context.Context, label, redirectTarget string) (*OastSessionInfo, error)

func (*InteractshBackend) DeleteSession

func (b *InteractshBackend) DeleteSession(ctx context.Context, idOrDomain string) error

func (*InteractshBackend) GetEvent

func (b *InteractshBackend) GetEvent(_ context.Context, eventID string) (*OastEventInfo, error)

func (*InteractshBackend) ListSessions

func (b *InteractshBackend) ListSessions(ctx context.Context) ([]OastSessionInfo, error)

func (*InteractshBackend) PollSession

func (b *InteractshBackend) PollSession(ctx context.Context, idOrDomain string, since string, eventType string, wait time.Duration, limit int) (*OastPollResultInfo, error)

func (*InteractshBackend) ProbeRedirectSupport added in v0.1.12

func (b *InteractshBackend) ProbeRedirectSupport(ctx context.Context)

ProbeRedirectSupport determines whether the OAST server supports redirect responses. Default and known interactsh-lite servers are assumed compatible. Custom servers are probed by registering with a 307 ResponseConfig and verifying the response.

func (*InteractshBackend) Start added in v0.1.12

func (b *InteractshBackend) Start(ctx context.Context)

Start probes the server for capabilities and starts background maintenance. Must be called before creating sessions. Pair with Close() for cleanup.

func (*InteractshBackend) SupportsRedirect added in v0.1.12

func (b *InteractshBackend) SupportsRedirect() bool

SupportsRedirect reports whether the OAST server supports redirect responses.

type MCPServerFlags

type MCPServerFlags struct {
	ConfigPath    string
	BurpMCPURL    string
	MCPPort       int
	ProxyPort     int    // 0 = not set via CLI
	RequireBurp   bool   // --burp flag: require Burp, error if unavailable
	WorkflowMode  string // "", "none", "multi", "explore", "test-report"
	Notes         bool   // enable notes/findings tools (experimental)
	SidecarSocket string // override for the sidecar IPC socket (path or host:port)
}

MCPServerFlags holds flags for MCP server mode.

func ParseMCPServerFlags

func ParseMCPServerFlags(args []string) (MCPServerFlags, error)

ParseMCPServerFlags parses flags for MCP server mode (sectool mcp).

type NativeProxyBackend

type NativeProxyBackend struct {
	// contains filtered or unexported fields
}

NativeProxyBackend implements HttpBackend using the native proxy. This backend provides wire-level fidelity for security testing including HTTP/1.1 and HTTP/2 support with header order preservation.

func NewNativeProxyBackend

func NewNativeProxyBackend(port int, configDir string, maxBodyBytes int, storage store.Provider, timeouts proxy.TimeoutConfig) (*NativeProxyBackend, error)

NewNativeProxyBackend creates a new native proxy backend. Does NOT start serving - call Serve() separately (typically in a goroutine). Call EnableSidecars before Serve to host the out-of-process sidecar listener.

func (*NativeProxyBackend) AddResponder added in v0.1.11

AddResponder registers a custom response for a specific origin and path.

func (*NativeProxyBackend) AddRule

func (*NativeProxyBackend) Addr

func (b *NativeProxyBackend) Addr() string

Addr returns the proxy listen address.

func (*NativeProxyBackend) ApplyRequestBodyOnlyRules

func (b *NativeProxyBackend) ApplyRequestBodyOnlyRules(body []byte, headers types.Headers) ([]byte, error)

ApplyRequestBodyOnlyRules applies only body rules to a request body. Used by HTTP/2 where headers are sent separately before body. If recompression fails, returns error so caller can reset the stream.

func (*NativeProxyBackend) ApplyRequestRules

func (b *NativeProxyBackend) ApplyRequestRules(req *types.RawHTTP1Request) *types.RawHTTP1Request

ApplyRequestRules applies request header and body rules. Rules are applied in the order they were added. When response body rules are active, strips unsupported encodings from Accept-Encoding so the server responds with an encoding we can decompress.

func (*NativeProxyBackend) ApplyResponseBodyOnlyRules

func (b *NativeProxyBackend) ApplyResponseBodyOnlyRules(body []byte, headers types.Headers) []byte

ApplyResponseBodyOnlyRules applies only body rules to a response body. Used by HTTP/2 where headers are sent separately before body. If recompression fails, returns original body to avoid corrupting response.

func (*NativeProxyBackend) ApplyResponseRules

func (b *NativeProxyBackend) ApplyResponseRules(resp *types.RawHTTP1Response) *types.RawHTTP1Response

ApplyResponseRules applies response header and body rules. Handles decompression/recompression for body rules.

func (*NativeProxyBackend) ApplyWSRules

func (b *NativeProxyBackend) ApplyWSRules(payload []byte, direction string) []byte

ApplyWSRules applies WebSocket rules to frame payload.

func (*NativeProxyBackend) CACert

func (b *NativeProxyBackend) CACert() *x509.Certificate

CACert returns the CA certificate used for MITM TLS interception.

func (*NativeProxyBackend) Close

func (b *NativeProxyBackend) Close() error

func (*NativeProxyBackend) DeleteProxyEntries added in v0.1.15

func (b *NativeProxyBackend) DeleteProxyEntries(ctx context.Context, flowIDs []string) (int, error)

func (*NativeProxyBackend) DeleteResponder added in v0.1.11

func (b *NativeProxyBackend) DeleteResponder(ctx context.Context, idOrLabel string) error

DeleteResponder removes a responder by ID or label.

func (*NativeProxyBackend) DeleteRule

func (b *NativeProxyBackend) DeleteRule(ctx context.Context, idOrLabel string) error

func (*NativeProxyBackend) EnableSidecars added in v0.1.18

func (b *NativeProxyBackend) EnableSidecars(cfg sidecar.Config, coreInvoke sidecar.CoreService, replayStore *store.ReplayHistoryStore) error

EnableSidecars constructs the sidecar IPC listener and registry. Call once before Serve. cfg.NativeProxyPort should be the proxy's listen port; the built-in adapter names are reserved automatically. coreInvoke backs the sidecar core_invoke method; it resolves the read-side tools lazily so it can be supplied before the MCP server exists.

func (*NativeProxyBackend) GetProxyChildren added in v0.1.18

func (b *NativeProxyBackend) GetProxyChildren(ctx context.Context, parentFlowID string) ([]ProxyEntry, error)

func (*NativeProxyBackend) GetProxyEntry added in v0.1.15

func (b *NativeProxyBackend) GetProxyEntry(ctx context.Context, flowID string) (*ProxyEntry, error)

func (*NativeProxyBackend) GetProxyHistory

func (b *NativeProxyBackend) GetProxyHistory(ctx context.Context, count int, afterFlowID string) ([]ProxyEntry, error)

func (*NativeProxyBackend) GetProxyHistoryMeta

func (b *NativeProxyBackend) GetProxyHistoryMeta(ctx context.Context, count int, afterFlowID string) ([]ProxyEntryMeta, error)

func (*NativeProxyBackend) HasBodyRules

func (b *NativeProxyBackend) HasBodyRules(isRequest bool) bool

HasBodyRules returns true if there are body rules for request or response. Used by HTTP/2 handler to decide whether to buffer full bodies.

func (*NativeProxyBackend) InterceptRequest added in v0.1.11

func (b *NativeProxyBackend) InterceptRequest(host string, port int, path string, method string) *proxy.InterceptedResponse

InterceptRequest checks if a request matches a registered responder.

func (*NativeProxyBackend) ListResponders added in v0.1.11

func (b *NativeProxyBackend) ListResponders(ctx context.Context) ([]protocol.ResponderEntry, error)

ListResponders returns all registered responders.

func (*NativeProxyBackend) ListRules

func (b *NativeProxyBackend) ListRules(ctx context.Context, websocket bool) ([]protocol.RuleEntry, error)

func (*NativeProxyBackend) RuleSnapshot added in v0.1.18

func (b *NativeProxyBackend) RuleSnapshot(adapter string) (uint64, []wire.Rule)

RuleSnapshot returns the current snapshot version and the rules scoped to the named adapter (scope empty or equal to the name), in apply order (HTTP rules then WS).

func (*NativeProxyBackend) SendRequest

func (*NativeProxyBackend) Serve

func (b *NativeProxyBackend) Serve() error

Serve starts the proxy server. Call in a goroutine.

func (*NativeProxyBackend) SetCaptureFilter added in v0.1.6

func (b *NativeProxyBackend) SetCaptureFilter(f proxy.CaptureFilter)

SetCaptureFilter configures the proxy to skip storing entries that the filter rejects. Filtered requests are still proxied normally.

func (*NativeProxyBackend) Sidecars added in v0.1.18

func (b *NativeProxyBackend) Sidecars() SidecarRegistry

Sidecars returns the sidecar registry, or nil when sidecars are not enabled.

func (*NativeProxyBackend) WaitReady

func (b *NativeProxyBackend) WaitReady(ctx context.Context) error

WaitReady blocks until Serve() has entered its accept loop.

type OastBackend

type OastBackend interface {
	// CreateSession registers with the OAST provider and starts background polling.
	// Returns session with short ID and domain.
	// If label is non-empty, it must be unique across all sessions.
	// If redirectTarget is non-empty, HTTP requests to the session domain receive a 307 redirect.
	CreateSession(ctx context.Context, label, redirectTarget string) (*OastSessionInfo, error)

	// SupportsRedirect reports whether this backend supports redirect responses.
	SupportsRedirect() bool

	// PollSession returns events for a session.
	// idOrDomain accepts either the short ID or the full domain.
	// since filters events: empty returns all, "last" returns since last poll, or an event ID.
	// eventType filters by protocol: empty returns all, otherwise one of dns, http, smtp, ftp, ldap, smb, responder.
	// wait specifies how long to block waiting for events (0 = return immediately).
	// limit caps the number of events returned (0 = no limit). When used with "since last",
	// the last position is updated to the last returned event (for pagination).
	PollSession(ctx context.Context, idOrDomain string, since string, eventType string, wait time.Duration, limit int) (*OastPollResultInfo, error)

	// GetEvent retrieves a single event by ID, searching across all sessions.
	// Returns the full event details without truncation.
	GetEvent(ctx context.Context, eventID string) (*OastEventInfo, error)

	// ListSessions returns all active sessions.
	ListSessions(ctx context.Context) ([]OastSessionInfo, error)

	// DeleteSession stops polling and deregisters from the OAST provider.
	// idOrDomain accepts either the short ID or the full domain.
	DeleteSession(ctx context.Context, idOrDomain string) error

	// Close cleans up all sessions (called on service shutdown).
	// Should attempt deregistration with a short timeout.
	Close() error
}

OastBackend defines the interface for OAST (Out-of-band Application Security Testing).

type OastEventInfo

type OastEventInfo struct {
	ID        string                 // Short sectool ID
	Time      time.Time              // When the interaction occurred
	Type      string                 // "dns", "http", "smtp"
	SourceIP  string                 // Remote address of the interaction
	Subdomain string                 // Full subdomain that was accessed
	Details   map[string]interface{} // Protocol-specific details
}

OastEventInfo represents a captured out-of-band interaction (internal domain type).

type OastPollResultInfo

type OastPollResultInfo struct {
	Events       []OastEventInfo // Events matching the filter
	DroppedCount int             // Number of events dropped due to buffer limit
}

OastPollResultInfo contains the result of polling for events.

type OastSessionInfo

type OastSessionInfo struct {
	ID             string    // Short sectool ID (e.g., "a1b2c3")
	Domain         string    // Full Interactsh domain (e.g., "xyz123.alpha.oastsrv.net")
	Label          string    // Optional user-provided label for easier reference
	RedirectTarget string    // URL to 307 redirect HTTP requests to (empty = no redirect)
	CreatedAt      time.Time // When the session was created
}

OastSessionInfo represents an active OAST session (internal domain type).

type PathQueryOpts

type PathQueryOpts struct {
	Method      string   // replace HTTP method
	Path        string   // replace entire path (without query)
	Query       string   // replace entire query string
	SetQuery    []string // add or replace query params ("key=value")
	RemoveQuery []string // remove query params by key
}

PathQueryOpts contains options for modifying the request line.

func (*PathQueryOpts) HasModifications

func (o *PathQueryOpts) HasModifications() bool

HasModifications returns true if any request line modification is specified.

type ProxyEntry

type ProxyEntry struct {
	FlowID    string    `json:"flow_id"`
	Timestamp time.Time `json:"-"` // capture-start for native; first observation for Burp
	Request   string    `json:"request"`
	Response  string    `json:"response"`
	// InterimResponses holds wire-formatted 1xx responses that preceded Response.
	InterimResponses []string `json:"interim_responses,omitempty"`
	Notes            string   `json:"notes"`
	Protocol         string   `json:"protocol"`                 // "http/1.1" or "http/2" (empty defaults to http/1.1)
	Adapter          string   `json:"adapter,omitempty"`        // emitting adapter name
	ParentFlowID     string   `json:"parent_flow_id,omitempty"` // parent flow when nested
	Scheme           string   `json:"scheme,omitempty"`         // "http" or "https" (empty = infer from host)
	Port             int      `json:"port,omitempty"`           // original port (0 = infer from scheme)
	// Annotations carries sidecar-authored flow metadata.
	Annotations       map[string]any `json:"annotations,omitempty"`
	InvokedBy         string         `json:"invoked_by,omitempty"`
	SidecarInstanceID string         `json:"sidecar_instance_id,omitempty"`
	// Placeholder marks an unparseable Burp entry that preserves offset contiguity; skipped for display.
	Placeholder bool `json:"-"`
}

ProxyEntry represents a single proxy history entry in HttpBackend-agnostic form.

type ProxyEntryMeta

type ProxyEntryMeta struct {
	FlowID       string
	Timestamp    time.Time // capture-start for native; first observation for Burp
	Method       string
	Host         string
	Path         string // includes query string
	Status       int
	RespLen      int
	Protocol     string
	Adapter      string // emitting adapter name
	ParentFlowID string // parent flow when nested (stream child, session inner flow)
	Scheme       string // "http" or "https" (empty = infer from host)
	Port         int    // original port (0 = infer from scheme)
	ContentType  string
	// Annotations carries sidecar-authored flow metadata.
	Annotations       map[string]any
	InvokedBy         string
	SidecarInstanceID string
	// Placeholder marks an unparseable Burp entry that preserves offset contiguity; skipped for display.
	Placeholder bool
}

ProxyEntryMeta holds lightweight metadata for a proxy history entry. Used by summary/list paths to avoid deserializing full request/response bodies.

type ProxyListRequest

type ProxyListRequest struct {
	Host         string `json:"host,omitempty"`
	Path         string `json:"path,omitempty"`
	Method       string `json:"method,omitempty"`
	Status       string `json:"status,omitempty"`
	SearchHeader string `json:"search_header,omitempty"`
	SearchBody   string `json:"search_body,omitempty"`
	Since        string `json:"since,omitempty"`
	ExcludeHost  string `json:"exclude_host,omitempty"`
	ExcludePath  string `json:"exclude_path,omitempty"`
	Adapter      string `json:"adapter,omitempty"`
	ProtocolTag  string `json:"protocol_tag,omitempty"`
	ParentFlowID string `json:"parent_flow_id,omitempty"`
	Limit        int    `json:"limit,omitempty"`
	Offset       int    `json:"offset,omitempty"`
	Source       string `json:"source,omitempty"`
}

ProxyListRequest contains filters for proxy list queries.

func (*ProxyListRequest) HasFilters

func (r *ProxyListRequest) HasFilters() bool

HasFilters returns true if any filter is set.

type RequestSender

type RequestSender func(ctx context.Context, req SendRequestInput, start time.Time) (*SendRequestResult, error)

RequestSender sends a single request and returns the result.

type ResponderBackend added in v0.1.11

type ResponderBackend interface {
	// AddResponder registers a custom response for a specific origin and path.
	// ResponderID is assigned by the backend and returned in the result.
	AddResponder(ctx context.Context, input protocol.ResponderEntry) (*protocol.ResponderEntry, error)

	// DeleteResponder removes a responder by ID or label.
	DeleteResponder(ctx context.Context, idOrLabel string) error

	// ListResponders returns all registered responders.
	ListResponders(ctx context.Context) ([]protocol.ResponderEntry, error)
}

ResponderBackend defines the interface for managing proxy responders. Only available when using the native proxy backend.

type SendRequestInput

type SendRequestInput struct {
	RawRequest      []byte
	Target          types.Target
	FollowRedirects bool
	Force           bool // Skip validation for protocol-level tests

	// Protocol from the original history entry ("http/1.1" or "http/2")
	// Empty defaults to HTTP/1.1
	Protocol string
}

SendRequestInput contains all parameters for sending a request.

type SendRequestResult

type SendRequestResult struct {
	Headers         []byte
	Body            []byte
	Duration        time.Duration
	ModifiedRequest []byte // post-rule request bytes; nil if no rules applied
}

SendRequestResult contains the response from a sent request.

func FollowRedirects

func FollowRedirects(ctx context.Context, req SendRequestInput, start time.Time, maxRedirects int, sender RequestSender) (*SendRequestResult, error)

FollowRedirects sends a request and follows redirects up to maxRedirects times. Uses sender to perform individual requests, allowing different backend implementations. Used by BurpBackend which doesn't use the wire-fidelity sender.

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server is the sectool MCP server.

func NewServer

func NewServer(flags MCPServerFlags, hb HttpBackend, ob OastBackend, cb CrawlerBackend) (*Server, error)

NewServer creates a new MCP server instance with optional backends. If a backend is nil, Run initializes the default implementation.

func (*Server) CoreInvoke added in v0.1.18

func (s *Server) CoreInvoke(ctx context.Context, tool string, params json.RawMessage) (string, bool, error)

CoreInvoke dispatches a core MCP tool by name for the sidecar core_invoke method, delegating to the MCP server's tool handlers once it is built.

func (*Server) CoreToolNames added in v0.1.18

func (s *Server) CoreToolNames() []string

CoreToolNames returns the static core MCP tool names captured at construction, or nil before the MCP server is built. It lets the sidecar registry reject a tool-name collision against core tools; connected sidecars' tool names are checked separately, so this stays the genuine core set.

func (*Server) DeleteProxyHistory added in v0.1.15

func (s *Server) DeleteProxyHistory(ctx context.Context, flowIDs []string) (int, int, []string, error)

DeleteProxyHistory removes the supplied flow_ids from the proxy backend and the replay store. Flow_ids referenced by any saved note are retained and returned in skippedNoted. Each store silently ignores ids it doesn't own, so callers don't need to pre-route by source.

func (*Server) OriginateNative added in v0.1.18

func (s *Server) OriginateNative(ctx context.Context, p wire.SidecarSendParams, invokedBy string) (wire.SidecarSendResult, *wire.Error)

OriginateNative backs a sidecar's invoke_adapter targeting the reserved "sectool" adapter: it originates an outbound HTTP request through the native send path. Returns an error until the MCP server is ready.

func (*Server) RequestShutdown

func (s *Server) RequestShutdown()

RequestShutdown initiates server shutdown.

func (*Server) Run

func (s *Server) Run(ctx context.Context) error

Run starts the MCP server and blocks until shutdown.

func (*Server) SetQuietLogging added in v0.1.4

func (s *Server) SetQuietLogging()

SetQuietLogging suppresses verbose startup output and removes timestamps from log output. Intended for use in tests.

func (*Server) WaitTillStarted

func (s *Server) WaitTillStarted()

WaitTillStarted blocks until the server has started.

type SidecarRegistry added in v0.1.18

type SidecarRegistry interface {
	// HasAdapter reports whether a healthy sidecar is registered under name.
	HasAdapter(name string) bool
	// AdapterTools returns each healthy adapter's MCP tools keyed by adapter name,
	// as a single consistent snapshot.
	AdapterTools() map[string][]wire.MCPTool
	// InvokeTool delegates a sidecar-registered tool call to its owning adapter.
	InvokeTool(ctx context.Context, name string, args json.RawMessage) (wire.InvokeToolResult, *wire.Error)
	// SidecarSend routes a replay or origination to the named adapter.
	SidecarSend(ctx context.Context, adapter string, p wire.SidecarSendParams) (wire.SidecarSendResult, *wire.Error)
	// SetToolsChangedHook registers a callback invoked when the connected adapter set changes.
	SetToolsChangedHook(fn func())
}

SidecarRegistry is the connected-sidecar surface the MCP server consumes for replay routing and tool composition. The native proxy backend's sidecar manager implements it; it is defined here (in wire terms only) so the service depends on this contract rather than the deep sidecar package.

type StatusCodeFilter

type StatusCodeFilter struct {
	// contains filtered or unexported fields
}

StatusCodeFilter matches status codes by exact value or range (e.g., 2XX).

func (*StatusCodeFilter) Empty

func (f *StatusCodeFilter) Empty() bool

Empty returns true if the filter has no conditions.

func (*StatusCodeFilter) Matches

func (f *StatusCodeFilter) Matches(code int) bool

Matches returns true if the code matches the filter.

Directories

Path Synopsis
Package dedupe provides small order-preserving deduplication helpers.
Package dedupe provides small order-preserving deduplication helpers.
Package fileutil provides small filesystem helpers shared across the service.
Package fileutil provides small filesystem helpers shared across the service.
types
Package types holds the proxy capture data model: the wire-fidelity HTTP/1.1 request/response types, the common Flow/Message envelope, and the rule-applier contract.
Package types holds the proxy capture data model: the wire-fidelity HTTP/1.1 request/response types, the common Flow/Message envelope, and the rule-applier contract.

Jump to

Keyboard shortcuts

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