When Your WordPress Site Gets 99% Bot Traffic: Finding and Fixing a Hidden Security Problem
A client contacted us about an unusual problem: their WordPress website was being overwhelmed with traffic. They were receiving 69,000 requests per day, nearly maxing out their hosting plan. The site is a nonprofit membership and events site — nothing viral, nothing that explained this surge.
What we found was two separate problems, connected by a security vulnerability. And what seemed like a hosting catastrophe turned out to be an opportunity to secure the site and cut their hosting costs.
The First Problem: A Credential Attack
When we dug into the traffic logs, the pattern was unmistakable. The site was being hammered with login attempts — roughly 9,000 POST requests to the login page per day, coming from constantly changing IP addresses. This wasn't a simple password-guessing attack that could be blocked by banning an address. It was a distributed attack using dozens of different IPs.
The attacker wasn't trying random usernames. The attempts looked targeted, which raised a question: how did they know which usernames to attack?
The Second Problem: The Information Leak
We found the answer in a WordPress technical endpoint that most people don't know exists. Every WordPress site has a REST API — a machine-readable interface designed so mobile apps and other tools can talk to WordPress. By default, the user endpoint publishes a list of every account on the site to anyone who asks, without requiring a login.
On this site, that endpoint was returning 32 user accounts in full detail: real names, the usernames people log in with, and hashed email addresses. Six of those accounts were administrators — including four shared administrative logins used by board members for different roles like president, membership coordinator, and webmaster.
The two problems were connected. The attackers were reading that public list to find valid administrator usernames, then using those names to guess passwords. This explains why the attack looked targeted rather than random. And it meant the people running the nonprofit had unknowingly published the names of the accounts with complete control over their website.
Did Anyone Get In?
We checked. We reviewed all administrator accounts, recent account creations, custom code, and the plugin list. We found no evidence that the attack succeeded. The exposed information didn't include passwords or payment details — but it included everything an attacker needed to know that they were attacking valid targets.
Because six administrator usernames had been publicly readable for an unknown period, we recommended password resets on those accounts as a precaution.
The Fix
We deployed a layered approach:
Blocked the information leak — We closed the public endpoint in two independent places so a failure in one doesn't reopen it. We also added code at the WordPress level, not just the edge, so even direct attacks on the origin are blocked.
Stopped the login attack — We added a Cloudflare Turnstile challenge to the login form. Real members pass it invisibly. Automated scripts cannot. Critically, WordPress never even evaluates the password on these automated attempts — so attackers learn nothing, not even whether a username is valid.
Added rate limiting — A backup limit now caps how quickly anyone can attempt to log in from a single IP.
Closed an unused attack vector — WordPress has an outdated technical interface called XML-RPC that attackers commonly exploit. We turned it off.
Updated everything — We found 24 out of 40 WordPress plugins were out of date and updated them all. Outdated add-ons are the #1 way WordPress sites actually get compromised, so this matters more than the flashy stuff.
Fixed a crawling problem — The Events Calendar was generating thousands of uncrawlable archive URLs that bots were hammering. We blocked those and cached the legitimate event pages.
What Members Noticed
Essentially nothing. Logging in works exactly as before. The challenge is invisible in a normal browser. The public website, the member directory, and the events calendar are all unchanged.
The Payoff: 99% of Traffic Was Bots
Here's where this gets interesting. We measured the traffic before and after.
Before: 69,000 requests per day, of which only about 850 were real people. The rest was automated.
After: Origin load down 84% in nine days. The site is now handling the same real traffic but without the bot noise.
The client was paying for a hosting plan sized for 100,000 visits per month. They were actually getting 850–1,500 human visitors per month. All those other "visits" were the attack and the crawlers.
By fixing the security problem, we also opened the door to moving to a smaller, significantly cheaper hosting plan. Deploying two-factor authentication on the hosting account is the remaining step — without it, the hosting provider's login panel can bypass WordPress's own protections entirely.
What This Cost
Some of this was just having eyes on the logs. The Cloudflare setup required a free account (the client already had one). Turnstile is free. The WordPress code change was a handful of lines. The plugin updates were automatic but required testing.
Total: a few hours of careful work, zero paid tools, and a security fix that doubles as a hosting cost reduction.
Why This Matters
This story matters because it happens quietly on thousands of WordPress sites. A nonprofit or small organization gets a hosting bill spike they don't understand, or they get hacked through a plugin they forgot to update, or their hosting bill climbs because bots are consuming resources. Often these aren't separate problems — they're connected. The security vulnerability attracts the attack, which inflates the hosting bill.
The fix usually isn't exotic. It's understanding what's actually happening, layering some basic protections, and keeping your software current. It's doing the boring stuff right.
If this sounds like your WordPress site, that's worth an audit. We can help. Get in touch →