scanner

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Aug 16, 2026 License: MIT Imports: 33 Imported by: 0

Documentation

Overview

Package scanner provides code scanning and analysis functionality. bastion:ignore-file xss,RULE-DESER-001 detector signatures are data, not execution

Package scanner provides code scanning and analysis functionality.

Package scanner provides code scanning and vulnerability detection.

Package scanner provides code scanning and analysis functionality. bastion:ignore-file RULE-DESER-001 detector signatures are data, not execution

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrRepositoryTooLarge is returned when a repository exceeds the size limit.
	ErrRepositoryTooLarge = errors.New("repository size exceeds maximum allowed")

	// ErrUnsupportedHost is returned when the Git host is not in the allowed list.
	ErrUnsupportedHost = errors.New("git host is not supported")

	// ErrInvalidRepositoryURL is returned when the repository URL is invalid.
	ErrInvalidRepositoryURL = errors.New("invalid repository URL")

	// ErrCloneTimeout is returned when cloning times out.
	ErrCloneTimeout = errors.New("clone operation timed out")

	// ErrAuthenticationFailed is returned when Git authentication fails.
	ErrAuthenticationFailed = errors.New("git authentication failed")

	// ErrPathTraversal is returned when path traversal is detected.
	ErrPathTraversal = errors.New("path traversal detected")

	// ErrBinaryFile is returned when trying to read a binary file.
	ErrBinaryFile = errors.New("binary file detected")
)

Functions

func DetectLanguage

func DetectLanguage(path string) string

DetectLanguage detects the programming language from file path.

func ExtractRepoInfo

func ExtractRepoInfo(repoURL string) (owner, repo string, err error)

ExtractRepoInfo extracts owner and repo name from a repository URL.

func GetLanguageExtensions

func GetLanguageExtensions(language string) []string

GetLanguageExtensions returns all extensions for a language.

func HTTPAuth

func HTTPAuth(username, password string) transport.AuthMethod

HTTPAuth creates HTTP basic auth.

func IsBinaryFile

func IsBinaryFile(content []byte) bool

IsBinaryFile checks if content is binary.

func IsExportedName

func IsExportedName(name string) bool

IsExportedName checks if a name is exported (starts with uppercase).

func ReadFileFromDisk

func ReadFileFromDisk(path string, maxSize int64) ([]byte, error)

ReadFileFromDisk reads a file from the filesystem with size limit.

func SSHKeyAuth

func SSHKeyAuth(privateKeyPath, password string) (transport.AuthMethod, error)

SSHKeyAuth creates SSH key authentication from a file.

func SSHKeyAuthFromBytes

func SSHKeyAuthFromBytes(privateKey []byte, password string) (transport.AuthMethod, error)

SSHKeyAuthFromBytes creates SSH key authentication from bytes.

func TokenAuth

func TokenAuth(token string) transport.AuthMethod

TokenAuth creates HTTP token auth (for GitHub/GitLab tokens).

Types

type AST

type AST struct {
	Language    string            `json:"language"`
	FilePath    string            `json:"file_path"`
	Functions   []Function        `json:"functions"`
	Classes     []Class           `json:"classes"`
	Imports     []Import          `json:"imports"`
	Variables   []Variable        `json:"variables"`
	Comments    []Comment         `json:"comments"`
	Strings     []StringLiteral   `json:"strings"`
	CallSites   []CallSite        `json:"call_sites"`
	Annotations []Annotation      `json:"annotations,omitempty"`
	RawAST      interface{}       `json:"-"` // Language-specific AST
	Metadata    map[string]string `json:"metadata,omitempty"`
}

AST represents a parsed abstract syntax tree.

type Analyzer

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

Analyzer computes code metrics for parsed files. Security detection lives in internal/scanner/rules, not here.

func NewAnalyzer

func NewAnalyzer(cfg config.ScannerConfig, logger *logrus.Logger) *Analyzer

NewAnalyzer creates a new Analyzer.

func (*Analyzer) CalculateDuplication

func (a *Analyzer) CalculateDuplication(files []*ParsedFile) float64

