iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

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…