Cloudflare WAF Custom Rules lets you create precise traffic filtering rules. Rules run at the Cloudflare network level — malicious requests are blocked before reaching the server.
Creating a Rule: Security → WAF → Custom Rules → Create
Block a Country
Condition: ip.geoip.country eq "RU"
Action: Block
Protecting /wp-login.php
Condition:
(http.request.uri.path eq "/wp-login.php")
AND NOT (ip.src in {123.45.67.0/24})
Action: Managed Challenge (CAPTCHA)
Block Bad Bots
Condition: cf.client.bot
Action: Block
Allow Only Specific Countries
Condition:
NOT (ip.geoip.country in {"UA" "RU" "BY"})
AND http.request.uri.path starts with "/admin"
Action: Block
Blocking a Specific IP
Security → WAF → Tools → IP Access Rules → Add.
IP or range (1.2.3.4 or 1.2.3.0/24) → Action: Block.
Bot Fight Mode
Security → Bots → Bot Fight Mode → On. Automatically blocks known malicious bots without creating manual rules.
Firewall Logs
Security → Events — a full log of all blocked and challenged requests with the block reason, IP, country, and request type.
Actions in Custom Rules
| Action | What happens |
|---|---|
| Block | The request is rejected, the visitor sees error page 1020 |
| Managed Challenge | Cloudflare itself decides whether to show a check |
| JS Challenge | A mandatory check that runs JavaScript |
| Interactive Challenge (CAPTCHA) | A visual puzzle for the visitor |
| Allow | Skip without further WAF checks |
| Log | Just write to the log, do not block (for testing) |
Before turning on Block for a new rule, set it to Log first and watch Security → Events for a few hours — that shows whether legitimate requests are getting caught by the rule.
Common mistakes when setting up rules
The rule blocked the administrator
This often happens with country or IP-range rules when the admin connects from a different country or through a VPN. Add an exception to the rule's condition with AND NOT (ip.src in {YOUR_IP}), or create a separate IP Access Rule with the Allow action — it has higher priority.
The rule is created but never fires
Check the order of conditions: AND means both conditions must be true at once, not either one. People often confuse it with OR and end up with a rule that matches no real request at all. Also check that the rule is enabled (the Enabled toggle), not sitting saved as a draft.
Verifying the result
# Check that the rule blocks the intended request
curl -I -A "BadBot/1.0" https://example.com/wp-login.php
HTTP/2 403
cf-mitigated: challenge
If the expected status is missing, open Security → Events and find the request by time: it shows exactly which rule (or the lack of one) handled it.
When Custom Rules do not fit
- You need protection against application-level attacks that cannot be expressed as a simple condition (for example, business-logic anomalies) — that calls for a full WAF Managed Ruleset or server-side analysis.
- You need to change behavior in real time with complex logic — a Worker, which can run arbitrary code, fits that better.
- The plan's rule limit is used up and there is no more room to merge conditions with OR — move part of the logic into Rate Limiting Rules or Bot Management, which have their own separate limits.
Rule conditions are built on fields such as http.request.uri.path, ip.geoip.country, and http.user_agent — the full field list opens right inside the rule builder when you pick a field from the dropdown, so there is no need to memorize the syntax.
IP Access Rules can be created at three levels: for a single site (Zone), for every domain on the account at once (Account), or personally for your own login (User). An Account-level rule is handy for blocking the same malicious IP across every project at once without duplicating it.
Before saving a rule, Cloudflare shows a preview of how many recent real requests would have matched the condition. If that number looks unexpectedly high for what seemed like a narrow condition, double-check the rule's logic before enabling it, not after.
The Description field on a rule has no effect on filtering logic, but it saves time during an audit of a list of a dozen rules six months later, once you no longer remember why a particular rule was created.
Custom Rules and IP Access Rules apply before a request ever reaches the cache or the application code — a blocked request never shows up in your server logs or in your own site's visitor analytics, only in Cloudflare's own Security → Events.
Frequently asked questions
What happens if both a Custom Rule and Bot Fight Mode match the same incoming request?
Cloudflare rules apply in a set priority order, and more specific protection mechanisms, including IP Access Rules and certain built-in checks, generally run before the broader Custom Rules and Bot Fight Mode. In practice this means a request stops at whichever rule fires first, and the remaining mechanisms never even get to evaluate it.
Can a rule be temporarily turned off without deleting it if it starts blocking legitimate visitors?
Yes, every rule has an enabled toggle that temporarily turns off its logic without deleting the rule or its conditions. That makes quick troubleshooting easy: disable the suspicious rule, check whether access returns for the affected visitors, then switch the rule back on once the condition has been fixed.
Do blocked Custom Rules requests show up in the logs on your own server?
No, a request stopped at the Cloudflare level never reaches the origin server, so it never shows up in the web server's own logs or in the site's own visitor analytics. The only place that request is visible is the Security → Events section in the Cloudflare dashboard, and that is where to look when investigating this kind of block.
If an IP Access Rule allows an address but a Custom Rule blocks that same address, which one wins?
IP Access Rules run before Custom Rules and carry higher priority, so an allow rule set at the IP Access Rules level wins over a blocking condition in Custom Rules for that same address. That is exactly what makes them a handy tool for narrow exceptions, such as a trusted work IP, regardless of how the broader rules are written.