Cloudflare WAF Redesign & Cache Recovery for a High-Traffic News Site
Replaced a blunt 'I'm Under Attack' mode that challenged 680,000 real readers with targeted rules, and recovered cache hit rate to 71%.
April 2026/Brazil/12 days (phased implementation)
StackWordPress 6.9.x with JNews child theme · LiteSpeed Cache · Memcached object cache · Cloudflare CDN + WAF · Hostinger Cloud Professional · DreamHost (secondary sister site) · MySQL · Advanced Ads Pro (CVE-2023-2186, CVE-2023-27474) · Elementor Pro (CVE-2023-48777, CVE-2022-1329)
The situation
A high-traffic regional news site got hit with two problems at once. Scammers abused the public job-submission form to post WhatsApp links impersonating real local companies, and the site went from a 723k request/day baseline to 1.48M in 24 hours, a 104% surge. The owners flipped on Cloudflare's 'I'm Under Attack' mode. That threw a 26.6% 403 rate at 680,000 legitimate readers while blocking zero actual attackers. Meanwhile the origin was crashing: Memcached was off, a popular-posts plugin was writing to MySQL on every pageview, and the cache rules were misconfigured. The sister site had its own mess, active web-shell scanning and credential-harvesting probes.
What I found
The job-submission form was taking 15,005 requests in 24 hours, all with crafted /wa.me/ WhatsApp paths appended. The spam used 7 distinct WhatsApp numbers that impersonated real local companies, supermarkets, a dairy brand, a transport company.
The Under Attack Mode response had backfired. In 24 hours it fired 752,707 times, challenged 680,904 legitimate readers (a 90.5% bypass rate), produced 63,222 abandoned sessions, and hard-blocked zero attackers. Googlebot mobile crawl dropped 38% under the verified-bot throttling, and Meta and WhatsApp link-preview bots were getting challenged, which broke shared-article previews. The Vivo ISP, Brazil's #1 carrier and 21% of the site's traffic, was the main victim: 37,162 challenges and 22,980 abandoned.
The cache side was just as broken. Memcached had been off since a prior Duplicator Pro restore. WordPress Popular Posts was writing directly to MySQL twice per pageview. JNews was persisting its query cache with no expiry (the 0-byte transient pattern). HTML cache hit rate at Cloudflare was only 3.4%, because a duplicate cache rule with a 7-day TTL was being overridden by a bypass_by_default rule. And the Cloudflare API token was broken (missing Zone:Read scope), which silently killed every LiteSpeed cache purge.
A few rule-level bugs were wasting resources. One firewall rule had a logic bug, an impossible AND condition on two ASN values, which gave it an 88% bypass rate across 206,822 wasted events. The global rate limit (40 req/10s) was firing on normal page loads because a single article triggers 30 to 60 sub-requests. xmlrpc.php was taking 61 brute-force hits a day, 38 of them POSTs. A legacy Joomla /component/mailto/ endpoint, still reachable, was taking 7,500 GETs and 1,273 POSTs of email-injection attempts.
The sister site had its own problems. Active web-shell scanning from a Korea-based IP was probing for idx_<timestamp>.php filenames that matched attack dates. Credential-harvesting probes hit .env, .aws/credentials, and .git/config from Netherlands, Singapore, and US IPs. Its Cloudflare SSL mode had been set to Flexible (unencrypted origin) since 2020. Barkrowler was consuming 10.9% of its traffic, 3,294 requests a day, with zero SEO value. And a malicious .htaccess with shell-allowlist patterns was sitting in a staging subdirectory.
What I did
I started by pulling 8 days of Cloudflare analytics, 50+ JSON files, to baseline attack versus legitimate traffic. I traced the server crashes back to a combination of things: a Memcached restart, WPP's direct DB writes, a Jetpack autoloader rebuild, and a cache-exclusion rule. Before I touched anything, I took a full database backup (201 MB gzipped), a settings snapshot, and a theme-mods backup.
The performance fixes went in first. I re-enabled Memcached object cache with wp litespeed-option set object 1. I added a WPP_CACHE_VIEWS define to wp-config.php so WPP batches its writes every 2 minutes instead of hammering MySQL. I cleared the slide-tag cache exclusion, disabled the duplicate /noticias/ rule that was overriding the 7-day TTL, and replaced the broken API token with a scoped one (Zone:Read + Cache Purge). To keep Cloudflare in sync, I deployed a small mu-plugin, cf-auto-purge-on-save.php, that purges on every post save.
The JNews cache needed its own diagnosis. I queried ModuleQuery::do_query directly inside Memcached, which surfaced the missing-expiry pattern. I disabled the JNews query cache and enabled flush-on-publish, so editor changes actually show up on the homepage.
Then IUAM came out. I designed 7 new WAF rules to replace it: a verified-bot bypass with anti-spoof guards, a scanner/crawler UA block covering 30+ patterns (nmap, masscan, zgrab, nikto, wpscan, sqlmap, acunetix, nuclei and more), a sensitive-endpoint block for wa.me paths, xmlrpc, and the Joomla legacy endpoint, admin and API protection, a threat-score challenge, a non-browser UA challenge, and a cloud/hosting ASN challenge. I added two rate-limit rules: RL1 on admin and login, RL2 site-wide at 500/60s with static assets excluded. I also fixed the logic-bug rule and killed the overly broad Vivo ASN rule.
Rollout went in three phases: immediate blocks first, then bot bypass and rate-limit fixes, then the IUAM revert and cache-rule cleanup. On the recommendations side, I suggested Turnstile CAPTCHA on the form with a wa.me content filter and editorial review enforcement, Zero Trust on /wp-admin and /wp-login via Cloudflare Access, and for the sister site, an SSL upgrade to Let's Encrypt plus switching from Flexible to Full (Strict).
How it landed
After 12 days the site was stable. Server load dropped from crash-level spikes to around 10% utilization (6.3 on a 64-core box). Cache hit ratio climbed back to 71.1% and Memcached itself was hitting 90.82%. MySQL connections returned to normal, 77 of 2000. The editor publish workflow that had been lagging for minutes now updates the homepage in seconds. The Under Attack numbers told the story on their own: 680k+ real readers challenged, zero attackers hard-blocked, so pulling it out for targeted rules was not a close call. HTML edge cache should climb from 3.4% to the 40% range once the new rules warm up. The client got 203 JSON data files, 15 markdown analysis documents, and rollback steps for every change.
In their words
“Tanveer did an outstanding job and exceeded my expectations in every aspect. He was extremely professional, transparent, and honest throughout the entire process. He performed a deep technical analysis of my website, identified critical issues that were affecting performance and stability, and implemented precise solutions with great expertise. He fixed server crashes, optimized WordPress performance, corrected complex caching problems (including JNews and LiteSpeed), and properly restored the Cloudflare integration. What impressed me the most was his methodical approach: every change was explained, approved, and backed by real evidence and testing. Communication was clear, patient, and highly professional from start to finish. I highly recommend Tanveer to anyone looking for a skilled, trustworthy, and detail-oriented professional. I would definitely work with him again.”