A Web Application Firewall sits between your users and your application, inspecting every HTTP request and blocking those that match known attack patterns or custom rules. For complete protection, pair WAF with a managed SOC to detect and respond to threats that bypass WAF controls. For most internet-facing web applications, a properly configured WAF is the most cost-effective security control you can deploy — stopping the bulk of automated attacks before they ever reach your application code.
Our cloud security team deploys and tunes Cloudflare WAF configurations as part of a broader cloud hardening programme. See how we implemented this for a Melbourne SaaS company in our Cloudflare WAF case study.
Cloudflare is the dominant WAF provider for good reason: global network (300+ PoPs), DDoS mitigation integrated at the network layer, aggressive threat intelligence updates, and a freemium model that makes enterprise-grade protection accessible to organisations of any size. This guide takes you from zero to a hardened, operationally mature Cloudflare WAF deployment.
Understanding What a WAF Protects Against
Before configuration, understand what a WAF does and doesn’t do:
WAF protects against:
- Injection attacks (SQL injection, command injection) via HTTP requests
- Cross-site scripting (XSS)
- SSRF (Server-Side Request Forgery) via known patterns
- Path traversal
- Remote file inclusion
- Automated scanners and vulnerability crawlers
- Application-layer DDoS (HTTP flood)
- Credential stuffing on login endpoints
- Bad bots and scrapers
WAF does NOT protect against:
- Logic flaws in your application (a WAF can’t understand your business rules)
- Vulnerabilities in your server configuration outside the request path — address these with vulnerability management
- Supply chain attacks (compromised dependencies)
- Authenticated attackers who have valid sessions
- Zero-day exploits with no known signature
A WAF is defence in depth, not a substitute for secure development. It buys you time and blocks the noise — but your application needs to be coded securely as well. A cloud security assessment can identify the configuration gaps that a WAF alone won’t address.
Cloudflare Plan Tiers
| Feature | Free | Pro ($20/mo) | Business ($200/mo) | Enterprise |
|---|---|---|---|---|
| Managed WAF rules | Basic | Full OWASP CRS | Full + custom page rules | Full + custom + priority support |
| Custom WAF rules | 5 | 20 | 100 | 1000+ |
| Rate limiting | 1 rule | 10 rules | Unlimited | Unlimited |
| Bot management | Basic Bot Fight Mode | Super Bot Fight Mode | Super Bot Fight Mode | Advanced Bot Management |
| DDoS protection | Unmetered (L3/4/7) | Unmetered | Unmetered | Unmetered + custom thresholds |
| Analytics | 24hr | 72hr | 30 days | 90 days |
| Log forwarding | ❌ | ❌ | Logpush | Logpush |
For most production web applications, Pro or Business is the minimum recommended tier. The Business tier unlocks full custom rules and Logpush (essential for SIEM integration).
Phase 1: DNS and Proxy Configuration
1.1 Onboard Your Domain
- Add your domain to Cloudflare
- Update your domain’s nameservers to Cloudflare’s
- Wait for propagation (typically 1–24 hours)
1.2 Enable Cloudflare Proxy
In DNS settings, ensure the orange cloud (proxy) is enabled for all records that serve web traffic. Grey cloud = DNS only, no WAF/DDoS protection.
A api.example.com → 1.2.3.4 [Proxied ✓]
A www.example.com → 1.2.3.4 [Proxied ✓]
A mail.example.com → 1.2.3.4 [DNS only — don't proxy mail]
1.3 Lock Down Your Origin
Once behind Cloudflare, your origin server should only accept traffic from Cloudflare’s IP ranges — otherwise attackers bypass your WAF by hitting the origin directly.
Cloudflare IPv4 ranges (as of writing — always check the live list at cloudflare.com/ips):
173.245.48.0/20
103.21.244.0/22
103.22.200.0/22
103.31.4.0/22
141.101.64.0/18
108.162.192.0/18
190.93.240.0/20
188.114.96.0/20
197.234.240.0/22
198.41.128.0/17
162.158.0.0/15
104.16.0.0/13
104.24.0.0/14
172.64.0.0/13
131.0.72.0/22
AWS security group (restrict inbound HTTP/HTTPS to Cloudflare only):
# Get Cloudflare IPs dynamically
CF_IPS=$(curl -s https://www.cloudflare.com/ips-v4)
# Add each to your security group
for cidr in $CF_IPS; do
aws ec2 authorize-security-group-ingress \
--group-id sg-xxxx \
--protocol tcp --port 443 \
--cidr $cidr
done
Also implement Cloudflare Authenticated Origin Pulls — your origin verifies that requests come from Cloudflare using mTLS:
# nginx — verify Cloudflare client cert
ssl_client_certificate /etc/ssl/cloudflare-origin-pull-ca.pem;
ssl_verify_client on;
Phase 2: WAF Rule Configuration
2.1 Enable Managed Rules (OWASP Core Rule Set)
Navigate to Security → WAF → Managed Rules. Enable:
- Cloudflare Managed Ruleset — Cloudflare’s proprietary ruleset, updated continuously based on threat intelligence
- Cloudflare OWASP Core Ruleset — implements OWASP CRS 3.x
Initial action: Set all rules to Log mode first. Do not block immediately — spend 1-2 weeks reviewing logs to identify false positives before switching to Block.
OWASP Paranoia Level: Start at level 1 (low false positives). Increase to level 2 or 3 as you tune out false positives.
2.2 WAF Rule Actions
| Action | Behaviour | When to Use |
|---|---|---|
| Log | Record but allow | Initial deployment, tuning phase |
| Block | Return 403 | Confirmed malicious patterns |
| Challenge | Show CAPTCHA | Suspicious but uncertain |
| JS Challenge | Browser integrity check (silent) | Bot traffic |
| Managed Challenge | Cloudflare decides type | Default for most rules |
| Skip | Bypass WAF for this request | Trusted IPs, known-good traffic |
2.3 Custom WAF Rules
After enabling managed rules, add custom rules tailored to your application.
Block requests with no User-Agent:
(not http.request.headers["user-agent"][0] exists)
→ Block
Block common scanner signatures:
(http.request.headers["user-agent"][0] contains "sqlmap") or
(http.request.headers["user-agent"][0] contains "nikto") or
(http.request.headers["user-agent"][0] contains "masscan") or
(http.request.headers["user-agent"][0] contains "zgrab")
→ Block
Block path traversal attempts:
(http.request.uri.path contains "../") or
(http.request.uri.path contains "..%2F") or
(http.request.uri.path contains "%2e%2e%2f")
→ Block
Protect admin paths — challenge non-office IPs:
(http.request.uri.path starts_with "/admin") and
(not ip.src in {203.0.113.0/24 198.51.100.0/24})
→ Managed Challenge
Block credential stuffing on login — challenge high request volume:
(http.request.uri.path eq "/api/auth/login") and
(http.request.method eq "POST")
→ Rate limit (see Phase 3)
Geo-blocking (if you don’t serve certain countries):
(ip.geoip.country in {"CN" "RU" "KP" "IR"})
→ Block
Use this carefully — it’s a blunt instrument and blocks legitimate users. Useful when you’re seeing specific attack traffic from regions you don’t serve.
Phase 3: Rate Limiting
Cloudflare rate limiting lets you define rules based on request volume from an IP or across a session.
Login Endpoint Protection
Rule name: Login Rate Limit
Expression: (http.request.uri.path eq "/api/auth/login" and http.request.method eq "POST")
Threshold: 5 requests per 60 seconds per IP
Action: Block for 10 minutes
API Endpoint General Protection
Rule name: API Rate Limit
Expression: (http.request.uri.path starts_with "/api/")
Threshold: 300 requests per 60 seconds per IP
Action: Managed Challenge
Password Reset / Account Recovery Protection
Rule name: Password Reset Rate Limit
Expression: (http.request.uri.path contains "/forgot-password" or
http.request.uri.path contains "/reset-password")
Threshold: 3 requests per 300 seconds per IP
Action: Block for 1 hour
GraphQL Query Depth Limiting
For GraphQL APIs, limit query complexity to prevent resource exhaustion:
Expression: (http.request.uri.path eq "/graphql" and
http.request.body.size > 10000)
Action: Block
Phase 4: Bot Management
4.1 Cloudflare Bot Fight Mode
For Pro plans: Enable Super Bot Fight Mode under Security → Bots.
Options:
- Definitely automated → Block or Challenge
- Likely automated → Challenge
- Verified bots (Google, Bing, monitoring services) → Allow
4.2 Advanced Bot Management (Enterprise)
Enterprise Bot Management adds:
- Bot score (0–99) — challenge or block based on confidence level
- Machine learning-based bot detection
- JavaScript fingerprinting
- Tor exit node detection
- Anomaly-based detection for sophisticated bots
Custom rule using bot score:
(cf.bot_management.score lt 30 and
not http.request.uri.path starts_with "/api/webhook/")
→ Block
4.3 Handling False Positives for Legitimate Bots
Some automated traffic is legitimate — monitoring services, SEO crawlers, uptime monitors. Allowlist known-good IPs:
(ip.src in {185.93.228.0/24}) ← Pingdom
→ Skip WAF
Or use the Verified Bots classification to automatically allow Google, Bing, and other major search crawlers.
Phase 5: DDoS Configuration
Cloudflare’s DDoS protection is always on and unmetered at all plan levels. Key configuration options:
HTTP DDoS Attack Protection
Under Security → DDoS → HTTP DDoS attack protection:
- Sensitivity: Start at Medium. Increase to High or High+ if you’re under attack.
- Action: Override to Block for critical endpoints; leave Managed for general traffic.
Network-Layer DDoS (Magic Transit / Spectrum)
For volumetric attacks targeting non-HTTP ports or raw IP infrastructure, Magic Transit (BGP advertisement of your IP space through Cloudflare) or Spectrum (proxied TCP/UDP) extends protection beyond HTTP.
Phase 6: SSL/TLS Configuration
Encryption Mode
Set encryption mode to Full (Strict) — this validates Cloudflare’s connection to your origin server uses a valid certificate.
Free → Flexible (Cloudflare ↔ browser encrypted; Cloudflare ↔ origin unencrypted) ← DON'T USE
→ Full (encrypted to origin, cert not validated) ← Acceptable short-term
→ Full (Strict) (encrypted to origin, valid cert required) ← RECOMMENDED
HSTS
Enable HSTS under SSL/TLS → Edge Certificates:
- Max-Age: 12 months minimum (31,536,000 seconds)
- Include subdomains: Yes (if all subdomains are HTTPS)
- Preload: Yes (submit to HSTS preload list after stable deployment)
Minimum TLS Version
Set minimum TLS to 1.2 (disable TLS 1.0 and 1.1): SSL/TLS → Edge Certificates → Minimum TLS Version → TLS 1.2
Phase 7: Security Headers and Page Rules
Add security headers via Transform Rules → Modify Response Header:
Rule: Add Security Headers
Expression: (true) ← applies to all responses
Add headers:
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: geolocation=(), microphone=()
Content-Security-Policy: default-src 'self'; ...
Phase 8: Logging and SIEM Integration
Cloudflare Logpush (Business/Enterprise)
Set up Logpush to send WAF logs to your SIEM, S3, or SIEM in real-time:
# Create Logpush job to S3
curl -X POST "https://api.cloudflare.com/client/v4/zones/{zone_id}/logpush/jobs" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
--data '{
"destination_conf": "s3://my-bucket/cloudflare-logs?region=ap-south-1",
"dataset": "http_requests",
"logpull_options": "fields=ClientIP,ClientRequestMethod,ClientRequestURI,WAFAction,WAFRuleID,EdgeResponseStatus×tamps=rfc3339",
"enabled": true
}'
Key fields to capture for security:
ClientIP— source IPWAFAction— block/challenge/logWAFRuleID— which rule firedWAFRuleMessage— description of the ruleClientRequestURI— target pathClientRequestMethod— HTTP methodEdgeResponseStatus— HTTP response code
Microsoft Sentinel Integration
Cloudflare has a native Sentinel data connector (Community). Alternatively, route Logpush through Azure Event Hub → Log Analytics workspace.
KQL query — top blocked IPs last 24 hours:
Cloudflare_CL
| where WAFAction_s == "block"
| where TimeGenerated > ago(24h)
| summarize BlockCount = count() by ClientIP_s
| top 20 by BlockCount
Tuning and False Positive Management
Process for Tuning
- Log mode first — run all rules in Log mode for 2 weeks
- Identify false positives — look for legitimate traffic matching rules
- Add exceptions — create WAF rule exceptions for specific paths or IPs
- Switch to Block — move rules to Block mode once false positives are eliminated
- Monitor weekly — review logs for new false positives after application changes
Creating Rule Exceptions
Rule: Exception for API upload endpoint
Expression: (http.request.uri.path starts_with "/api/upload" and
http.request.method eq "POST")
Managed rules to skip: [specific rule IDs that fire on file uploads]
Never skip entire managed rulesets — be surgical about which rules to exempt.
Security Incident Response with Cloudflare
When you’re under attack:
- Enable Under Attack Mode — Security → Settings → Security Level → Under Attack (adds JS challenge to all visitors)
- Create emergency IP block — Custom Rule to block attacker IPs immediately
- Increase rate limit sensitivity — reduce thresholds on targeted endpoints
- Enable firewall events export — get real-time attack telemetry
- Contact Cloudflare support — Enterprise accounts get direct DDoS response support
Go-Live Checklist
Before moving all rules from Log to Block:
- All managed rules reviewed, false positives identified and excepted
- Custom rules deployed and tested with legitimate traffic
- Rate limiting configured for login, API, password reset endpoints
- Origin locked to Cloudflare IPs only
- Authenticated Origin Pulls configured
- SSL mode set to Full (Strict)
- TLS 1.2 minimum enforced
- HSTS enabled
- Security headers deployed via Transform Rules
- Logpush configured and verified
- Alerts set up for WAF blocks and DDoS events
CyberneticsPlus deploys and tunes Cloudflare WAF configurations for clients across SaaS, financial services, and e-commerce as part of our cloud security practice. We handle full deployment, custom rule development, SIEM integration, and ongoing tuning. Read our Cloudflare WAF Melbourne SaaS case study or contact us to protect your web applications.