WAF Rules
A WAF can block obvious SQL injection patterns before they reach your app — UNION SELECT, OR 1=1, comment-based comment injection. Use it as defense in depth alongside parameterised queries, not as your only line of defense.
Cloudflare, AWS WAF, ModSec, bypasses
EXAMPLE
// SCENARIO — defensive engineering: how to deploy + tune a WAF specifically against SQLi.
// Authorised testing of your own staging.
// 1) Managed SQLi rule sets — start with the basics
// AWS WAF: AWSManagedRulesSQLiRuleSet
// Cloudflare: OWASP Core Rule Set (Pro+) — rule family 942
// Azure App Gateway WAF: OWASP CRS (built-in)
// ModSecurity nginx: install CRS, ID 942100-942999
# AWS WAF — Terraform
resource "aws_wafv2_web_acl" "sqli" {
name = "sqli-acl"
scope = "REGIONAL"
default_action { allow {} }
rule {
name = "sqli-managed"
priority = 1
override_action { none {} }
statement {
managed_rule_group_statement {
vendor_name = "AWS"
name = "AWSManagedRulesSQLiRuleSet"
}
}
visibility_config {
sampled_requests_enabled = true
cloudwatch_metrics_enabled = true
metric_name = "sqli"
}
}
}
// 2) Cloudflare Custom Rule — block obvious payload patterns
// Dashboard → Security → WAF → Custom rules
expression: '(http.request.uri.query contains " UNION SELECT ")
or (http.request.uri.query matches "\\\\\\\\bselect\\\\s+(\\\\*|\\\\w+)\\\\s+from\\\\b")
or (http.request.body contains "' OR 1=1")
or (http.request.body matches "\\\\\\\\b(drop|truncate)\\\\s+table\\\\b")'
action: block
// 3) ModSecurity / nginx + CRS
# /etc/nginx/modsec/main.conf
Include /etc/modsecurity.d/owasp-crs/rules/*.conf
SecRuleEngine DetectionOnly # start here
SecAuditEngine On
SecAuditLog /var/log/modsec_audit.log
SecPcreMatchLimit 100000
SecPcreMatchLimitRecursion 100000
# Tune: remove specific rule if false positive
SecRuleRemoveById 942100 # 'SQL Injection Attack: SQL Tautology Detected'
# Once stable:
SecRuleEngine On
// 4) Detection-only first
// Block mode kills legitimate traffic. Steps:
// 1. Enable detect-only / 'count' mode
// 2. Wait 1-2 weeks; analyse hits
// 3. Tune false positives (legitimate ' in name field → false positive)
// 4. Enable block mode
// 5. Monitor 24h for collateral damage
// 5) Anti-bypass — multiple layers
// WAF alone is insufficient. Attackers bypass via:
// • URL encoding ('%27%20OR%201%3D1')
// • Double encoding ('%2527')
// • Mixed case (UnIoN SeLeCt)
// • Comment injection (UN/**/ION SE/**/LECT)
// • Whitespace tricks (\t\n)
// • Different parsers (HPP — multiple ?id=1&id=2)
// • Encoding the entire payload via JSON / base64
//
// Pair WAF with:
// • Parameterised queries (the actual fix)
// • Input validation (Zod schema)
// • Least-privilege DB user
// • Audit logging
// • Code review for raw SQL
// 6) Custom rules — tighten for your app shape
// You know your app's expected inputs. Block what makes no sense for you.
// Block SQL keywords in fields that should be numeric IDs only
expression: '(http.request.uri.path matches "^/api/orders/\\\\d+$")
and (http.request.uri.query matches "[a-zA-Z]")'
action: block
// Block requests with > 5 single quotes in the body
expression: '(http.request.body matches "('.*){5,}")'
action: block
// Disallow request paths your API doesn't use
expression: '(http.request.uri.path matches "^/(admin|wp-admin|phpmyadmin)")'
action: block
// 7) Rate limiting + IP reputation
// SQLi probing tends to spam many variants. Rate limits curb it.
// • AWS WAF: rate-based rules (limit per 5 min per IP)
// • Cloudflare: rate-limiting rules
// • ModSec: ip block lists from CRS-Plus
// Also subscribe to:
// • AbuseIPDB
// • Cloudflare Threat Intel
// • Proofpoint Emerging Threats
// 8) Logging + SIEM integration
// • Cloudflare Logpush → S3 → Splunk / Datadog / Sumo
// • AWS WAF logs → S3 → Athena queries / OpenSearch
// • ModSec audit log (massive — rotate hourly)
// • Tag each blocked event with: rule id, URI, source IP, user-agent, payload sample
// 9) Correlation: WAF + app + DB logs
// A successful SQLi (WAF missed it) might show:
// • Sudden CPU spike in DB
// • Slow queries in pg_stat_statements
// • Unusual joins on system tables
// • Anomalous data access patterns (one user reading many tables)
//
// Build dashboards correlating WAF + app + DB telemetry.
// 10) Lock down origin
// If origin IP is public, attackers bypass WAF by direct connection.
// • CloudFront → ALB with origin verify header
// • Cloudflare Tunnel — origin never has public IP
// • Security group: allow ONLY the CDN's IP range
//
// CloudFront example:
resource "aws_security_group" "alb" {
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
prefix_list_ids = [data.aws_ec2_managed_prefix_list.cloudfront.id]
}
}
// 11) Testing your WAF (authorised + on staging)
// • OWASP ZAP active scan with SQLi profile
// • Burp Suite — manual probes
// • sqlmap (against your STAGING with authorisation)
// sqlmap -u 'https://staging.example.com/api?id=1' --batch --tamper=between
// • Track WAF block rate; tune rules until it catches >95% of common payloads
// 12) When WAF blocks legitimate traffic
// • Whitelist trusted IPs (corporate, partners) via 'bypass' rule
// • Customer-reported false positives → investigate raw log, identify rule, suppress
// • Don't blanket disable rules; suppress for specific URI patterns
SecRuleUpdateTargetById 942100 "!ARGS:customer_notes" // exempt this field from rule 942100
// 13) Anti-patterns
// • WAF as the only defense — bypasses exist; ship secure code
// • Disabling rules globally to silence false positives — leaves the door open
// • No log monitoring — you don't know attacks are happening
// • Origin not locked down — attackers connect directly
// • Same payload patterns block legitimate user inputs (' in names, e.g. O'Brien) — tune carefully
// • Treating WAF for compliance only (PCI DSS 6.6) without operational value
// 14) Detection signals to alert on
// • >10 blocked SQLi attempts from one IP in 5 min — likely scanner
// • New SQL keyword in request body where none expected
// • New User-Agent paired with SQLi probe — automated tool fingerprint
// • Sudden spike in 403/406 responses — WAF actively defending
// • DB query plan changes in pg_stat_statements — suspicious queries getting through
// 15) Common bugs
// • Trusting X-Forwarded-For from anywhere → IP spoofing; rate limit fails
// • WAF rules in front of Cloud Run / Lambda but origin allows direct invocation → bypass
// • Forgot to enable bot management — automated probes flood your origin
// • Generic WAF in production but ignored false-positive reports — users frustrated
// • Block message generic ('403 Forbidden') — legitimate users can't self-diagnose; customise
// • Migrating from one WAF to another without parallel running — coverage gap
// • Letting CRS go stale — security rules updated regularly; pull updates monthly
// • CDN cache poisoning of error pages — exposed sensitive paths visible to attackers
Why it matters
A SQLi WAF (AWS Managed Rules, OWASP CRS) is defense in depth, not the fix. Start in detect-only, tune false positives, lock down origin so attackers can’t bypass the CDN, and pair with parameterised queries plus rate limiting and SIEM-fed dashboards. Treat the WAF as a noisy alarm system — the secure code is the lock.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
// WAF blocks the easy cases (e.g. ' OR 1=1 --) but DON'T rely on it. // It's defence-in-depth — your fix is in the code.Try it Yourself »
Discussion
Loading…