How Cloudflare Saved My Store: A Real Case Study — Stopping Bot Attacks, Protecting Firebase, and Locking Down Admin Access
A step-by-step, real-world guide for small business owners and online sellers. This is a full technical walkthrough of how I hardened Link My Site using Cloudflare firewall rules, rate-limiting, Zero Trust access policies, and Firebase best practices to stop malicious traffic, prevent a drained database, and keep admin access locked down.
Short take: within 48 hours of enabling targeted Cloudflare rules and a Zero Trust login policy (single verified email + country restriction + one-time PIN), I stopped automated attacks that were depleting my Firebase quota and breaking site features. Below is exactly how I did it — step by step.
The wake-up call — how the attack looked and why it mattered
Shortly after launching Link My Site, I started seeing intermittent feature failures: categories didn’t load, product lists returned empty, and some customers reported missing content. Investigation showed the root cause was a sudden spike of API requests hitting Firebase. My daily Firebase quota was being drained by automated clients and scrapers — not a single targeted breach, but volume-driven resource exhaustion.
Lesson learned: An attacker doesn't have to "break in" to cause severe disruption. High-volume automated traffic (curl/wget/python scripts, scanners) can quickly exhaust quotas and cause real downtime for paying customers.
Once I identified that the traffic was coming from scripted clients, scanners, and generic probes (often hitting /.git, /wp-admin, and direct SDK paths like /__/*), I moved immediately to defend the origin with Cloudflare and to lock down admin access behind Zero Trust.
What I deployed — quick overview
Here’s the exact defensive stack I deployed, in deployment order (this order is important; each layer buys time for the next):
- Cloudflare firewall rules — five targeted rules that block common scanners, CLI clients, WP probes, reconnaissance, and direct Firebase access.
- Rate limiting — 10 requests per 10 seconds per IP on key endpoints to stop bursts and thread-based scraping tools.
- Zero Trust (Cloudflare Access) — admin/login area protected by a single verified email, One-Time PIN (OTP), and country restriction.
- Firebase rules & architecture changes — minimize blast radius and require authenticated admin operations.
- Monitoring & alerting — review firewall events, enable alerts for quota spikes and unusual traffic.
Detailed Cloudflare firewall rules — copy/paste ready
Below are the exact rules I created. I include the intent, the Cloudflare match expression (copy-ready), and the recommended action. In Cloudflare: Dashboard → Security → WAF → Firewall Rules (or Firewall Rules depending on UI).
Rule 1 — Block Bad Bots (broad)
Purpose: Block known or obvious malicious scanners and fingerprinting tools before they reach the origin.
(http.user_agent contains "sqlmap") or (http.user_agent contains "masscan") or (cf.client.bot) or (ip.geoip.as_number in { 0 })
Action: Block
Notes: Use Cloudflare’s built-in bot detection (cf.client.bot) plus user agent checks for known tools. For the ASN list, you can add known malicious ASNs if you have intelligence; otherwise leave out the ASN clause.
Rule 2 — Block WordPress probes
Purpose: Many automated scanners hit common WordPress endpoints across the internet. Even non-WordPress sites receive this noise; blocking it reduces useless traffic.
(http.request.uri.path contains "/wp-admin") or (http.request.uri.path contains "/wp-login.php") or (http.request.uri.path contains "/xmlrpc.php")
Action: Block (or Managed Challenge if you want to confirm).
Rule 3 — Block CLI/scripted clients (curl, wget, python)
Purpose: Scrapers and brute-force tools often use predictable clients; challenge or block them.
(http.user_agent contains "curl") or (http.user_agent contains "Wget") or (http.user_agent contains "python-requests") or (http.user_agent contains "Go-http-client")
Action: Managed Challenge (recommended) — this shows CAPTCHA to humans but blocks bots.
Tip: Use Block only if you are sure no legitimate integration uses these clients.
Rule 4 — Protect Firebase, admin, and login endpoints
Purpose: Prevent direct hits to SDK paths and admin pages which can be abused to drain quota or attempt admin access.
(http.request.uri.path contains "/__/firebase") or (http.request.uri.path contains "/admin") or (http.request.uri.path contains "/login")
Action: Managed Challenge for /login
, Block for direct /__/firebase
hits (if you proxy everything through your site). Use Managed Challenge for /admin
if real humans need access with CAPTCHA; otherwise prefer Zero Trust for admin access.
Rule 5 — Block reconnaissance and leak attempts (git, .env, backups)
Purpose: Prevent scanners from finding .git trees, environment files, or backup archives.
(http.request.uri.path contains "/.git") or (http.request.uri.path contains ".env") or (http.request.uri.path contains "backup.zip")
Action: Block
Rate Limiting — 10 requests per 10 seconds
Purpose: Stop high-rate bursts from a single IP which leads to quota exhaustion.
Scope: /* (or more selective: /api/*, /v1/*)
Threshold: 10 requests per 10 seconds per IP
Action: Block for 60 seconds (or Challenge)
Why 10/10: Typical human browsing won't exceed this; threaded scrapers will. Tune if your legitimate users need higher throughput from single IPs (e.g., some corporate proxies).
Step-by-step: creating these rules in Cloudflare
Follow these steps to implement the rules exactly:
- Log in to Cloudflare dashboard and select your domain.
- Go to Security → WAF → Firewall Rules (or Security → Firewall Rules depending on UI).
- Click Create a Firewall Rule, name it (e.g., Block Bad Bots), paste the expression from the list above, choose the Action, and Deploy.
- Repeat for each rule. Order matters — put broad, high-confidence blocks first (bad bots, CLI clients), then path-based protections.
- Set up Rate Limiting in Security → Rate Limiting and apply the 10/10 rule to the endpoints you want to protect.
How to test rules safely
Testing is critical. Use these steps to verify without breaking legitimate traffic:
- Open an incognito/private browser window and hit your site normally — confirm pages load.
- Use a VPN to replicate an external country IP and visit your login and admin endpoints (this verifies geo and challenge behavior).
- Use curl/wget from a test machine to perform scripted requests: e.g.,
curl -I <"example.com/">"example.com"
and confirm the CLI-block rule triggers a challenge or block. - Trigger the rate limit from a controlled IP (a looped curl script) to confirm the rule throttles as expected.
Cloudflare Zero Trust: locking down admin with OTP + email + country
Protecting the admin area with Cloudflare Access (Zero Trust) is what converted these firewall rules into a full “zero-access” admin workflow. Below are the exact steps I used.
Step A — Verify the admin email in Zero Trust
- Go to one.dash.cloudflare.com and sign in with your Cloudflare account.
- Open My Account → Emails (or Identity → Account Emails) and Add Email.
- Enter
"[email protected]"
and click Send Verification Email. Click the link in that email to verify ownership.
Step B — Configure login methods
- In the Zero Trust dashboard, go to Access → Settings → Login Methods.
- Enable One-time PIN (OTP) and disable Accept all available identity providers. This prevents other identity providers from acting as fallbacks.
- Leave any WARP automatic auth off unless you want devices to pass through as trusted automatically.
Step C — Create an Application (your login page)
- Go to Access → Applications → Add an application.
- Choose Self-hosted or HTTP application and enter the exact URL:
"https://example.com/login"
. - Name it (e.g., Login Auth — Name Of Site) and proceed to Policies.
Step D — Create the policy (Include + Require)
This is the critical policy that enforces single-email OTP plus country requirement.
- Policy Name: Enter Site Name Here, Action: Allow.
- Include (OR): Selector = Emails, Value =
"[email protected]"
. (Make sure there are no placeholder emails left.) - Require (AND):
- Selector = Country, Value =
(enter the country)
- Selector = Login Methods, Value =
One-time PIN
- Selector = Country, Value =
- Session Duration: set to 1–2 hours (or use application default).
- Save the policy — this step is critical. If you don’t click Save, the policy will not be enforced.
"[email protected]"
in the Include rules, remove it. If you don't save the policy, nothing will change.
Step E — Verify the Zero Trust behavior
- Open an incognito browser and navigate to
"example.com/login"
. - Enter a non-authorized email — expect immediate Deny (no OTP sent) or a Managed Challenge followed by Deny depending on settings.
- Enter
"[email protected]"
from a Country IP — you should receive OTP immediately. - Test from a VPN set to a different country (e.g., USA) — you should get challenge → Deny (no OTP sent).
Firebase rules & architecture — reducing blast radius
Even with Cloudflare, you must harden Firebase so a single noisy endpoint can't break everything.
- Segregate data: Keep public product collections separate from admin or billing collections.
- Require auth for admin writes: Tighten Firebase rules so only authenticated, role-tagged users can change critical data.
- Server-side throttling: Implement server-side request validation and per-user rate-limits so no single client can exhaust quota.
- Alerts and quotas: Configure Firebase alerts when reads/writes approach threshold so you can react before quota exhaustion.
How to read Cloudflare analytics & firewall events (what to look for)
Cloudflare analytics and Firewall Events are where you’ll find evidence the rules are working. Key metrics:
- Firewall Events count — number of blocked or challenged requests per rule.
- Rate limit triggers — how often the 10/10 rule fires.
- Top source countries & IPs — shows attacker geography.
- Top user agents — lets you see curl/wget/python requests being blocked.
- Peak minute/hour — tells you intensity and whether a minute could have drained Firebase.
Template for your analytics section (replace placeholders):Attack window: 2025-09-14 02:30 UTC → 2025-09-14 07:00 UTC Total blocked requests: XXXXX Firewall rule "Block CLI clients (curl/wget/python)" blocked: YYYY Firewall rule "Block Bad Bots" blocked: ZZZZ Rate limit (10/10) triggered: AAAA times Top offending country: US (62%), RU (18%), CN (10%) Peak blocked minute: 2025-09-14 03:12 UTC (3450 requests)
Interpreting the numbers: the total blocked requests are the traffic you did not have to serve. If your peak blocked minute’s volumes had reached Firebase, your site would have failed. Rate-limit triggers indicate automated bursts stopped by the 10/10 rule.
Testing & validation checklist — do this right away
- Incognito + correct admin email (Country IP) → OTP delivered, login succeeds.
- Incognito + wrong email (any IP) → immediate Deny, no OTP delivered.
- VPN outside Country→ Managed Challenge then Deny (no OTP).
- Run a curl-based automated script to your endpoints — confirm CLI rule triggers.
- From a controlled IP, fire repeated calls to trigger the rate limit and confirm block behavior.
- Check Cloudflare Firewall Events and filter by each rule to confirm matches.
Troubleshooting common issues
OTP not delivered
Check that the admin email is verified under My Account → Emails in the Zero Trust dashboard. If not verified, OTPs may not be reliably sent. Also check your email provider spam filters and delivery logs.
Policy changes not taking effect
Remember to click Save when editing policies. If you edit and leave the page without saving, the old policy remains active.
Legitimate traffic blocked
If a real customer or integration is blocked, convert the offending rule from Block → Managed Challenge while you investigate. Use Firewall Events to identify false positives.
Real-world rollout timeline (how I applied defenses)
- T+0: Detect spike in Firebase usage and site errors.
- T+15 min: Block
/__/firebase
, add Rate Limit 10/10 to stabilize traffic. - T+30–60 min: Add CLI user-agent blocks and WordPress probe blocks.
- T+2 hours: Deploy Zero Trust login (single email + OTP + country). Test OTP delivery.
- T+24 hours: Review analytics, tune rules (Block vs Challenge), and schedule weekly log reviews.
Final checklist — exactly what to save and monitor
- Cloudflare firewall rules: copy expressions into a safe file (or JSON export) and back them up.
- Rate limit settings: record scope and threshold.
- Zero Trust: verify the admin email, confirm policy saved, and keep session duration documented.
- Firebase rules: back up rules and role mappings, set alerting on quota thresholds.
- Weekly review: firewall events, access logs, and odd spikes in traffic.
Bottom line: By combining Cloudflare firewall rules, rate limiting, and a strict Zero Trust admin policy (single verified email, OTP, country), you can protect a small business site from automated attacks and quota exhaustion — without expensive tooling.