Rate limit, move the door, add a second factor
WordPress Brute Force Attacks: How to Make Them Pointless
Identify a brute force attack on a WordPress login by what it leaves behind: repeated failed sign-ins from rotating addresses, load spikes with no matching traffic, and lockout mail nobody triggered. Automated guessing runs against every install continuously, so the target is not the attempt. Rate limiting, a moved sign-in route and a second factor end the exposure rather than slowing it down.
A WordPress brute force attack is automated password guessing against wp-login.php or XML-RPC. It is continuous and universal rather than targeted. Rate limiting, two-factor authentication and moving the login endpoint remove the exposure; blocking addresses individually does not.
Is your site showing signs of compromise?
Checks what an attacker or a search engine would see from outside, including the giveaways of a cloaked hack.
Reads only what any visitor can see — no login, no access needed. We keep the address, your email and what the check found for 1 year, then delete it. How we handle it.

Symptoms and what they indicate
| Symptom | What it indicates | Urgency |
|---|---|---|
| Hundreds of failed logins from rotating addresses | Distributed guessing in progress | Routine, but confirm the defences |
| Lockout notifications nobody triggered | Attempts against a real username | Routine |
| Load spikes with no matching visitor traffic | XML-RPC amplification | Act this week |
| Failed attempts against one specific username | The username is known and targeted | Act this week |
| A successful login from an unfamiliar location | The guessing succeeded | Treat as a compromise now |
| New administrator accounts | Post-compromise persistence | Treat as a compromise now |
Continuous, universal, and not about you
Every reachable WordPress install receives automated login attempts, continuously, starting within hours of the domain first resolving. The traffic is indiscriminate: software walking address ranges, trying common usernames against common passwords.
That matters for the response. Attempts are not evidence of being singled out, and counting them achieves nothing. What matters is whether any of them can succeed, which is a question about your passwords rather than about their volume.
Why blocking addresses is the wrong instinct
The first reaction to a log full of failed logins is to block the addresses, and it is effort with no return.
The addresses rotate. A distributed attempt uses thousands of them, each making a handful of tries, and a blocklist is obsolete before it is finished. Meanwhile the underlying exposure is unchanged.
Rate limiting works because it does not care where attempts come from. Two-factor works because it removes the value of guessing correctly at all. Both are configuration rather than vigilance, which is the only kind of defence that survives a busy month.
The version that actually succeeds
Random guessing rarely works against a generated password. Credential stuffing does.
An attacker takes username and password pairs from an unrelated breach and tries them against thousands of WordPress sites. No guessing is involved – the password is correct somewhere, and the only question is whether it was reused here.
That is why unique passwords and two-factor sit at the top of the hardening list and why everything else on it is secondary. A reused administrator password defeats every other measure on this page.
Credential attacks are one entry route among several, and the others rarely announce themselves as loudly. What each one looks like, and what closes it, is catalogued on WordPress security threats.
Removing it, in order
- Confirm whether anything succeeded. Failed attempts are noise; a successful login is an incident. Check the user list for accounts nobody created and the last-login times on every administrator before doing anything else.
- Rate limit the login endpoint. Lock out after a small number of failures, per address and per username. This alone removes the economics of guessing.
- Turn on two-factor for every account that can install code. The password stops being sufficient, which ends the entire credential-guessing class regardless of how many attempts arrive.
- Disable XML-RPC unless something needs it. It allows many credential attempts inside one request, which bypasses ordinary login rate limits and is where the load spikes come from.
- Move or protect the login path. Server-level protection stops the traffic before PHP starts, which removes the load as well as the risk.
- Close user enumeration. Author archives and the REST users endpoint publish valid usernames, which is half of every attempt. Both are closed with configuration rather than a plugin.
- Rotate credentials where anything succeeded. Passwords, salts and session tokens together, so an existing session does not survive the reset.
Harden it against a repeat
- Reused credentials from an unrelated breach are the most common way guessing succeeds
- Removes the entire credential-guessing class outright
- Without it an attacker gets unlimited attempts at no cost
- It permits many credential attempts inside a single request
- Usernames are half of every attempt and WordPress publishes them by default
- Automated traffic stops reaching PHP at all
- Every extra administrator is another target and another reused password
- A campaign against one account is visible weeks before it succeeds
Tick the tasks you already run. Where you stand, what the gaps cost and which ones matter appear here.
Site already compromised?
Cleanup starts the same day. We trace the entry point rather than only removing what the scanner found, because a site that reinfects still has the backdoor.
Start recovery$199 one-time, credited against your first month · Included free on Business
Questions people ask before calling
Is my site being targeted?
Almost certainly not personally. Automated guessing runs against every reachable WordPress install continuously, and the traffic is indiscriminate. Attempts against one specific username are the exception worth investigating.
Do I need to block the attacking addresses?
No, and it does not work. The addresses rotate constantly, so blocking them individually is endless. Rate limiting and two-factor remove the exposure regardless of where attempts come from.
Does moving wp-login.php help?
Yes, though not through obscurity alone. The real gain is that automated traffic stops reaching PHP, which removes the server load along with most of the noise in the logs.
How do I know whether an attempt succeeded?
Check the administrator list for accounts nobody created, and the last-login time on every existing account. A successful login from an unfamiliar location is an incident rather than an attack.
Will a security plugin stop this?
It handles the rate limiting well. It cannot give you unique passwords or two-factor, which are the two changes that matter most, and it runs inside PHP so the traffic still reaches the application.
When it needs handing over
wordpress malware removal serviceClean malware out of WordPress and close the route in, so the same infection does not return in a fortnight. Files, database, scheduled tasks and administrator…