Class: AsktiveRecord::SqlSanitizer

Inherits:
Object
  • Object
show all
Defined in:
lib/asktive_record/sql_sanitizer.rb

Overview

SqlSanitizer provides robust SQL sanitization to prevent injection attacks from LLM-generated queries. It validates that queries are safe SELECT statements and blocks dangerous patterns like DDL, DML, and injection techniques.

Constant Summary collapse

DANGEROUS_KEYWORDS =

SQL keywords that indicate dangerous operations

%w[
  INSERT UPDATE DELETE DROP ALTER CREATE TRUNCATE
  REPLACE MERGE GRANT REVOKE EXEC EXECUTE
  CALL RENAME LOAD COPY INTO OUTFILE DUMPFILE
].freeze
INJECTION_PATTERNS =

Patterns that indicate SQL injection attempts

[
  /;\s*\S/i,                    # Semicolon followed by another statement
  /--\s/,                       # SQL line comment
  %r{/\*.*?\*/}m,               # SQL block comment
  /\bUNION\b.*\bSELECT\b/i, # UNION-based injection
  /\bINTO\s+OUTFILE\b/i,        # File write attempt
  /\bINTO\s+DUMPFILE\b/i,       # File dump attempt
  /\bLOAD_FILE\b/i,             # File read attempt
  /\bBENCHMARK\b/i,             # Time-based injection
  /\bSLEEP\b\s*\(/i,           # Time-based injection
  /\bIF\b\s*\(/i,              # Conditional injection (IF function)
  /\bCASE\s+WHEN\b.*\bTHEN\b.*\bWAITFOR\b/i, # Conditional time-based
  /\bWAITFOR\s+DELAY\b/i,      # MSSQL time-based injection
  /\bpg_sleep\b/i,             # PostgreSQL time-based injection
  /\bDBMS_LOCK\.SLEEP\b/i      # Oracle time-based injection
].freeze

Class Method Summary collapse

Class Method Details

.sanitize!(sql, allow_only_select: true) ⇒ String

Sanitizes the given SQL string. Raises AsktiveRecord::SanitizationError if the query is unsafe.

Parameters:

  • sql (String)

    the SQL string to sanitize

  • allow_only_select (Boolean) (defaults to: true)

    whether to restrict to SELECT-only (default: true)

Returns:

  • (String)

    the sanitized SQL string

Raises:



40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/asktive_record/sql_sanitizer.rb', line 40

def sanitize!(sql, allow_only_select: true)
  raise SanitizationError, "SQL query cannot be nil or empty." if sql.nil? || sql.strip.empty?

  cleaned = clean_sql(sql)

  validate_select_only!(cleaned) if allow_only_select

  check_dangerous_keywords!(cleaned)
  check_injection_patterns!(cleaned)

  cleaned
end