WAF Deployment Patterns


WAF Overview

A Web Application Firewall (WAF) filters and monitors HTTP traffic between web applications and the internet. It protects against common attacks like SQL injection, XSS, and CSRF.

Inline WAF Deployment

The WAF sits directly in the request path:




# ModSecurity configuration


SecRuleEngine On


SecRequestBodyAccess On


SecResponseBodyAccess On




# SQL Injection prevention


SecRule REQUEST_COOKIES|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* \


"/((\%27)|(\'))\s*((\%6F)|o|(\%4F))((\%72)|r|(\%52))/ix" \


"id:'981173',\


phase:2,\


deny,\


status:403,\


msg:'SQL Injection Attack'"




# XSS prevention


SecRule ARGS "@detectXSS" \


"id:'958056',\


phase:2,\


deny,\


status:403,\


msg:'XSS Attack Detected'"





Reverse Proxy WAF

Deploy WAF as a reverse proxy for centralized protection:




# Nginx with ModSecurity


server {


listen 443 ssl;


server_name app.example.com;




# ModSecurity enabled


modsecurity on;


modsecurity_rules_file /etc/nginx/modsec/main.conf;




location / {


proxy_pass http://backend:8080;


proxy_set_header Host $host;


proxy_set_header X-Real-IP $remote_addr;


proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;


}


}





Cloud WAF (AWS WAF)




# AWS WAF with rate limiting and SQL injection protection


resource "aws_wafv2_web_acl" "main" {


name = "main-waf"


description = "Main WAF ACL"


scope = "REGIONAL"




default_action {


allow {}


}




rule {


name = "RateLimit"


priority = 1




action {


block {}


}




statement {


rate_based_statement {


limit = 2000


aggregate_key_type = "IP"


}


}




visibility_config {


cloudwatch_metrics_enabled = true


metric_name = "RateLimit"


sampled_requests_enabled = true


}


}




rule {


name = "SQLInjection"


priority = 2




action {


block {}


}




statement {


sql_injection_match_statement {


field_to_match {


body {}


}


text_transformation {


priority = 0


type = "URL_DECODE"


}


}


}




visibility_config {


cloudwatch_metrics_enabled = true


metric_name = "SQLInjection"


sampled_requests_enabled = true


}


}


}





API Protection

APIs require different WAF rules than web applications:




# Custom WAF rule for API protection


API_WAF_RULES = {


"missing_auth_header": {


"priority": 1,


"match": lambda req: "Authorization" not in req.headers,


"action": "block",


"response": 401


},


"invalid_content_type": {


"priority": 2,


"match": lambda req: (


req.method in ["POST", "PUT", "PATCH"]


and req.headers.get("Content-Type") != "application/json"


),


"action": "block",


"response": 415


},


"path_traversal": {


"priority": 3,


"match": lambda req: "../" in req.path or "..\\" in req.path,


"action": "block",


"response": 403


}


}





WAF Logging and Monitoring




-- Analyze blocked requests


SELECT country, COUNT(*) as blocked_count,


ARRAY_AGG(DISTINCT rule_id) as triggered_rules


FROM waf_logs


WHERE action = 'BLOCK'


AND timestamp > NOW() - INTERVAL '24 hours'


GROUP BY country


ORDER BY blocked_count DESC;




-- False positive analysis


SELECT rule_id, COUNT(*) as false_positives


FROM waf_logs


WHERE action = 'BLOCK'


AND downstream_status = 200


AND timestamp > NOW() - INTERVAL '7 days'


GROUP BY rule_id


ORDER BY false_positives DESC;





Conclusion

Choose the WAF deployment pattern that fits your architecture. Inline WAF offers the strongest protection but adds latency. Cloud WAF provides scalability with minimal maintenance. Reverse proxy WAF is ideal for centralized management. Tune your WAF rules carefully to minimize false positives and monitor blocked requests regularly.