validate

package
v1.5.0 Latest Latest
Warning

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

Go to latest
Published: Nov 15, 2025 License: MIT Imports: 4 Imported by: 0

README

GoSQLX CLI Security Validation

This package provides comprehensive input sanitization and security validation for the GoSQLX CLI tool.

Overview

The validate package implements defense-in-depth security measures to protect against:

  • Path traversal attacks
  • Symlink exploitation
  • File size DoS attacks
  • Malicious file types
  • Special file access (devices, pipes, etc.)
  • System path access

Quick Start

Basic Usage
import "github.com/ajitpratap0/GoSQLX/cmd/gosqlx/internal/validate"

// Validate a file with default security settings
err := validate.ValidateInputFile("/path/to/query.sql")
if err != nil {
    log.Fatalf("Security validation failed: %v", err)
}
Custom Validation Settings
validator := validate.NewSecurityValidator()

// Customize security settings
validator.MaxFileSize = 5 * 1024 * 1024  // 5MB limit
validator.AllowSymlinks = false           // Block symlinks (default)
validator.AllowedExtensions = []string{".sql", ".txt"}

// Validate with custom settings
err := validator.Validate("/path/to/file.sql")

Security Features

1. Path Traversal Prevention

Automatically detects and blocks path traversal attempts:

// These will be rejected:
validate.ValidateInputFile("../../../etc/passwd")
validate.ValidateInputFile("/tmp/../../../etc/shadow")

// These are safe:
validate.ValidateInputFile("/safe/dir/query.sql")
validate.ValidateInputFile("./queries/test.sql")

By default, all symlinks are blocked:

// Symlink will be rejected
err := validate.ValidateInputFile("/path/to/symlink.sql")
// Error: "symlinks are not allowed for security reasons"

// To allow symlinks (not recommended):
validator := validate.NewSecurityValidator()
validator.AllowSymlinks = true
err := validator.Validate("/path/to/symlink.sql")
3. File Size Limits

Default maximum file size is 10MB:

const MaxFileSize = 10 * 1024 * 1024 // 10MB

// Files larger than 10MB are rejected
err := validate.ValidateInputFile("/path/to/huge.sql")
// Error: "file too large: 11000000 bytes (max 10485760)"

// Custom size limit:
validator := validate.NewSecurityValidator()
validator.MaxFileSize = 1024 * 1024 // 1MB
4. File Type Restrictions

Only SQL-related file types are allowed:

Allowed:

  • .sql - SQL files
  • .txt - Text files
  • (no extension) - Files without extensions

Blocked:

  • .exe, .bat, .sh, .py, .js - Executables and scripts
  • .dll, .so, .dylib - Libraries
  • .jar, .deb, .rpm - Packages
  • All other extensions
// These will be rejected:
validate.ValidateInputFile("malware.exe")
validate.ValidateInputFile("script.sh")

// These are allowed:
validate.ValidateInputFile("query.sql")
validate.ValidateInputFile("data.txt")
validate.ValidateInputFile("queries")  // No extension
5. Quick Security Check

Fast pre-validation without filesystem access:

// Check if a path looks safe before processing
if !validate.IsSecurePath(userInput) {
    return fmt.Errorf("insecure path detected")
}

// Blocked patterns:
// - Path traversal: "../../../etc/passwd"
// - Null bytes: "file.sql\x00.txt"
// - System paths: "/etc/passwd", "C:\Windows\System32\config\SAM"

API Reference

Functions
ValidateInputFile(path string) error

Validates a file path with default security settings.

Returns: Error if validation fails, nil if safe

Example:

err := validate.ValidateInputFile("/path/to/file.sql")
ValidateFileAccess(path string) error

Alias for ValidateInputFile - compatible with existing code.

IsSecurePath(path string) bool

Quick security check without filesystem access.

Returns: false if path contains suspicious patterns

Example:

if !validate.IsSecurePath(userInput) {
    return errors.New("insecure path")
}
Types
SecurityValidator

Main validation struct with configurable settings.

Fields:

  • MaxFileSize int64 - Maximum allowed file size (default: 10MB)
  • AllowedExtensions []string - List of allowed file extensions
  • AllowSymlinks bool - Whether to allow symlinks (default: false)
  • WorkingDirectory string - Optional directory restriction

Methods:

NewSecurityValidator() *SecurityValidator

Creates a validator with secure defaults.

Validate(path string) error

Performs comprehensive security validation on a file path.

