SQL Injection Attacks
SQL Injection Attacks
SQL injection remains a critical threat to web applications, allowing attackers to manipulate database queries through malicious input. While application-level defenses are primary, firewalls provide an additional security layer by detecting and blocking common injection patterns.
Modern SQL injection attacks use various encoding and obfuscation techniques to bypass simple pattern matching. Effective firewall rules must understand these evasion methods:
# SQL injection detection module
import re
import urllib.parse
import base64
class SQLInjectionDetector:
def __init__(self):
# Common SQL injection patterns
self.patterns = [
# Basic patterns
r"(\bunion\b.*\bselect\b|\bselect\b.*\bfrom\b|\binsert\b.*\binto\b)",
r"(\bdrop\b.*\btable\b|\bcreate\b.*\btable\b|\balter\b.*\btable\b)",
r"(\bexec\b|\bexecute\b)\s*\(",
# Encoded patterns
r"(\%27|\')(\%6F|o|\%4F)(\%72|r|\%52)", # 'or
r"(\%27|\')(\%3D|=)(\%27|\')", # '='
# Comment patterns
r"(--)|(\/\*.*\*\/)|(\#)",
# Advanced patterns
r"(benchmark|sleep|waitfor\s+delay)",
r"(group\s+by\s+\d+\s+having)",
r"(information_schema|sysobjects|syscolumns)",
]
self.compiled_patterns = [re.compile(p, re.IGNORECASE) for p in self.patterns]
def check_request(self, request_data):
# Decode and normalize input
decoded_data = self.decode_input(request_data)
# Check against patterns
for pattern in self.compiled_patterns:
if pattern.search(decoded_data):
return {
'detected': True,
'pattern': pattern.pattern,
'decoded_input': decoded_data[:200] # First 200 chars for logging
}
# Check for unusual encoding
if self.has_suspicious_encoding(request_data):
return {
'detected': True,
'pattern': 'suspicious_encoding',
'decoded_input': request_data[:200]
}
return {'detected': False}
def decode_input(self, data):
"""Decode various encoding formats"""
decoded = data
# URL decode
try:
decoded = urllib.parse.unquote(decoded)
except:
pass
# HTML decode
decoded = decoded.replace('<', '<').replace('>', '>')
decoded = decoded.replace('&', '&').replace('"', '"')
# Hex decode
decoded = re.sub(r'0x([0-9a-fA-F]+)',
lambda m: chr(int(m.group(1), 16)), decoded)
return decoded.lower()
WAF rules for SQL injection prevention:
# ModSecurity rules for SQL injection
SecRule ARGS "@detectSQLi" \
"id:1001,\
phase:2,\
block,\
msg:'SQL Injection Attack Detected',\
logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\
severity:'CRITICAL',\
setvar:'tx.sql_injection_score=+%{matched_var_severity}',\
setvar:'tx.anomaly_score_pl1=+%{matched_var_severity}'"
# Specific parameter protection
SecRule ARGS:id "!@rx ^[0-9]+$" \
"id:1002,\
phase:2,\
block,\
msg:'Non-numeric ID parameter',\
severity:'WARNING'"
# Block common SQL injection tools
SecRule REQUEST_HEADERS:User-Agent "@pm sqlmap havij sqlinject" \
"id:1003,\
phase:1,\
block,\
msg:'SQL Injection Tool Detected',\
severity:'CRITICAL'"