Cloudflare WAF Walkthrough: Monitor First, Block Later, Skip OWASP
The Cloudflare WAF is one of the highest-ROI security controls you can deploy on a public-facing application: it sits at the edge, inspects every HTTP/HTTPS request, and drops malicious traffic before it ever touches your origin. Turning it on takes about ten minutes. Turning it on without breaking your site takes a bit more care.
This post is the walkthrough I wish I had the first time I rolled WAF out on a production domain. It assumes you’ve already got the domain on Cloudflare (proxied — orange cloud — DNS is in place) and you’re looking for the implementation playbook, not a marketing overview. For the conceptual deep dive on what Advanced WAF actually does at Layer 7, see Cloudflare Advanced WAF.
The plan we’ll follow:
- Monitor first. Put rules in log-only mode so you can see what would be blocked.
- Deploy the Cloudflare Managed Ruleset. Signature-based, low false positive rate.
- Layer in the WAF Attack Score (if you’re on Business or Enterprise).
- Skip OWASP Core Ruleset. Cloudflare themselves now warn against running it for most use cases.
- Set up alerting on traffic spikes so you find out before your users do.
- Review and iterate for at least a week before you call it done.
What you need before you start
- A Cloudflare account with the domain added and DNS records proxied (orange cloud).
- An honest read of your traffic: who legitimately calls your API? Do you have search bots you care about? Internal scripts? Webhooks from third parties? Write these down — they’ll become your allowlist later.
- Plan-aware expectations. The Free plan gets the Cloudflare Free Managed Ruleset (a subset of the full managed list) and Super Bot Fight Mode in limited form. Pro and Business unlock more, and Enterprise unlocks WAF Attack Score and per-rule action overrides.
A note on plans: a lot of the interesting WAF features (Attack Score, leaked credentials detection, action overrides for managed rules, advanced alerting filters) live on Business and Enterprise. The walkthrough below works on any plan, but I’ll flag which steps require what.
Step 1: Monitor before you block (and seriously, do this)
The single biggest cause of “we turned on the WAF and the site went down” is going straight to Block action on day one. The Cloudflare Managed Ruleset has a low false positive rate by design, but “low” is not “zero” — and your application has weird endpoints, weird payloads, and a long-tail of legitimate clients that the ruleset was never tested against.
The fix is mundane: run in log-only mode for at least a week, ideally two, before you actually start blocking. You record matches without affecting traffic, then review what would have been blocked, then promote to Block after you’ve handled the false positives.
How you set up log-only mode depends on your plan:
- Enterprise. Go to Security → WAF → Managed rules, deploy the Cloudflare Managed Ruleset, then use a per-rule action override to set every enabled rule’s action to Log. This records matches in Security Events without taking action.
- Business / Pro. The dashboard doesn’t give you a “log-only” toggle on the managed ruleset itself — its default action is Block. The pragmatic workaround: deploy the managed ruleset as normal but lean heavily on custom rules with the Log action for any new policy you’re testing. For the managed ruleset itself, watch Security Events daily for the first week and tune (or disable) any rule that flags legitimate traffic.
- Free. The Free Managed Ruleset is on by default. There’s no log-only mode for it, so your monitoring strategy is simply to watch Security Events closely after enabling anything else and roll back fast if needed.
Either way, the discipline is the same: assume your first deployment will catch something it shouldn’t, and build the feedback loop to catch that before your users do.
Step 2: Deploy the Cloudflare Managed Ruleset
This is the workhorse. It’s signature-based, updated weekly by Cloudflare’s threat intel team, and tuned to catch the long tail of CVE exploitation and common attack vectors (SQLi, XSS, RCE, file inclusion, deserialization) without lighting up your dashboard with false positives.
In the new Security dashboard:
- Go to Security → Settings, optionally filter by Web application exploits.
- Toggle on Cloudflare managed ruleset.
In the old dashboard:
- Go to Security → WAF → Managed rules.
- Next to Cloudflare Managed Ruleset, click Deploy.
What you’re enabling by default is a curated subset of the full ruleset — Cloudflare specifically does not enable every rule out of the box, because doing so would dramatically increase false positives. If your application has a particular technology fingerprint (a WordPress site, a Drupal install, a Java app server) you can enable additional rules targeted at those stacks.
A note on testing. If you’re running a pentest or a vulnerability scanner against your own site to validate the WAF, temporarily flip the ruleset to enable all rules with action Block. Just remember to revert when you’re done — leaving every rule on in production is the fast path to breaking weird-but-legitimate clients.
Step 3: Add a WAF Attack Score rule (Business / Enterprise)
The Managed Ruleset catches known attack patterns. The WAF Attack Score is the machine-learning layer that catches the rest — novel payloads, bypasses around signature rules, and previously-unseen attacks. It assigns every request a score from 1 (almost certainly an attack) to 99 (almost certainly clean).
Business plans get access to a single field (WAF Attack Score Class, which buckets requests as Attack / Likely Attack / Likely Clean / Clean). Enterprise plans get the full numeric WAF Attack Score field and can write custom rules against any threshold.
A sensible starting custom rule (Enterprise):
When incoming requests match:
WAF Attack Score less than 20
Action: Block
Or, more conservatively, while you’re still validating:
When incoming requests match:
WAF Attack Score less than 20
Action: Log
The < 20 threshold is Cloudflare’s own suggested starting point. Run it in Log mode for a week, look at what’s being scored low, and then promote to Block when you’re confident there are no critical false positives. Once Managed Ruleset + Attack Score are both deployed, you’ve covered most of what the WAF can do for you.
Step 4: Why I leave OWASP Core Ruleset off
This is the section that surprises people. The OWASP Core Ruleset is the marquee feature on every WAF marketing page — and Cloudflare’s own documentation now openly warns against running it for most use cases. The Get Started page for WAF calls it prone to false positives, and notes that it adds only marginal protection beyond what the Cloudflare Managed Ruleset and Attack Score already give you.
The reason is mechanical: the OWASP ruleset is score-based with paranoia levels. Each matched rule contributes points; when the total crosses your configured threshold (default 40, “Medium”), the configured action fires. The attack-coverage overlaps almost entirely with the Cloudflare Managed Ruleset and Attack Score, but the false positive surface is much wider because legitimate requests with unusual-looking payloads (think: form posts with markup, URL-encoded JSON, base64 blobs) can accumulate enough OWASP points to trip the threshold even when no single rule is screaming.
If you run a high-traffic site and you turn OWASP on at the defaults, you will spend a non-trivial fraction of your week fielding “the site is blocking me” tickets from users, third-party integrations, and your own ops team. The tuning loop is real work — you have to either ratchet the paranoia level down (PL1) and the score threshold up (High - 25), or you have to maintain a growing list of exceptions per endpoint.
My default recommendation: leave OWASP Core Ruleset off. Run Cloudflare Managed Ruleset and (if available) the Attack Score custom rule. If you have a compliance requirement that specifically calls for OWASP CRS coverage, turn it on at the most permissive settings (PL1 + High - 25 threshold) in Log action, watch it for a month, and only promote to Block once you’ve burned through the false positives.
Step 5: Get notified when something actually happens
You’ve got the rules in place. The question now is: how do you find out when the WAF starts blocking unusual volume? You don’t want to live in the dashboard, and you don’t want to find out from a customer.
Cloudflare offers two built-in alerts, both reachable via Notifications in the dashboard:
- Security Events Alert — available on Business and Enterprise. Alerts on traffic spikes across all services that generate Security Events log entries (WAF, Rate Limiting, Bots, etc.).
- Advanced Security Events Alert — Enterprise only. Same idea, but lets you filter by zone, service, and action.
The way these actually fire is important to understand: Cloudflare uses a z-score calculation over the last six hours of five-minute event buckets. An alert is triggered when the z-score exceeds 3.5 and the absolute spike crosses 200 events. You won’t get duplicate alerts within a two-hour window. You cannot configure either threshold — it’s not “alert me when blocks exceed N per minute.” It’s “alert me when blocks spike unusually relative to the recent baseline, with a minimum of 200 events involved.”
To set one up:
- Go to Notifications in the Cloudflare dashboard.
- Click Add.
- Pick Security Events Alert (or Advanced Security Events Alert if you’re on Enterprise).
- Select the zones (domains) you want to monitor.
- Set the delivery: email, PagerDuty, or a webhook into Slack / your incident tool / your SIEM.
- Save.
Mean time to detection is about five minutes. That’s good enough to catch a real attack early but not so noisy that you’re getting paged for every transient blip.
If you’re on Pro or Free
Pro and Free plans don’t get the built-in Security Events Alert. You have three reasonable alternatives:
- GraphQL Analytics API polling. Write a small script (Cloudflare Worker, Lambda, GitHub Action on a cron) that queries the GraphQL endpoint every 5–10 minutes for
firewallEventsAdaptivecounts and posts to a Slack webhook when the count crosses your chosen threshold. This is the most flexible — you control the threshold, the time window, and the alert format. - Logpush (Business and up). Stream Security Events to S3 / GCS / Datadog / Splunk and alert from there. This is what larger orgs do anyway because the WAF is one of many log sources you care about.
- Custom rules with a notification action. Cloudflare doesn’t support per-rule notifications, but you can use Cloudflare Workers in front of your custom rule to forward selected mitigation events to a webhook. More work, more flexibility.
For most readers running a single domain on Pro, the GraphQL polling approach (option 1) is the right tool.
Step 6: Review what you’ve built
The dashboards you want to live in for the first month:
- Security → Analytics → Security Analytics. Shows all incoming traffic, including requests not affected by any security control. This is where you sanity-check that you’re not over-blocking; look for legitimate-looking traffic patterns that aren’t reaching origin.
- Security → Analytics → Security Events. Shows everything Cloudflare mitigated — what rule, what action, what request. This is where you triage false positives and tune.
A useful review rhythm:
- Daily for the first week — open Security Events at the end of each day, look at the top mitigated rules, top blocked source IPs, and top mitigated paths. Anything that looks like a legitimate client (your own integration, a known partner, a search bot) gets an exception or an allowlist entry.
- Weekly for the first month — look at trends. Is one rule responsible for 90% of blocks? Is one IP range hammering you? Is there a path on your site that gets hit disproportionately?
- Monthly afterwards — sanity check. The WAF is generally low maintenance once you’ve tuned it, but managed rulesets update weekly, so it’s worth a periodic look.
A few useful tools to add along the way
Once the base WAF is in place, these are the next high-value adds:
- Rate limiting rules. Pick your authentication endpoint (
/login,/api/auth,/wp-login.php) and put a rate limit on it. Even a generous limit (10 req/min per IP) defeats most credential stuffing without affecting legitimate users. - Geo-blocking (selective). If your application has no legitimate users in a region but you’re seeing a lot of attack traffic from it, a country-level block is cheap. Don’t blanket-block; be specific.
- IP allowlists for admin paths. A custom rule that requires source IPs from a known list before serving
/adminor/wp-adminshuts down 99% of admin-bruteforce traffic at the edge. - Leaked credentials detection. Available on Pro and above. Detects when a user submits known-compromised credentials and lets you act (block, challenge, log).
- Super Bot Fight Mode (Pro/Business) or Bot Management (Enterprise). The WAF and the bot product are separate but complementary — credential-stuffing, scraping, and inventory hoarding are bot problems, not WAF problems.
TL;DR
- Don’t go straight to Block. Run new rules in Log mode for at least a week. Watch Security Events daily.
- Deploy the Cloudflare Managed Ruleset. It’s the default for a reason — high signal, low noise.
- Add a WAF Attack Score rule if you’re on Business or Enterprise.
< 20 = Blockis a sensible starting point. - Leave OWASP Core Ruleset off. Cloudflare’s own docs warn it’s high false positive for marginal additional coverage. Only enable if compliance demands it, and then run it in Log mode first.
- Set up Security Events Alert. Business/Enterprise get it native; Pro/Free can build a GraphQL polling job in an afternoon.
- Review daily for a week, weekly for a month. That’s the whole game.
Reference: Cloudflare WAF documentation.