CalculateDuplication detects code duplication.

func (*Analyzer) CalculateMetrics

func (a *Analyzer) CalculateMetrics(files []*ParsedFile) *CodeMetrics

CalculateMetrics calculates code metrics for parsed files.

type Annotation

type Annotation struct {
	Name      string   `json:"name"`
	Arguments []string `json:"arguments,omitempty"`
	Line      int      `json:"line"`
}

Annotation represents a code annotation/decorator.

type BranchInfo

type BranchInfo struct {
	Name       string    `json:"name"`
	SHA        string    `json:"sha"`
	LastCommit time.Time `json:"last_commit"`
	Author     string    `json:"author"`
}

BranchInfo represents information about a branch.

type CallSite

type CallSite struct {
	Name      string   `json:"name"`
	Receiver  string   `json:"receiver,omitempty"`
	Arguments []string `json:"arguments,omitempty"`
	Line      int      `json:"line"`
	Column    int      `json:"column"`
	IsMethod  bool     `json:"is_method"`
}

CallSite represents a function/method call.

type Class

type Class struct {
	Name        string     `json:"name"`
	Methods     []Function `json:"methods"`
	Fields      []Field    `json:"fields"`
	LineStart   int        `json:"line_start"`
	LineEnd     int        `json:"line_end"`
	IsExported  bool       `json:"is_exported"`
	Extends     string     `json:"extends,omitempty"`
	Implements  []string   `json:"implements,omitempty"`
	DocString   string     `json:"doc_string,omitempty"`
	Annotations []string   `json:"annotations,omitempty"`
}

Class represents a class/struct definition.

type CloneOptions

type CloneOptions struct {
	URL       string
	Branch    string
	CommitSHA string
	Depth     int
	Auth      transport.AuthMethod
	Timeout   time.Duration
}

CloneOptions holds options for cloning a repository.

type CloneResult

type CloneResult struct {
	Path       string
	CommitSHA  string
	Branch     string
	CommitInfo *CommitInfo
	Size       int64
}

CloneResult contains information about a cloned repository.

type CodeMetrics

type CodeMetrics struct {
	TotalFiles        int             `json:"total_files"`
	TotalLines        int             `json:"total_lines"`
	CodeLines         int             `json:"code_lines"`
	CommentLines      int             `json:"comment_lines"`
	BlankLines        int             `json:"blank_lines"`
	LanguageBreakdown map[string]int  `json:"language_breakdown"`
	FileTypeBreakdown map[string]int  `json:"file_type_breakdown"`
	AverageFileSize   float64         `json:"average_file_size"`
	LargestFiles      []FileSizeInfo  `json:"largest_files"`
	ComplexityScore   float64         `json:"complexity_score"`
	DuplicationScore  float64         `json:"duplication_score"`
	FunctionMetrics   FunctionMetrics `json:"function_metrics"`
}

CodeMetrics holds code quality metrics.

type Comment

type Comment struct {
	Text    string `json:"text"`
	Line    int    `json:"line"`
	LineEnd int    `json:"line_end,omitempty"`
	IsBlock bool   `json:"is_block"`
	IsDoc   bool   `json:"is_doc"`
}

Comment represents a code comment.

type CommitInfo

type CommitInfo struct {
	SHA        string    `json:"sha"`
	Author     string    `json:"author"`
	Email      string    `json:"email"`
	Message    string    `json:"message"`
	Timestamp  time.Time `json:"timestamp"`
	ParentSHAs []string  `json:"parent_shas,omitempty"`
}

CommitInfo holds information about a commit.

type Field

type Field struct {
	Name       string `json:"name"`
	Type       string `json:"type,omitempty"`
	Line       int    `json:"line"`
	IsExported bool   `json:"is_exported"`
	Tags       string `json:"tags,omitempty"` // For Go struct tags
}

Field represents a class/struct field.

type FileDiff

type FileDiff struct {
	FromPath string `json:"from_path"`
	ToPath   string `json:"to_path"`
	Action   string `json:"action"` // Insert, Delete, Modify
	Patch    string `json:"patch,omitempty"`
}

