security

package
v0.7.0 Latest Latest
Warning

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

Go to latest
Published: May 8, 2026 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Overview

Package security provides input sanitization and output scanning for fullsend's agent entrypoints. These scanners run at the boundaries:

  • Input boundary: before untrusted text (issue bodies, PR descriptions, code comments, context files) reaches agent processing
  • Output boundary: before agent-generated text (PR comments, issue comments) is posted via the forge API

The scanners are adapted from Hermes Agent's production security controls, ported to Go for integration into fullsend's CLI entrypoints.

See: experiments/hermes-security-patterns/ for the Python prototypes and evaluation results.

Index

Constants

View Source
const SandboxHooksDir = "/tmp/workspace/.claude/hooks"

SandboxHooksDir is the path where hook scripts are installed inside the sandbox. Must match sandbox.SandboxWorkspace + "/.claude/hooks".

Variables

View Source
var CanaryPostToolHook []byte
View Source
var CanaryPreToolHook []byte
View Source
var ContextSuppressPostToolHook []byte
View Source
var SSRFPreToolHook []byte
View Source
var ScannableFiles = map[string]bool{
	"agents.md":               true,
	".cursorrules":            true,
	"claude.md":               true,
	".claude.md":              true,
	"soul.md":                 true,
	".hermes.md":              true,
	"hermes.md":               true,
	"gemini.md":               true,
	".gemini.md":              true,
	"copilot-instructions.md": true,
	"skill.md":                true,
}

ScannableFiles is the set of filenames that should be scanned for prompt injection before being loaded into agent context.

View Source
var SecretRedactPostToolHook []byte
View Source
var TirithCheckHook []byte
View Source
var ToolAllowlistPreToolHook []byte
View Source
var UnicodePostToolHook []byte

Functions

func AppendFinding

func AppendFinding(path string, tf TracedFinding) error

AppendFinding writes a traced finding as a JSON line to the given file path.

func DestroyMLScanner

func DestroyMLScanner()

DestroyMLScanner is a no-op stub when ONNX runtime is not available.

func GenerateClaudeSettings

func GenerateClaudeSettings(h *harness.Harness) ([]byte, error)

GenerateClaudeSettings produces a .claude/settings.json with security hooks configured according to the harness SecurityConfig. Returns the JSON bytes.

func GenerateTraceID

func GenerateTraceID() string

GenerateTraceID returns a UUID v4 string for correlating security findings across scanning phases (host pre-step, sandbox pre-agent, runtime hooks, post-agent output scan).

func HasCriticalFindings added in v0.2.0

func HasCriticalFindings(findings []Finding) bool

HasCriticalFindings reports whether any finding has critical severity.

func HookFiles

func HookFiles(h *harness.Harness) map[string][]byte

HookFiles returns a map of filename -> content for all enabled hook scripts.

func IsValidTraceID

func IsValidTraceID(id string) bool

IsValidTraceID returns true if the trace ID is safe for shell interpolation.

func MLScanAvailable

func MLScanAvailable() bool

MLScanAvailable reports whether the native ONNX ML scanner is compiled in.

func ShouldScan

func ShouldScan(filename string) bool

ShouldScan reports whether a filename should be scanned for injection.

Types

type ContextInjectionScanner

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

ContextInjectionScanner detects prompt injection patterns in project context files (AGENTS.md, .cursorrules, CLAUDE.md, etc.) before they are loaded into an agent's system prompt. Adapted from Hermes Agent's prompt_builder.py injection scanning.

func NewContextInjectionScanner

func NewContextInjectionScanner() *ContextInjectionScanner

NewContextInjectionScanner creates a scanner with the default pattern set.

func (*ContextInjectionScanner) Name

func (c *ContextInjectionScanner) Name() string

func (*ContextInjectionScanner) Scan

type Finding

type Finding struct {
	Scanner  string // "secret_redactor", "ssrf_validator", "context_injection", "unicode_normalizer"
	Name     string // pattern name or category
	Severity string // "critical", "high", "medium"
	Detail   string // human-readable description
	Position int    // byte offset in original text, -1 if N/A
}

Finding represents a single security issue detected by a scanner.

type Pipeline

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

Pipeline chains multiple scanners in sequence. Each scanner's sanitized output feeds into the next scanner's input.

func InputPipeline