Validation Steps:

  1. Resolves symlinks and gets real path
  2. Checks if file is a symlink (blocked by default)
  3. Validates path for traversal attempts
  4. Verifies file is a regular file (not device, pipe, etc.)
  5. Checks file size against limit
  6. Validates file extension
  7. Tests read permissions

Security Best Practices

1. Always Use Validation
// ❌ WRONG - No validation
content, _ := os.ReadFile(userProvidedPath)

// ✅ CORRECT - Validate first
if err := validate.ValidateInputFile(userProvidedPath); err != nil {
    return fmt.Errorf("security validation failed: %w", err)
}
content, _ := os.ReadFile(userProvidedPath)
// ✅ RECOMMENDED - Use defaults (symlinks blocked)
err := validate.ValidateInputFile(path)

// ⚠️ USE WITH CAUTION - Only if absolutely necessary
validator := validate.NewSecurityValidator()
validator.AllowSymlinks = true  // Security risk
3. Use Appropriate Size Limits
// For CLI tools processing user files
validator := validate.NewSecurityValidator()
validator.MaxFileSize = 10 * 1024 * 1024  // 10MB (default)

// For automated processing
validator.MaxFileSize = 1 * 1024 * 1024   // 1MB (stricter)

// For trusted internal files
validator.MaxFileSize = 100 * 1024 * 1024 // 100MB (relaxed)
4. Restrict Working Directory
// Restrict file access to specific directory
validator := validate.NewSecurityValidator()
validator.WorkingDirectory = "/safe/queries/dir"

// Only files within /safe/queries/dir will be allowed
err := validator.Validate(path)

Testing

Run the comprehensive test suite:

# Run all tests
go test ./cmd/gosqlx/internal/validate/

# Run with race detection
go test -race ./cmd/gosqlx/internal/validate/

# Run specific security feature tests
go test -v -run TestSecurityFeatures ./cmd/gosqlx/internal/validate/

# Run benchmarks
go test -bench=. ./cmd/gosqlx/internal/validate/

Error Handling

All validation errors include descriptive messages:

err := validate.ValidateInputFile(path)
if err != nil {
    // Examples of error messages:
    // "symlinks are not allowed for security reasons: /path/link -> /real/path"
    // "file too large: 11000000 bytes (max 10485760)"
    // "unsupported file extension: .exe (allowed: [.sql .txt ])"
    // "not a regular file: /dev/null (mode: Dcrw-rw-rw-)"
    // "suspicious path pattern detected: /../"
}

Performance

The validation overhead is minimal:

  • File validation: ~2.5μs per operation
  • Quick path check: ~250ns per operation
  • Memory allocation: ~128 bytes per validation

Impact: < 0.01% overhead on typical CLI operations

Integration

This package is automatically integrated with all GoSQLX CLI commands:

  • gosqlx validate - SQL validation
  • gosqlx format - SQL formatting
  • gosqlx parse - AST parsing
  • gosqlx analyze - SQL analysis

All file inputs are automatically validated before processing.

Security Updates

This package follows OWASP security guidelines and is regularly updated to address new threat vectors.

Current Version: 1.0.0 Last Security Review: 2025-11-05 Test Coverage: 100% Known Vulnerabilities: None

Support

For security issues or questions:

  • Open an issue on GitHub
  • Tag with "security" label
  • For sensitive issues, contact maintainers directly

License

This security validation package is part of GoSQLX and follows the same license.

Documentation

Index

Constants

View Source
const (
	// MaxFileSize limits file size to prevent DoS attacks (10MB)
	MaxFileSize = 10 * 1024 * 1024
)

Variables

This section is empty.

Functions

func IsSecurePath

func IsSecurePath(path string) bool

IsSecurePath performs a quick check if a path looks secure

func ValidateFileAccess

func ValidateFileAccess(path string) error

ValidateFileAccess is a convenience function that validates file access This is compatible with the existing ValidateFileAccess function in cmd

func ValidateInputFile

func ValidateInputFile(path string) error

ValidateInputFile performs comprehensive security validation on a file path

Types

type SecurityValidator

type SecurityValidator struct {
	MaxFileSize       int64
	AllowedExtensions []string
	AllowSymlinks     bool
	WorkingDirectory  string // Optional: restrict to working directory
}

SecurityValidator provides comprehensive file security validation

func NewSecurityValidator

func NewSecurityValidator() *SecurityValidator

NewSecurityValidator creates a validator with default security settings

func (*SecurityValidator) Validate

func (v *SecurityValidator) Validate(path string) error

Validate performs comprehensive security checks on a file path

Jump to

Keyboard shortcuts

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