FileDiff represents a file diff.

type FileSizeInfo

type FileSizeInfo struct {
	Path  string `json:"path"`
	Lines int    `json:"lines"`
	Size  int64  `json:"size"`
}

FileSizeInfo holds size information for a file.

type Function

type Function struct {
	Name        string      `json:"name"`
	Parameters  []Parameter `json:"parameters"`
	ReturnType  string      `json:"return_type,omitempty"`
	Body        string      `json:"-"` // Not serialized to JSON
	LineStart   int         `json:"line_start"`
	LineEnd     int         `json:"line_end"`
	Complexity  int         `json:"complexity"`
	IsExported  bool        `json:"is_exported"`
	IsAsync     bool        `json:"is_async,omitempty"`
	Receiver    string      `json:"receiver,omitempty"` // For Go methods
	DocString   string      `json:"doc_string,omitempty"`
	Annotations []string    `json:"annotations,omitempty"`
}

Function represents a function definition.

type FunctionInfo

type FunctionInfo struct {
	Name       string   `json:"name"`
	StartLine  int      `json:"start_line"`
	EndLine    int      `json:"end_line"`
	Parameters []string `json:"parameters,omitempty"`
	ReturnType string   `json:"return_type,omitempty"`
	IsExported bool     `json:"is_exported"`
	Complexity int      `json:"complexity,omitempty"`
}

FunctionInfo holds simplified function information.

type FunctionMetrics

type FunctionMetrics struct {
	TotalFunctions      int     `json:"total_functions"`
	AverageFunctionSize float64 `json:"average_function_size"`
	LargestFunction     int     `json:"largest_function"`
	ExportedFunctions   int     `json:"exported_functions"`
	AverageComplexity   float64 `json:"average_complexity"`
}

FunctionMetrics holds function-related metrics.

type GenericParser

type GenericParser struct{}

GenericParser implements LanguageParser for unknown languages.

func (*GenericParser) GetLanguage

func (p *GenericParser) GetLanguage() string

func (*GenericParser) Parse

func (p *GenericParser) Parse(ctx context.Context, filePath string, content []byte) (*AST, error)

func (*GenericParser) SupportsFile

func (p *GenericParser) SupportsFile(path string) bool

type GitManager

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

GitManager handles Git repository operations with security considerations.

func NewGitManager

func NewGitManager(cfg config.GitConfig, logger *logrus.Logger) (*GitManager, error)

NewGitManager creates a new GitManager instance.

func (*GitManager) Cleanup

func (g *GitManager) Cleanup(path string) error

Cleanup removes a cloned repository.

func (*GitManager) CleanupAll

func (g *GitManager) CleanupAll() error

CleanupAll removes all cloned repositories.

func (*GitManager) CleanupOld

func (g *GitManager) CleanupOld(maxAge time.Duration) error

CleanupOld removes repositories older than the specified duration.

func (*GitManager) Clone

func (g *GitManager) Clone(ctx context.Context, opts CloneOptions) (*CloneResult, error)

Clone clones a repository with full options.

func (*GitManager) CloneRepository

func (g *GitManager) CloneRepository(ctx context.Context, repoURL, branch string) (*CloneResult, error)

CloneRepository clones a repository to a temporary directory.

func (*GitManager) GetBranches

func (g *GitManager) GetBranches(repoPath string) ([]BranchInfo, error)

GetBranches returns all branches in a repository.

func (*GitManager) GetChangedFiles

func (g *GitManager) GetChangedFiles(ctx context.Context, repoPath, fromCommit, toCommit string) ([]string, error)

GetChangedFiles returns files changed between two commits.

func (*GitManager) GetCommitInfo

func (g *GitManager) GetCommitInfo(repoPath, sha string) (*CommitInfo, error)

GetCommitInfo returns information about a specific commit.

func (*GitManager) GetDiff

func (g *GitManager) GetDiff(repoPath, fromSHA, toSHA string) ([]FileDiff, error)

GetDiff returns the diff between two commits.

