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…