Documentation
¶
Overview ¶
Package security provides SQL injection detection and security scanning for GoSQLX.
The primary entry points are NewScanner (creates a scanner that reports all severity levels), NewScannerWithSeverity (creates a scanner filtered to a minimum severity), Scanner.Scan (analyzes a parsed *ast.AST via deep tree traversal), and Scanner.ScanSQL (analyzes a raw SQL string using pre-compiled regex patterns). Both methods return a *ScanResult containing all Findings with severity, pattern type, risk description, and remediation suggestions, plus summary counts accessible via HasCritical(), HasHighOrAbove(), and IsClean().
Overview ¶
The security scanner performs static analysis on SQL to detect potential injection attacks and unsafe patterns. It uses a combination of AST traversal, pattern matching, and heuristic analysis to identify security issues.
Pattern Detection ¶
The scanner detects 8 types of SQL injection patterns:
- TAUTOLOGY: Always-true conditions (1=1, 'a'='a') used to bypass authentication
- COMMENT_BYPASS: Comment-based injection (--, /**/, #) to bypass validation
- UNION_BASED: UNION SELECT patterns for data extraction and schema enumeration
- STACKED_QUERY: Multiple statements with destructive operations (DROP, DELETE)
- TIME_BASED: Time delay functions (SLEEP, WAITFOR, pg_sleep) for blind injection
- OUT_OF_BAND: External data exfiltration (xp_cmdshell, LOAD_FILE, UTL_HTTP)
- DANGEROUS_FUNCTION: Dynamic SQL execution (EXEC, sp_executesql, PREPARE FROM)
- BOOLEAN_BASED: Conditional logic exploitation for data extraction
Severity Levels ¶
Each finding is assigned one of four severity levels:
- CRITICAL: Definite injection pattern detected (e.g., OR 1=1 --)
- HIGH: Highly suspicious patterns requiring immediate review
- MEDIUM: Potentially unsafe patterns that need investigation
- LOW: Informational findings and best practice violations
Basic Usage ¶
AST-based scanning:
import (
"github.com/ajitpratap0/GoSQLX/pkg/sql/parser"
"github.com/ajitpratap0/GoSQLX/pkg/sql/security"
)
// Parse SQL into AST
ast, err := parser.Parse(tokens)
if err != nil {
log.Fatal(err)
}
// Scan for security issues
scanner := security.NewScanner()
results := scanner.Scan(ast)
// Review findings
for _, finding := range results.Findings {
fmt.Printf("[%s] %s: %s\n",
finding.Severity,
finding.Pattern,
finding.Description)
}
Raw SQL scanning:
scanner := security.NewScanner()
results := scanner.ScanSQL("SELECT * FROM users WHERE id = 1 OR 1=1 --")
if results.HasCritical() {
fmt.Println("CRITICAL security issues found!")
for _, f := range results.Findings {
fmt.Printf(" - %s: %s\n", f.Pattern, f.Description)
fmt.Printf(" Risk: %s\n", f.Risk)
fmt.Printf(" Suggestion: %s\n", f.Suggestion)
}
}
Filtering by Severity ¶
Filter findings by minimum severity level:
// Only report HIGH and CRITICAL findings
scanner, err := security.NewScannerWithSeverity(security.SeverityHigh)
if err != nil {
log.Fatal(err)
}
results := scanner.Scan(ast)
fmt.Printf("Found %d high-severity issues\n", results.HighCount + results.CriticalCount)
Scan Results ¶
The ScanResult structure provides comprehensive information:
results := scanner.Scan(ast)
fmt.Printf("Total findings: %d\n", results.TotalCount)
fmt.Printf("Critical: %d, High: %d, Medium: %d, Low: %d\n",
results.CriticalCount,
results.HighCount,
results.MediumCount,
results.LowCount)
// Check severity thresholds
if results.IsClean() {
fmt.Println("No security issues detected")
}
if results.HasHighOrAbove() {
fmt.Println("High-priority security issues require attention")
}
Finding Details ¶
Each Finding contains detailed information:
for _, finding := range results.Findings {
fmt.Printf("Pattern: %s\n", finding.Pattern) // Pattern type
fmt.Printf("Severity: %s\n", finding.Severity) // Risk level
fmt.Printf("Description: %s\n", finding.Description) // What was found
fmt.Printf("Risk: %s\n", finding.Risk) // Security impact
fmt.Printf("Suggestion: %s\n", finding.Suggestion) // Remediation advice
if finding.Line > 0 {
fmt.Printf("Location: Line %d, Column %d\n", finding.Line, finding.Column)
}
}
Performance Considerations ¶
The scanner uses pre-compiled regex patterns (initialized once at package load) for optimal performance. Scanning is thread-safe and suitable for concurrent use.
Production Integration ¶
Example CI/CD integration:
scanner := security.NewScanner()
results := scanner.ScanSQL(userProvidedSQL)
if results.HasCritical() {
// Block deployment
log.Fatal("CRITICAL security vulnerabilities detected")
}
if results.HasHighOrAbove() {
// Require security review
fmt.Println("WARNING: High-severity security issues require review")
}
Pattern Examples ¶
TAUTOLOGY detection:
"SELECT * FROM users WHERE username='admin' OR 1=1 --" → CRITICAL: Always-true condition detected
UNION_BASED detection:
"SELECT name FROM products UNION SELECT password FROM users" → CRITICAL: UNION-based data extraction
TIME_BASED detection:
"SELECT * FROM orders WHERE id=1 AND SLEEP(5)" → HIGH: Time-based blind injection
STACKED_QUERY detection:
"SELECT * FROM users; DROP TABLE users --" → CRITICAL: Stacked query with destructive operation
Version ¶
This package is part of GoSQLX v1.6.0 and is production-ready for enterprise use.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Finding ¶
type Finding struct {
// Severity indicates the risk level (CRITICAL, HIGH, MEDIUM, LOW)
Severity Severity `json:"severity"`
// Pattern indicates the type of injection pattern detected
Pattern PatternType `json:"pattern"`
// Description provides human-readable explanation of what was found
Description string `json:"description"`
// Risk describes the potential security impact
Risk string `json:"risk"`
// Line number where the issue was detected (if available)
Line int `json:"line,omitempty"`
// Column number where the issue was detected (if available)
Column int `json:"column,omitempty"`
// SQL contains the problematic SQL fragment (if available)
SQL string `json:"sql,omitempty"`
// Suggestion provides remediation advice
Suggestion string `json:"suggestion,omitempty"`
}
Finding represents a single security finding from the scanner. It contains detailed information about a detected vulnerability including severity, pattern type, location, and remediation suggestions.
type PatternType ¶
type PatternType string
PatternType categorizes the type of SQL injection pattern detected by the scanner. Each pattern type represents a specific attack vector or vulnerability class.
const ( // PatternTautology detects always-true conditions (1=1, 'a'='a') used to bypass authentication PatternTautology PatternType = "TAUTOLOGY" // PatternComment detects comment-based injection (--, /**/, #) to bypass validation PatternComment PatternType = "COMMENT_BYPASS" // PatternStackedQuery detects multiple statements with destructive operations (DROP, DELETE) PatternStackedQuery PatternType = "STACKED_QUERY" // PatternUnionBased detects UNION SELECT patterns for data extraction and schema enumeration PatternUnionBased PatternType = "UNION_BASED" // PatternUnionInjection detects UNION SELECT patterns with injection fingerprints (system // table access or NULL-column padding). This is a CRITICAL severity signal used by ScanSQL. PatternUnionInjection PatternType = "UNION_INJECTION" // PatternUnionGeneric detects any UNION SELECT pattern. HIGH severity — may be legitimate. // Used by ScanSQL to flag generic UNION SELECT for review. PatternUnionGeneric PatternType = "UNION_GENERIC" // PatternTimeBased detects time delay functions (SLEEP, WAITFOR, pg_sleep) for blind injection PatternTimeBased PatternType = "TIME_BASED" // PatternBooleanBased detects conditional logic exploitation for data extraction PatternBooleanBased PatternType = "BOOLEAN_BASED" // PatternOutOfBand detects external data exfiltration (xp_cmdshell, LOAD_FILE, UTL_HTTP) PatternOutOfBand PatternType = "OUT_OF_BAND" // PatternDangerousFunc detects dynamic SQL execution (EXEC, sp_executesql, PREPARE FROM) PatternDangerousFunc PatternType = "DANGEROUS_FUNCTION" )
type ScanResult ¶
type ScanResult struct {
// Findings contains all detected security issues
Findings []Finding `json:"findings"`
// TotalCount is the total number of findings across all severity levels
TotalCount int `json:"total_count"`
// CriticalCount is the number of CRITICAL severity findings
CriticalCount int `json:"critical_count"`
// HighCount is the number of HIGH severity findings
HighCount int `json:"high_count"`
// MediumCount is the number of MEDIUM severity findings
MediumCount int `json:"medium_count"`
// LowCount is the number of LOW severity findings
LowCount int `json:"low_count"`
}
ScanResult contains all findings from a security scan along with summary statistics. Use the helper methods HasCritical(), HasHighOrAbove(), and IsClean() to quickly assess the scan results.
func (*ScanResult) HasCritical ¶
func (r *ScanResult) HasCritical() bool
HasCritical returns true if any CRITICAL severity findings exist. Use this to quickly check for definite security vulnerabilities that require immediate attention.
Example:
if results.HasCritical() {
log.Fatal("CRITICAL security vulnerabilities detected - blocking deployment")
}
func (*ScanResult) HasHighOrAbove ¶
func (r *ScanResult) HasHighOrAbove() bool
HasHighOrAbove returns true if any HIGH or CRITICAL severity findings exist. Use this to check for issues that require security review before deployment.
Example:
if results.HasHighOrAbove() {
fmt.Println("WARNING: High-priority security issues require review")
// Trigger security team notification
}
func (*ScanResult) IsClean ¶
func (r *ScanResult) IsClean() bool
IsClean returns true if no findings of any severity level exist. A clean result indicates no security issues were detected.
Example:
if results.IsClean() {
fmt.Println("✓ No security issues detected")
} else {
fmt.Printf("⚠ Found %d security issues\n", results.TotalCount)
}
type Scanner ¶
type Scanner struct {
// MinSeverity filters findings below this severity level.
// Only findings with severity >= MinSeverity are included in results.
MinSeverity Severity
}
Scanner performs security analysis on SQL ASTs and raw SQL strings. It detects SQL injection patterns using a combination of AST traversal, regex pattern matching, and heuristic analysis.
Scanner is safe for concurrent use from multiple goroutines as it uses pre-compiled patterns and maintains no mutable state during scanning.
Example usage:
scanner := security.NewScanner()
results := scanner.Scan(ast)
if results.HasCritical() {
log.Fatal("Critical security issues detected")
}
func NewScanner ¶
func NewScanner() *Scanner
NewScanner creates a new security scanner with default settings. The default scanner reports all findings (MinSeverity = SeverityLow).
The scanner is immediately ready to use and is safe for concurrent scanning from multiple goroutines.
Example:
scanner := security.NewScanner() results := scanner.Scan(ast)
func NewScannerWithSeverity ¶
NewScannerWithSeverity creates a scanner filtering by minimum severity. Only findings at or above the specified severity level will be reported.
Returns an error if the severity level is not recognized. Valid severity levels are: SeverityLow, SeverityMedium, SeverityHigh, SeverityCritical.
Example:
// Only report HIGH and CRITICAL findings
scanner, err := security.NewScannerWithSeverity(security.SeverityHigh)
if err != nil {
log.Fatal(err)
}
results := scanner.Scan(ast)
func (*Scanner) Scan ¶
func (s *Scanner) Scan(tree *ast.AST) *ScanResult
Scan analyzes a parsed SQL AST for SQL injection patterns and vulnerabilities. It performs deep traversal of the AST to detect suspicious patterns including tautologies, dangerous functions, UNION-based injection, and other attack vectors.
The method is safe for concurrent use as it does not modify the Scanner state.
Returns a ScanResult containing all detected findings that meet the MinSeverity threshold, along with summary statistics by severity level.
Example:
ast, err := parser.Parse(tokens)
if err != nil {
log.Fatal(err)
}
scanner := security.NewScanner()
results := scanner.Scan(ast)
fmt.Printf("Found %d security issues\n", results.TotalCount)
for _, finding := range results.Findings {
fmt.Printf("[%s] %s\n", finding.Severity, finding.Description)
}
func (*Scanner) ScanSQL ¶
func (s *Scanner) ScanSQL(sql string) *ScanResult
ScanSQL analyzes raw SQL string for injection patterns using regex-based detection. This method is useful for detecting patterns that might not be visible in the AST, such as SQL comments, or when you don't have a parsed AST available.
The method uses pre-compiled regex patterns to detect:
- Comment-based injection (--, /**/, #)
- Time-based blind injection (SLEEP, WAITFOR, pg_sleep, BENCHMARK)
- Out-of-band data exfiltration (xp_cmdshell, LOAD_FILE, UTL_HTTP)
- Dangerous functions (EXEC, sp_executesql, PREPARE FROM)
- UNION-based injection (UNION SELECT, information_schema)
- Stacked query injection (semicolon-separated destructive statements)
The method is safe for concurrent use.
Example:
scanner := security.NewScanner()
results := scanner.ScanSQL("SELECT * FROM users WHERE id = 1 OR 1=1 --")
if results.HasCritical() {
fmt.Println("CRITICAL security issue detected!")
for _, finding := range results.Findings {
fmt.Printf(" %s: %s\n", finding.Pattern, finding.Description)
}
}
type Severity ¶
type Severity string
Severity represents the severity level of a security finding. It is used to categorize the risk and priority of detected vulnerabilities.
const ( // SeverityCritical indicates definite injection (e.g., OR 1=1 --) SeverityCritical Severity = "CRITICAL" // SeverityHigh indicates likely injection (suspicious patterns) SeverityHigh Severity = "HIGH" // SeverityMedium indicates potentially unsafe patterns (needs review) SeverityMedium Severity = "MEDIUM" // SeverityLow indicates informational findings SeverityLow Severity = "LOW" )