WAF Custom Rules: Securing Apps with Cloudflare Traffic Control
Learn how to implement WAF custom rules in Cloudflare to block malicious traffic, restrict specific countries, and protect your infrastructure from threats.

Previously in this course, we explored Rate Limiting Basics: Protecting Your Apps with Cloudflare, which allows you to throttle aggressive users. In this lesson, we shift from throttling to definitive blocking.
While rate limiting handles high-volume traffic, WAF (Web Application Firewall) Custom Rules provide the precision needed to stop specific threats—like malicious IP ranges, known bad actors, or traffic from regions where your application doesn't operate—before they ever reach your origin server.
Understanding WAF First Principles
The Cloudflare WAF sits at the edge of the network. When a request hits the Cloudflare global network, it passes through the security engine before hitting any cache or origin server.
A WAF rule consists of two parts:
- The Expression (The "If"): A filter that identifies the traffic (e.g., "Is the country X?" or "Is the IP in this CIDR range?").
- The Action (The "Then"): What to do with the match (Block, Managed Challenge, JS Challenge, or Log).
Why use Custom Rules?
Unlike Page Rules (which we covered in Implementing Page Rules for Security: A Developer's Guide), WAF rules are evaluated with a "deny-by-default" mindset if you choose, and they support complex boolean logic across headers, ASN, country codes, and IP addresses.
Creating a WAF Custom Rule

Let's protect our project by blocking traffic from a specific country and a known malicious IP range.
- Navigate to your domain in the Cloudflare Dashboard.
- Go to Security > WAF > Custom rules.
- Click Create rule.
- Rule name: Give it something descriptive, like
Block_Unauthorized_Geo_And_IP. - Expression Editor: Use the "Edit expression" mode for maximum control.
The Logic Syntax
Cloudflare uses a specialized syntax. To block a country and an IP range, your expression will look like this:
Bash(ip.geoip.country eq "XX") or (ip.src in {192.0.2.0/24 203.0.113.0/24})
Replace XX with the two-letter ISO country code (e.g., "US", "CN", "DE").
- Action: Select Block.
- Click Deploy.
Testing WAF Blocking Behavior
You must verify your rules before relying on them. Since you probably don't want to block your own IP, use these methods to test:
1. The "Simulate" Method (Recommended)
Before setting the action to Block, set the action to Log. This allows the traffic through but marks it in your dashboard logs.
- Go to Security > Events.
- Filter by your rule name.
- If you see the traffic being "logged," you know the expression is matching correctly.
2. Using curl for Verification
To test an IP block, you can temporarily add your own IP to the block list (be careful!) or use a VPN/Proxy service to route traffic from the country you are blocking.
Bash# Test the response from your terminal curl -I https://your-app.com
If the rule is active and matching, you will receive a 403 Forbidden response.
Common Pitfalls
- Blocking Yourself: Always verify your own IP address before applying a broad "Block" rule. Cloudflare provides a "Skip" rule type if you need to whitelist your office or home network.
- Over-Blocking: Blocking entire countries can hurt SEO or legitimate users who use VPNs based in those countries. Prefer Managed Challenge over Block if you want to let real users pass a captcha while stopping bots.
- Order of Operations: Rules are evaluated in order. If you have a "Allow" rule at the top, it will bypass any "Block" rules further down.
FAQ
Q: What is the difference between Managed Challenge and Block? A: A Block returns a 403 immediately. A Managed Challenge presents a Cloudflare-hosted interactive challenge (like a captcha) to the user. Use the challenge for humans you don't want to lose; use block for known scrapers.
Q: Can I block based on user-agent?
A: Yes, using http.user_agent. However, note that user-agents are easily spoofed by malicious actors.
Q: Does this affect my D1 database or R2 storage? A: Since your Worker acts as the gateway to your D1/R2 resources, a WAF block at the edge prevents the request from ever triggering your Worker code, effectively protecting your backend from unnecessary compute and egress costs.
Recap
You have successfully implemented a WAF custom rule to filter traffic at the edge. By using the expression builder, you can now enforce geographic and network-based policies that protect your application's resources before they are ever consumed.
Up next: Managing Secrets Securely — we'll look at how to handle API keys and environment-specific credentials without leaking them in your source code.
Work with me

Custom Email & File Storage System on Cloudflare (Google Workspace Alternative)
Your own private email + file storage suite on your domain — unlimited mailboxes, no per-seat fees. A self-owned Google Workspace alternative for a flat ~$5/month.

Custom WordPress Plugin Development
Custom WordPress & WooCommerce plugins built to standard — by the developer behind a plugin with 5,000+ active installs and a SaaS with 10,000+ users.