func InputPipeline() *Pipeline

InputPipeline returns the standard input scanning pipeline for untrusted text entering the agent. Order matters:

  1. UnicodeNormalizer — strip invisible chars, normalize fullwidth
  2. ContextInjectionScanner — detect prompt injection patterns

func NewPipeline

func NewPipeline(scanners ...Scanner) *Pipeline

NewPipeline creates a scanner pipeline from the given scanners. Scanners run in order; place normalizers first, detectors after.

func OutputPipeline

func OutputPipeline() *Pipeline

OutputPipeline returns the standard output scanning pipeline for agent-generated text before posting to the forge.

  1. SecretRedactor — redact API keys, tokens, credentials

func (*Pipeline) Scan

func (p *Pipeline) Scan(text string) ScanResult

Scan runs all scanners in sequence. Returns the aggregate result. The pipeline is fail-open for sanitization (each scanner transforms the text) but fail-closed for safety (any scanner marking unsafe makes the whole result unsafe).

type SSRFValidator

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

SSRFValidator validates URLs against blocked networks, hostnames, and schemes to prevent Server-Side Request Forgery. Adapted from Hermes Agent's URL validation.

func NewSSRFValidator

func NewSSRFValidator() *SSRFValidator

NewSSRFValidator creates a validator with the default blocklists.

func (*SSRFValidator) Name

func (s *SSRFValidator) Name() string

func (*SSRFValidator) Scan

func (s *SSRFValidator) Scan(text string) ScanResult

Scan implements the Scanner interface. Extracts URLs from text and validates each one. Uses regex-based extraction (matching the Python hook's URL_PATTERN) to handle URLs embedded in markdown, JSON, etc.

func (*SSRFValidator) ValidateRedirectChain

func (s *SSRFValidator) ValidateRedirectChain(urls []string) ScanResult

ValidateRedirectChain checks each URL in a redirect chain.

func (*SSRFValidator) ValidateURL

func (s *SSRFValidator) ValidateURL(rawURL string, resolveDNS bool) ScanResult

ValidateURL checks a single URL for SSRF risk. Set resolveDNS to true to resolve hostnames and check resolved IPs.

type ScanResult

type ScanResult struct {
	Safe      bool
	Findings  []Finding
	Sanitized string // cleaned/redacted version of input (empty if unchanged)
}

ScanResult holds the outcome of a security scan.

func RunMLScan

func RunMLScan(_ string, _ bool) ScanResult

RunMLScan is a no-op stub when ONNX runtime is not available.

type Scanner

type Scanner interface {
	// Name returns the scanner identifier.
	Name() string

	// Scan checks text for security issues. Returns a ScanResult with
	// findings and optionally a sanitized version of the input.
	Scan(text string) ScanResult
}

Scanner is the interface for all security scanners.

type SecretRedactor

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

SecretRedactor scans text for API keys, tokens, credentials, and sensitive patterns, replacing them with masked versions. Adapted from Hermes Agent's agent/redact.py.

func NewSecretRedactor

func NewSecretRedactor() *SecretRedactor

NewSecretRedactor creates a redactor with the default pattern set.

func (*SecretRedactor) Name

func (s *SecretRedactor) Name() string

func (*SecretRedactor) Scan

func (s *SecretRedactor) Scan(text string) ScanResult

type TracedFinding

type TracedFinding struct {
	TraceID   string `json:"trace_id"`
	Timestamp string `json:"timestamp"`
	Phase     string `json:"phase"` // "host_input", "sandbox_context", "hook_pretool", "hook_posttool", "host_output"
	Finding
}

TracedFinding is a Finding enriched with trace and phase metadata for the JSONL audit log.

type UnicodeNormalizer

type UnicodeNormalizer struct{}

UnicodeNormalizer strips invisible Unicode characters and normalizes fullwidth characters to prevent command obfuscation and hidden payload injection. Adapted from Hermes Agent's approval.py.

func NewUnicodeNormalizer

func NewUnicodeNormalizer() *UnicodeNormalizer

NewUnicodeNormalizer creates a UnicodeNormalizer.

func (*UnicodeNormalizer) Name

func (u *UnicodeNormalizer) Name() string

func (*UnicodeNormalizer) Scan

func (u *UnicodeNormalizer) Scan(text string) ScanResult

Jump to

Keyboard shortcuts

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