func (*GitManager) GetFileContent

func (g *GitManager) GetFileContent(repoPath, filePath, commit string) ([]byte, error)

GetFileContent reads file content at a specific commit.

func (*GitManager) GetRecentCommits

func (g *GitManager) GetRecentCommits(repoPath string, limit int) ([]CommitInfo, error)

GetRecentCommits returns the most recent commits.

func (*GitManager) GetTags

func (g *GitManager) GetTags(repoPath string) ([]TagInfo, error)

GetTags returns all tags in a repository.

func (*GitManager) ListFiles

func (g *GitManager) ListFiles(repoPath string, filterFunc func(string) bool) ([]string, error)

ListFiles lists all files in the repository.

func (*GitManager) ValidateRepositoryURL

func (g *GitManager) ValidateRepositoryURL(repoURL string) error

ValidateRepositoryURL validates that a repository URL is allowed.

type GoParser

type GoParser struct{}

GoParser implements LanguageParser for Go.

func (*GoParser) GetLanguage

func (p *GoParser) GetLanguage() string

func (*GoParser) Parse

func (p *GoParser) Parse(ctx context.Context, filePath string, content []byte) (*AST, error)

func (*GoParser) SupportsFile

func (p *GoParser) SupportsFile(path string) bool

type Import

type Import struct {
	Path  string `json:"path"`
	Alias string `json:"alias,omitempty"`
	Line  int    `json:"line"`
	IsStd bool   `json:"is_std,omitempty"` // Is standard library
}

Import represents an import statement.

type ImportInfo

type ImportInfo struct {
	Path  string `json:"path"`
	Alias string `json:"alias,omitempty"`
	Line  int    `json:"line"`
}

ImportInfo holds simplified import information.

type JavaParser

type JavaParser struct{}

JavaParser implements LanguageParser for Java.

func (*JavaParser) GetLanguage

func (p *JavaParser) GetLanguage() string

func (*JavaParser) Parse

func (p *JavaParser) Parse(ctx context.Context, filePath string, content []byte) (*AST, error)

func (*JavaParser) SupportsFile

func (p *JavaParser) SupportsFile(path string) bool

type JavaScriptParser

type JavaScriptParser struct{}

JavaScriptParser implements LanguageParser for JavaScript.

func (*JavaScriptParser) GetLanguage

func (p *JavaScriptParser) GetLanguage() string

func (*JavaScriptParser) Parse

func (p *JavaScriptParser) Parse(ctx context.Context, filePath string, content []byte) (*AST, error)

func (*JavaScriptParser) SupportsFile

func (p *JavaScriptParser) SupportsFile(path string) bool

type LanguageParser

type LanguageParser interface {
	Parse(ctx context.Context, filePath string, content []byte) (*AST, error)
	GetLanguage() string
	SupportsFile(filePath string) bool
}

LanguageParser interface for language-specific parsers.

type Manager

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

Manager orchestrates the scanning process (basic manager).

func NewManager

func NewManager(
	scannerCfg config.ScannerConfig,
	gitCfg config.GitConfig,
	logger *logrus.Logger,
) *Manager

NewManager creates a new scan Manager.

func (*Manager) Scan

func (m *Manager) Scan(ctx context.Context, repo *models.Repository, scan *models.Scan, opts ScanOptions) (*ScanResult, error)

Scan performs a full security scan on a repository (original method).

func (*Manager) ScanPath

func (m *Manager) ScanPath(ctx context.Context, scanID uuid.UUID, path string, opts ScanOptions) (*ScanResult, error)

ScanPath performs a scan on a local path.

func (*Manager) ScanTarget

func (m *Manager) ScanTarget(ctx context.Context, scanID uuid.UUID, t Target, opts ScanOptions) (*ScanResult, error)

ScanTarget dispatches a scan by target type. Source targets reuse ScanPath so git-with-auth and a local directory converge on the same analysis path.

func (*Manager) ValidatePath

func (m *Manager) ValidatePath(path string) error

ValidatePath validates that a path is safe to scan.

type PHPParser

type PHPParser struct{}

