Having recently guided several clients through the initial configuration of Cloudflare's Web Application Firewall for legacy applications, I've observed a common pattern: the paralysis of choice when faced with a blank WAF configuration screen. If your site is already behind Cloudflare's proxy (orange-clouded), you've completed the hardest part—traffic is already flowing through their network. The WAF is a logical next layer, but its out-of-the-box state requires deliberate tuning to be effective and not disruptive.
I recommend a phased, observational approach. Your primary goal in Week 1 is not to block attacks, but to understand the baseline of your application's traffic and the default protections already in place. Start in **Dashboard > Security > WAF**. You'll see three core areas: **1) Managed Rulesets, 2) Custom Rules, and 3) Rate Limiting Rules**. Ignore Custom and Rate Limiting for now.
First, navigate to the Managed Rulesets. Cloudflare provides pre-configured rule groups from Cloudflare OWASP, Cloudflare Managed, and the WordPress/Drupal packages. The critical mistake is to enable everything on "Block" immediately. Instead, follow this playbook:
* **Day 0-1:** Ensure the **Cloudflare Managed Rule Set** is enabled, but configure its *Default Action* to "Log" for all rules. This creates a safety net.
* **Day 2-4:** Enable the **Cloudflare OWASP Core Rule Set** in "Log" mode only. This is a broad-spectrum rule set that catches many common web attacks.
* **Days 5-7:** Analyze the logs in **Security > Events**. Filter by "Action: Log." Look for:
* Which rules are triggering most frequently?
* What are the request paths and user agents?
* Are these legitimate requests (e.g., from your admin panel, specific API endpoints) or clear junk?
This observational phase provides the data you need to start crafting exceptions (allowlists) before you switch to blocking. For example, you may find a false positive where a rule `100135B` blocks a legitimate form post on `/contact`. You would then create a WAF custom rule to allow that. A sample rule expression to allowlist that path from a specific rule might look like:
```
(http.request.uri.path contains "/contact") and (cf.waf.score.gt(0))
```
But a more surgical approach is to use a **Rule Exception** within the Managed Ruleset itself, scoped to a specific rule ID.
After 7-10 days of logging, you can begin transitioning high-confidence, high-severity rules to "Block." I advise a graduated schedule:
* **Week 2:** Change rules with severity "Critical" and "High" from the OWASP set to "Block." Keep "Medium" and "Low" in "Log."
* **Week 3:** Review events again. If no critical false positives, enable "Block" for "Medium" severity rules.
* **Week 4+:** Now consider creating **Custom Rules** for your application's unique logic (e.g., blocking non-standard user agents on your admin path) and exploring **Rate Limiting** for login endpoints.
The principle is: observe, understand, then act. Enabling all rules on "Block" from the start risks breaking legitimate functionality and causing unnecessary friction. Your site being on CF gives you the advantage; their global network is already absorbing volumetric DDoS. The WAF is your surgical tool for application-layer logic. Start with the managed rules in a logging posture, refine based on your traffic patterns, and then progressively tighten the security posture.
- Mike
I agree completely with the phased, observational approach. Where I've seen teams run into trouble, even during that initial observation week, is misinterpreting the logs. The Security Events log will show hits against managed rules that are in *Log* or *Challenge* mode, but without proper context, a junior admin might mistake a legitimate, complex form submission for an attack because it triggered a SQLi rule. This can lead to prematurely disabling rules that are actually providing useful signals.
My addition to your playbook would be to cross-reference WAF events with your application logs during those first few days. If a rule is triggering, you need to see what the actual user was doing at that moment. Was it a search with an unusual pattern, or a failed login attempt with a suspicious payload? This correlation is essential to move from observation to informed tuning, and it prevents the common knee-jerk reaction of disabling rules that seem noisy but are actually catching baseline probe activity.
Neglecting this log correlation step often results in a WAF that's either too loud to be useful or, after aggressive silencing, too quiet to be effective.
Data doesn't lie, but folks sometimes do.
That's a really good point about cross referencing. I've been trying to just look at the WAF logs and got overwhelmed fast. I wouldn't have thought to check what the user was actually doing in the app at that moment.
How do you usually handle that log correlation practically? Is it just manually matching timestamps, or is there a better way to set it up?