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

WAF / RASP

Web Application Firewalls (WAFs) sit in front of your app and filter requests for known attack patterns — XSS, SQLi, RCE, command injection. They’re a defensive layer, not a substitute for secure code: combine WAF + CSP + input validation for defense in depth.

Cloudflare, AWS WAF, ModSecurity, rules

EXAMPLE
// 1) Where a WAF sits
//
//   Internet → DNS/CDN → WAF → Origin
//
// The WAF inspects HTTP requests + responses, decides allow/deny based on rules.
// Common deployments:
//   • Cloudflare WAF (managed)
//   • AWS WAF + CloudFront / ALB
//   • Azure Application Gateway WAF
//   • Google Cloud Armor
//   • ModSecurity (open-source; in nginx/apache)
//   • Caddy + Coraza (open-source ModSec port)

// 2) What a WAF blocks (typical XSS rules)
//   • <script tags in query params / body
//   • javascript: URL schemes
//   • on* event handlers (onload=, onerror=)
//   • iframe / object injection patterns
//   • Common XSS payload signatures (<svg onload=...>, document.cookie)
//   • SQLi (' OR 1=1, UNION SELECT)
//   • RCE / shell injection (; cat /etc/passwd)
//   • Local file inclusion (../etc/passwd)
//   • XML external entity attacks

// 3) Cloudflare WAF — simplest entry point
// • Free tier: basic managed ruleset
// • Pro+ : OWASP Core Rule Set; custom rules
// • Rules + Page Rules language: 'http.request.uri contains "' OR action=block'

// Custom Rule (Cloudflare UI / Terraform):
resource "cloudflare_filter" "block_sqli" {
    zone_id     = var.zone_id
    description = "Block obvious SQLi"
    expression  = "(http.request.uri.query contains \" UNION SELECT\") or (http.request.body contains \"' OR 1=1\")"
}

resource "cloudflare_firewall_rule" "block_sqli" {
    zone_id     = var.zone_id
    filter_id   = cloudflare_filter.block_sqli.id
    action      = "block"
    description = "Block obvious SQLi"
}

// 4) AWS WAF — managed + custom rules
// • Managed Rule Groups: 'AWS-AWSManagedRulesCommonRuleSet', 'AWSManagedRulesSQLiRuleSet'
// • Web ACL attached to ALB / CloudFront / API Gateway / AppSync

# Terraform example
resource "aws_wafv2_web_acl" "main" {
    name  = "main"
    scope = "CLOUDFRONT"
    default_action { allow {} }

    rule {
        name     = "common"
        priority = 1
        override_action { none {} }
        statement {
            managed_rule_group_statement {
                vendor_name = "AWS"
                name        = "AWSManagedRulesCommonRuleSet"
            }
        }
        visibility_config { sampled_requests_enabled = true; cloudwatch_metrics_enabled = true; metric_name = "common" }
    }

    rule {
        name     = "sqli"
        priority = 2
        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" }
    }

    rule {
        name     = "rate-limit"
        priority = 3
        action { block {} }
        statement {
            rate_based_statement {
                limit              = 2000
                aggregate_key_type = "IP"
            }
        }
        visibility_config { sampled_requests_enabled = true; cloudwatch_metrics_enabled = true; metric_name = "rate-limit" }
    }
}

// 5) ModSecurity + OWASP Core Rule Set
// nginx config
load_module modules/ngx_http_modsecurity_module.so;
server {
    modsecurity on;
    modsecurity_rules_file /etc/nginx/modsec/main.conf;
}

// /etc/nginx/modsec/main.conf
Include /etc/nginx/modsec/modsecurity.conf
Include /etc/nginx/modsec/crs-setup.conf
Include /etc/nginx/modsec/rules/*.conf
SecRuleEngine On                                  # detect-only mode: SecRuleEngine DetectionOnly

// CRS includes rules numbered 900000-999999. Tune via SecRuleRemoveById for false positives.

// 6) Detection-only mode FIRST
// Block mode on Day 1 causes outages from false positives.
// Run in detection-only for 1-2 weeks; analyse logs; tune; then enable blocking.

// Cloudflare:    'simulate' action
// AWS WAF:       'count' action
// ModSecurity:   SecRuleEngine DetectionOnly

// 7) Anti-bot challenges
// • Cloudflare Bot Management — JS challenges, captcha
// • Akamai Bot Manager
// • DataDome, PerimeterX
// • hCaptcha / reCAPTCHA Enterprise

// 8) WAF bypasses — assume sophisticated attackers will work around
// • URL encoding the payload (%3Cscript%3E)
// • Double encoding
// • Mixed case
// • Comment injection (UN/**/ION SE/**/LECT)
// • Whitespace tricks (\t\n)
// • Different parsers between WAF + origin (HPP — HTTP Parameter Pollution)
//
// WAF is a SPEED BUMP, not a wall. Secure your code as if no WAF existed.

// 9) Custom rules — domain-specific knowledge
// • Block paths your app doesn't serve (/admin from non-corporate IPs)
// • Block admin endpoints during business-hours-only access
// • Geo-block countries where you don't operate
// • Rate limit per-IP, per-token, per-endpoint
// • Block requests missing expected headers (User-Agent, Referer)

// 10) Logging + observability
// • Cloudflare Logs / Logpush to S3 / Splunk
// • AWS WAF Logs to S3 / CloudWatch / Kinesis
// • ModSecurity audit logs (huge!) — rotate aggressively
//
// Pipe to a SIEM (Splunk / Datadog / Sumo) for correlation.

// 11) Allowlist + denylist patterns
// • Allow known-good user-agent for partner integrations
// • Allow known IP ranges (office, partners)
// • Block known scanners / TOR exit nodes
// • Block ASNs known for abuse

// 12) Performance
// • WAFs add latency (5-50 ms typical) — measure
// • Heavy ruleset = more CPU at edge; benchmark
// • Cache lookups for repeat requests; some WAFs do this

// 13) WAF vs application-layer defense
// WAF:                                   App-layer:
//   Cheap to add                            Authoritative
//   Filters known patterns                   Catches business logic flaws
//   Tunable per environment                  Slow to ship
//   Blocks ZERO-DAY signatures (sometimes)   Resists novel input safely
//
// Use both. WAF is the first line; app is the source of truth.

// 14) Common bugs / mistakes
// • WAF in block mode without tuning → 500s from false positives
// • All traffic routed through WAF but WAF dropping legitimate API clients → escape valve for known clients
// • Trusting X-Forwarded-For without sanitisation → spoofed IPs in rate limits
// • Origin IP leaked → bypass the WAF directly; lock down origin firewall
// • WAF rules in nginx but logs in CloudWatch — mismatched troubleshooting; centralise
// • Block POST body inspection but allow query string injection — rules must cover ALL inputs
// • Detection-only mode left on permanently — wastes WAF; eventually block
// • Ignoring WAF logs — adversaries probing for hours/days; alert on rule hits
// • Treating WAF as a substitute for secure code — false sense of security

Why it matters

A WAF is a defensive speed bump, not a wall. Start in detect-only mode, layer managed rules (OWASP CRS, AWS Managed Rules), add custom rules for your endpoints and rate limits, log everything to a SIEM, and lock down origin IPs so attackers can’t bypass. Always pair the WAF with secure-by-default code and CSP — defense in depth, not defense in singularity.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
// Web Application Firewall: pattern + ML rules at the edge (Cloudflare, AWS WAF).
// RASP: runtime checks inside your app (Sqreen, Signal Sciences).
// Defense in depth — don't make it your only XSS control.
Try it Yourself »

Discussion

Loading…