PHPParser implements LanguageParser for PHP.

func (*PHPParser) GetLanguage

func (p *PHPParser) GetLanguage() string

func (*PHPParser) Parse

func (p *PHPParser) Parse(ctx context.Context, filePath string, content []byte) (*AST, error)

func (*PHPParser) SupportsFile

func (p *PHPParser) SupportsFile(path string) bool

type Parameter

type Parameter struct {
	Name     string `json:"name"`
	Type     string `json:"type,omitempty"`
	Default  string `json:"default,omitempty"`
	Variadic bool   `json:"variadic,omitempty"`
}

Parameter represents a function parameter.

type ParsedFile

type ParsedFile struct {
	Path            string           `json:"path"`
	Content         []byte           `json:"-"`
	Lines           []string         `json:"-"`
	Language        string           `json:"language"`
	LineCount       int              `json:"line_count"`
	Size            int64            `json:"size"`
	AST             *AST             `json:"ast,omitempty"`
	Functions       []FunctionInfo   `json:"functions,omitempty"`
	Imports         []ImportInfo     `json:"imports,omitempty"`
	Strings         []StringLiteral  `json:"strings,omitempty"`
	SecurityMarkers []SecurityMarker `json:"security_markers,omitempty"`
	Checksum        string           `json:"checksum,omitempty"`
}

ParsedFile represents a parsed source file with additional metadata.

func (*ParsedFile) GetContent

func (f *ParsedFile) GetContent() []byte

GetContent returns the file content.

func (*ParsedFile) GetLanguage

func (f *ParsedFile) GetLanguage() string

GetLanguage returns the file language.

func (*ParsedFile) GetLines

func (f *ParsedFile) GetLines() []string

GetLines returns the file lines.

func (*ParsedFile) GetPath

func (f *ParsedFile) GetPath() string

GetPath returns the file path.

type Parser

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

Parser handles source code parsing with multi-language support.

func NewParser

func NewParser(cfg config.ScannerConfig, logger *logrus.Logger) *Parser

NewParser creates a new Parser.

func (*Parser) ParseFile

func (p *Parser) ParseFile(path, language string) (*ParsedFile, error)

ParseFile parses a single file.

func (*Parser) ParseRepository

func (p *Parser) ParseRepository(ctx context.Context, repoPath string, excludedPaths []string, maxFiles int, pathPrefix string) ([]*ParsedFile, []ScanError, error)

ParseRepository parses all files in a repository.

Files are returned sorted by path. Parsing runs concurrently, so append order is nondeterministic; anything downstream that truncates, diffs, or assigns an ordinal to a finding needs a stable order to be reproducible.

The second return value lists files that were reached but could not be parsed. A dropped file yields no findings, which is indistinguishable from a clean file — and in a delta, indistinguishable from a fixed one. maxFiles caps how many files are read; 0 falls back to the configured limit. The cap is applied during the walk, in lexical order, so the scanned set is the same on every run. Truncating the parsed slice afterwards is not, because parsing is concurrent.

func (*Parser) RegisterParser

func (p *Parser) RegisterParser(parser LanguageParser)

RegisterParser registers a language-specific parser.

type PythonParser

type PythonParser struct{}

PythonParser implements LanguageParser for Python.

func (*PythonParser) GetLanguage

func (p *PythonParser) GetLanguage() string

func (*PythonParser) Parse

func (p *PythonParser) Parse(ctx context.Context, filePath string, content []byte) (*AST, error)

func (*PythonParser) SupportsFile

func (p *PythonParser) SupportsFile(path string) bool

type RubyParser

type RubyParser struct{}

RubyParser implements LanguageParser for Ruby.

func (*RubyParser) GetLanguage

func (p *RubyParser) GetLanguage() string

func (*RubyParser) Parse

func (p *RubyParser) Parse(ctx context.Context, filePath string, content []byte) (*AST, error)

func (*RubyParser) SupportsFile

func (p *RubyParser) SupportsFile(path string) bool

type ScanError

type ScanError struct {
	File    string `json:"file"`
	Message string `json:"message"`
	Phase   string `json:"phase"`
}

