Web Application Firewall (WAF)
A Web Application Firewall inspects HTTP/HTTPS traffic between clients and web applications, blocking requests that match known attack patterns or violate defined security rules. Unlike a network firewall, which operates at layers 3โ4 (IP/TCP), a WAF operates at layer 7 (application layer) and understands the semantics of HTTP โ headers, methods, URIs, query strings, request bodies, cookies, and responses.
A WAF is a detective and preventive control, not a substitute for secure application development. It buys time, reduces noise, and catches common attacks, but it cannot compensate for fundamentally flawed application logic.
How a WAF Works
WAFs inspect traffic using one or more of three approaches:
Negative Security Model (Signature/Blacklist)
Blocks requests matching known attack signatures. The default approach for most WAFs.
- Pattern-matched against a rule set (e.g., OWASP CRS)
- Fast to deploy, good coverage of known vulnerability classes
- Limited against novel or zero-day attacks
- Requires ongoing rule updates
Positive Security Model (Allowlist)
Only permits requests that conform to a defined specification of what is legitimate. Everything else is blocked by default.
- Built from the application's own API schema (OpenAPI/Swagger) or learned traffic baseline
- Most effective protection โ blocks unknown attacks by definition
- High upfront effort to define and maintain the allowlist
- Well-suited to APIs with a well-defined contract
Behavioural / Anomaly Scoring
Assigns a risk score to each request based on multiple signals. Requests exceeding a threshold are blocked or challenged.
- OWASP Core Rule Set (CRS) uses this model โ each matched rule adds to a running score
- Configurable threshold balances false positives vs missed detections
- More flexible than pure signature matching
Most production WAFs combine all three models.
Deployment Modes
Reverse Proxy (Most Common)
The WAF sits in front of the application server, receiving all traffic and forwarding clean requests.
Client โ [ WAF ] โ Application Server
- Full visibility into requests and responses
- Can terminate TLS, inject security headers, rewrite URLs
- Adds a network hop (typically <5ms latency when tuned)
- Single point of failure if not deployed in HA
Transparent / Inline Bridge
The WAF is inserted into the network path at layer 2 (bridge mode), invisible to clients and servers.
- No IP address changes required
- Harder to configure and maintain
- Still a point of failure
Out-of-Band / Passive (Detection Only)
Traffic is mirrored to the WAF for analysis. The WAF cannot block โ it can only alert.
- Zero impact on latency or availability
- Used in audit mode to tune rules before going inline
- Not a protective control
Cloud / CDN-based WAF
Traffic is routed through the WAF provider's infrastructure via DNS pointing the domain to the cloud WAF's IP range.
Client โ [ Cloud WAF (e.g. Cloudflare, AWS WAF) ] โ Origin Server
- No on-premises hardware
- Global PoPs reduce latency
- DDoS absorption capacity included
- Origin IP must be protected (clients must not bypass WAF by connecting directly to origin)
WAF Types
| Type | Examples | Best For |
|---|---|---|
| Cloud / SaaS | Cloudflare WAF, AWS WAF, Azure Front Door WAF, Akamai Kona | Public-facing apps, DDoS protection, rapid deployment |
| Open-source software | ModSecurity (Apache/Nginx), Coraza | Self-hosted, cost-sensitive, customisation |
| Commercial software | F5 NGINX App Protect, Imperva | On-premises, complex environments, advanced features |
| Hardware appliance | F5 BIG-IP ASM, Fortinet FortiWeb | Data centre perimeter, dedicated throughput |
| Kubernetes ingress | NGINX Ingress + ModSecurity, AWS WAF + ALB | Cloud-native, containerised workloads |
What a WAF Protects Against
WAFs are effective against the OWASP Top 10 and other common web attack classes:
| Attack Class | OWASP Category | WAF Effectiveness |
|---|---|---|
| SQL Injection | A03: Injection | High โ well-understood patterns |
| Cross-Site Scripting (XSS) | A03: Injection | High โ reflected/stored XSS patterns |
| Cross-Site Request Forgery (CSRF) | A01: Broken Access Control | Partial โ token validation requires app awareness |
| Path Traversal / LFI | A01: Broken Access Control | High โ ../ and %2e%2e patterns |
| OS Command Injection | A03: Injection | High โ shell metacharacter patterns |
| XML External Entity (XXE) | A05: Security Misconfiguration | High โ DTD patterns |
| Server-Side Request Forgery (SSRF) | A10: SSRF | Partial โ pattern matching on request bodies |
| HTTP Protocol Attacks | A05: Security Misconfiguration | High โ malformed headers, oversized requests |
| Scanner / Bot Activity | โ | High โ tool fingerprints, rate limiting |
| DDoS (Layer 7) | โ | High (cloud WAF) โ rate limiting, JS challenges |
| Credential Stuffing | โ | Moderate โ rate limiting, bot detection |
What a WAF cannot protect against:
- Business logic flaws (incorrect authorisation decisions in the app)
- Authenticated attacks from legitimate-looking requests
- Zero-day vulnerabilities with no matching signatures
- Attacks over encrypted channels it cannot inspect (mTLS where WAF is not the TLS terminator)
- Client-side attacks (XSS that has already executed in the browser)
OWASP Core Rule Set (CRS)
The OWASP Core Rule Set is the most widely deployed open-source WAF rule set, used with ModSecurity, Coraza, and supported by many commercial WAFs.
Anomaly Scoring Mode
CRS operates in anomaly scoring mode by default:
- Each matched rule adds to an inbound anomaly score
- When the total exceeds the anomaly threshold (default: 5), the request is blocked
- This prevents blocking on a single low-confidence match while blocking on combinations of suspicious signals
# ModSecurity + CRS: key configuration directives
SecRuleEngine On # Detection + blocking (use DetectionOnly to start)
SecAuditEngine RelevantOnly
SecAuditLog /var/log/modsec_audit.log
# CRS anomaly thresholds
SecAction \
"id:900110,\
phase:1,\
nolog,\
pass,\
t:none,\
setvar:tx.inbound_anomaly_score_threshold=5,\
setvar:tx.outbound_anomaly_score_threshold=4"
Paranoia Levels
CRS has four paranoia levels:
| Level | Description | False Positive Risk |
|---|---|---|
| PL1 (default) | Core rules, minimal false positives | Low |
| PL2 | Extended rules | Moderate |
| PL3 | Strict rules โ advanced detection | High |
| PL4 | Maximum detection | Very high โ only for highly tuned environments |
Start at PL1 in detection mode, tune out false positives, then move to enforce mode before considering PL2.
Deployment Strategy
Phase 1 โ Detection Mode (No Blocking)
Run the WAF in detection/audit mode. Log all rule matches without blocking traffic.
- Duration: 2โ4 weeks minimum for applications with varied traffic patterns
- Collect and analyse false positives
- Identify legitimate requests that trigger rules (e.g., rich text editors, admin interfaces with complex payloads)
Phase 2 โ Tune False Positives
For each false positive:
# Disable a specific rule for a specific URI
SecRule REQUEST_URI "@beginsWith /admin/editor" \
"id:1001,phase:1,nolog,pass,ctl:ruleRemoveById=941100"
# Exclude a parameter from a rule
SecRuleUpdateTargetById 941100 "!REQUEST_COOKIES:_session"
# Whitelist a trusted IP range from all rules
SecRule REMOTE_ADDR "@ipMatch 10.0.0.0/8" \
"id:1002,phase:1,nolog,allow,ctl:ruleEngine=Off"
Phase 3 โ Enforce Mode (Blocking)
Enable blocking mode. Start with lower-confidence rules in detection and higher-confidence rules blocking. Monitor for new false positives after every application deployment.
Phase 4 โ Ongoing Tuning
A WAF is not set-and-forget. Retuning is required after:
- Application changes (new endpoints, parameters, content types)
- CRS rule set updates
- New attack campaigns targeting the application
WAF Bypass Techniques (Know Your Limits)
Understanding bypass methods helps set realistic expectations for what a WAF achieves.
| Bypass Technique | Description |
|---|---|
| Encoding variations | URL-encode, double-encode, Unicode normalisation โ %27 vs ' vs %2527 |
| Case variation | SeLeCt instead of SELECT in SQL injection |
| Comment injection | SE/*comment*/LECT in SQL |
| HTTP parameter pollution | Multiple parameters with the same name, parsed differently |
| Large payload splitting | Spreading the attack across multiple requests |
| Content-type confusion | Sending JSON in a form-encoded request body |
| HTTP/2 or HTTP/3 | Some WAFs do not inspect newer protocol versions equally |
| Chunked transfer encoding | Evasion through non-standard chunking |
| Out-of-band exfiltration | DNS-based SQLi exfiltration may not be detected |
Implication: A WAF reduces the attack surface and stops unsophisticated automated attacks effectively, but a determined and skilled attacker can often find a bypass. The WAF must be paired with secure code, input validation, parameterised queries, and output encoding in the application itself.
Protecting the WAF Origin
For cloud WAFs, if attackers discover and directly access the origin server IP, the WAF is bypassed entirely.
Mitigations:
- Restrict origin server ingress to only the WAF provider's IP ranges at the network firewall level
- Use cloud WAF features like Cloudflare Authenticated Origin Pulls (client certificate on origin)
- Rotate origin IP if it has been exposed
- Do not include the origin IP in any public DNS records, email headers, or error pages
# Example: Allow only Cloudflare IPs to reach origin (iptables)
# Fetch current Cloudflare IP ranges from their API and apply as allowlist
curl -s https://www.cloudflare.com/ips-v4 | while read ip; do
iptables -I INPUT -p tcp --dport 443 -s "$ip" -j ACCEPT
done
iptables -A INPUT -p tcp --dport 443 -j DROP
Security Headers via WAF
A WAF or reverse proxy can inject security response headers that the application may not set itself:
# Nginx WAF proxy โ inject security headers on all responses
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; ..." always;
Rate Limiting and Bot Management
A WAF is the natural place to enforce rate limiting โ it sees all traffic before it reaches the application.
| Control | Purpose |
|---|---|
| IP-based rate limiting | Throttle high-volume requests from a single source |
| Path-based rate limiting | Stricter limits on login, password reset, OTP endpoints |
| CAPTCHA / JS challenge | Distinguish humans from bots for borderline requests |
| Bot reputation scoring | Block known malicious ASNs, Tor exit nodes, hosting ranges |
| Credential stuffing protection | Alert and block on high failed-login rates |
# AWS WAF rate-based rule example
- Name: RateLimitLogin
Priority: 1
Statement:
RateBasedStatement:
Limit: 100 # requests per 5 minutes per IP
AggregateKeyType: IP
ScopeDownStatement:
ByteMatchStatement:
FieldToMatch:
UriPath: {}
SearchString: /login
PositionalConstraint: STARTS_WITH
TextTransformations:
- Priority: 0
Type: LOWERCASE
Action:
Block: {}
WAF in a DevSecOps Pipeline
Integrate WAF rule testing into CI/CD to prevent deployments from introducing new false positives or uncovered attack surface:
- Automated security scanning (DAST โ OWASP ZAP, Burp Suite) runs against staging behind the WAF
- WAF rule set changes go through the same review process as application code
- WAF alerts feed into the same SIEM/alerting pipeline as application logs
- New API endpoints trigger a WAF rule review to ensure coverage
Hardening Checklist
| Control | Priority | Notes |
|---|---|---|
| WAF deployed in inline/blocking mode | Critical | Detection mode only is not a protective control |
| OWASP CRS or equivalent rule set enabled | High | Keep updated โ new rules for new CVEs |
| TLS termination at WAF | High | WAF cannot inspect encrypted traffic it doesn't terminate |
| Origin IP restricted to WAF IPs only | Critical | Prevents WAF bypass via direct origin access |
| Rate limiting on authentication endpoints | High | Login, password reset, OTP, API keys |
| Detection mode used before enforcement | High | Tune false positives before blocking |
| Security response headers injected | Medium | HSTS, X-Frame-Options, CSP, etc. |
| WAF logs shipped to SIEM | High | Alerts on anomaly spikes, new attack campaigns |
| False positive review process defined | High | Prevents tuning that inadvertently disables protection |
| WAF coverage reviewed on each deployment | Medium | New endpoints may need new rules or exclusions |
| Bot / crawler management configured | Medium | Protect scraping-sensitive content and auth flows |
| WAF bypass testing included in pen tests | Medium | Validate WAF effectiveness under adversarial conditions |