ScanError represents an error during scanning.

type ScanOptions

type ScanOptions struct {
	EnabledRules  []string `json:"enabled_rules,omitempty"`
	MaxFiles      int      `json:"max_files,omitempty"`
	ExcludedPaths []string `json:"excluded_paths,omitempty"`
	Timeout       time.Duration
	Branch        string `json:"branch,omitempty"`
	CommitSHA     string `json:"commit_sha,omitempty"`

	// PathPrefix is prepended to every reported file path. Scanning a
	// subdirectory would otherwise report paths relative to that subdirectory,
	// and since the path feeds the fingerprint, a subdirectory scan could never
	// be compared against a baseline taken from the whole tree.
	PathPrefix string `json:"path_prefix,omitempty"`
}

ScanOptions holds options for a scan.

type ScanResult

type ScanResult struct {
	Vulnerabilities []models.Vulnerability
	Metrics         CodeMetrics
	FilesScanned    int
	LinesScanned    int
	Duration        time.Duration
	Errors          []ScanError
}

ScanResult holds the result of a scan.

type SecurityMarker

type SecurityMarker struct {
	Type        string `json:"type"` // sql_query, exec, eval, etc.
	Description string `json:"description"`
	Line        int    `json:"line"`
	Column      int    `json:"column"`
	Snippet     string `json:"snippet"`
}

SecurityMarker represents security-sensitive code markers.

type StringLiteral

type StringLiteral struct {
	Value      string `json:"value"`
	Line       int    `json:"line"`
	Column     int    `json:"column"`
	IsRaw      bool   `json:"is_raw,omitempty"`
	IsTemplate bool   `json:"is_template,omitempty"`
}

StringLiteral represents a string literal in code.

type TagInfo

type TagInfo struct {
	Name    string    `json:"name"`
	SHA     string    `json:"sha"`
	Message string    `json:"message,omitempty"`
	Tagger  string    `json:"tagger,omitempty"`
	Date    time.Time `json:"date"`
}

TagInfo represents information about a tag.

type Target

type Target struct {
	Type      TargetType
	Path      string               // source_local
	URL       string               // source_git repo URL (or live_url endpoint, later)
	Branch    string               // source_git
	CommitSHA string               // source_git
	Auth      transport.AuthMethod // source_git private-repo auth (nil = public)
}

Target describes what to assess. It is the single seam through which SAST today and DAST later both reach the Manager: a new engine adds an arm to ScanTarget and returns the same *ScanResult, leaving the CLI, report renderer, and engagement config untouched.

type TargetType

type TargetType string

TargetType is what a scan points at. Source types are implemented today; live_url is the declared seam for the future DAST engine.

const (
	TargetSourceLocal TargetType = "source_local" // a directory on disk
	TargetSourceGit   TargetType = "source_git"   // a git repo, cloned then scanned
	TargetLiveURL     TargetType = "live_url"     // DAST — see docs/DAST_ROADMAP.md
)

type TypeScriptParser

type TypeScriptParser struct{}

TypeScriptParser implements LanguageParser for TypeScript.

func (*TypeScriptParser) GetLanguage

func (p *TypeScriptParser) GetLanguage() string

func (*TypeScriptParser) Parse

func (p *TypeScriptParser) Parse(ctx context.Context, filePath string, content []byte) (*AST, error)

func (*TypeScriptParser) SupportsFile

func (p *TypeScriptParser) SupportsFile(path string) bool

type Variable

type Variable struct {
	Name       string `json:"name"`
	Type       string `json:"type,omitempty"`
	Value      string `json:"value,omitempty"`
	Line       int    `json:"line"`
	IsConstant bool   `json:"is_constant"`
	IsExported bool   `json:"is_exported"`
	Scope      string `json:"scope,omitempty"` // global, local, class
}

Variable represents a variable declaration.

Directories

Path Synopsis
Package rules provides the rule engine for vulnerability detection.
Package rules provides the rule engine for vulnerability detection.

Jump to

Keyboard shortcuts

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