How to Stop Brute-Force Attacks on WordPress Login
You stop WordPress brute-force login attacks by rate-limiting failed login attempts, requiring two-factor authentication, and closing off the two doors attackers actually use — wp-login.php and xmlrpc.php — while skipping the tweaks that feel like security but don't add real protection.
This is for anyone running WordPress — a small business owner, an agency managing client sites, or a solo blogger — who's noticed a wall of failed login attempts in their logs, or just wants to get ahead of it. You'll get a step-by-step hardening stack with exact plugin names and config snippets, plus an honest breakdown of what's real defense versus what's just theater.
What a brute-force attack on WordPress actually looks like
Most WordPress attacks aren't a person typing passwords by hand. They're bots working through a list — either guessing many passwords against one username (classic brute force), or trying username/password pairs leaked from other breaches against your site (credential stuffing, per OWASP's Credential Stuffing Prevention Cheat Sheet). Both hit /wp-login.php (and /wp-admin/, which just redirects there) at high volume, hoping your admin account uses a weak or reused password.
There's a second, less obvious front: xmlrpc.php. This is WordPress's legacy remote-publishing API, and its system.multicall method lets an attacker bundle hundreds of username/password guesses into a single HTTP request. That means basic rate limiting — which usually counts requests, not the login attempts hidden inside them — can miss it entirely. This is one of the most useful facts in this guide, because most login-hardening advice ignores it.
The hardening stack: what matters vs. what's theater
| Defense | Actually stops brute force? | Effort |
|---|---|---|
| Rate-limit / lock out after failed attempts | Yes | Low (plugin) |
| Two-factor authentication (2FA) | Yes | Low–medium |
| Disable or restrict XML-RPC | Yes | Low |
| Strong, unique passwords + no shared logins | Yes | Low |
| WAF / edge rate limiting (e.g. Cloudflare) | Yes, blocks before WordPress even loads | Medium |
Hide/rename wp-login.php | Partial — cuts noise, not a real barrier | Low |
| Rename the "admin" username | Partial — stops the laziest bots only | Low |
| Login CAPTCHA | Partial — slows automation, not a full stop | Low |
If you only have time for two things, do the first two rows.
Step 1: Limit login attempts and lock accounts out
Install Limit Login Attempts Reloaded (free, wordpress.org) and configure:
- Lockout after 4 failed attempts.
- Lockout duration: 20 minutes, doubling on repeat offenses.
- "Cookie-based brute-force protection" and IP logging turned on so you can see who's knocking.
If you're behind Cloudflare (even the free tier), add a rate-limiting rule: block or CAPTCHA-challenge any IP sending more than 5 POST requests to /wp-login.php within 1 minute. Edge-level rate limiting stops traffic before it ever reaches your server, which matters if you're on shared hosting where WordPress itself can get overwhelmed just processing the attempts.
Step 2: Turn on two-factor authentication (2FA)
This is the single highest-leverage step. Even if a bot guesses your password, it still can't log in without the second factor. Use the official Two Factor plugin (wordpress.org, maintained by WordPress core contributors) or the 2FA module in Wordfence or Solid Security (formerly iThemes Security). Enforce it on every account with Administrator or Editor access — not just yours. CISA lists multi-factor authentication as one of the highest-impact steps anyone can take to prevent account takeover; see their guidance on turning on MFA.
Step 3: Disable or restrict XML-RPC
Most sites don't need XML-RPC anymore — WordPress 5.6+ added Application Passwords (under Users → Profile → Application Passwords) and a REST API that cover what the old Jetpack/mobile-app integrations used it for. If you don't use the WordPress mobile app or Jetpack's older connection method, block it outright.
Apache (.htaccess):
<Files xmlrpc.php>
Require all denied
</Files>
Nginx:
location = /xmlrpc.php {
deny all;
}
If you do need XML-RPC (some Jetpack features still use it), don't disable the whole file — just remove the dangerous multicall method with a small must-use plugin:
add_filter( 'xmlrpc_methods', function( $methods ) {
unset( $methods['system.multicall'] );
return $methods;
});
Step 4: IP-level lockout with fail2ban (self-managed servers/VPS)
If you manage your own server, install the WP fail2ban plugin, which logs failed WordPress login attempts to syslog in a format fail2ban can parse, then add a jail:
[wordpress]
enabled = true
filter = wordpress
logpath = /var/log/auth.log
maxretry = 5
findtime = 600
bantime = 3600
This bans the IP address at the firewall level after repeated failures — the attacker can't even reach wp-login.php again, not just get denied by it. On managed hosting (WP Engine, Kinsey, most shared hosts) you won't have shell access for this; lean on your host's built-in brute-force protection instead, which most reputable WordPress hosts now include.
Step 5: Hiding wp-login.php — useful, but don't count on it
Plugins like WPS Hide Login let you change your login URL from /wp-login.php to something custom, like /portal-access. This is "security through obscurity" — it doesn't fix a vulnerability, it just makes your site a less visible target to the dumbest, most generic bots scanning the entire internet for /wp-login.php. It genuinely does cut down log noise and server load. It should never be your only defense, because a single leaked link, a misconfigured cache, or a targeted attacker (rather than a mass scanner) bypasses it instantly.
What's mostly theater
- Renaming the "admin" username alone — helps against the laziest scripts, does nothing against credential stuffing using real emails.
- A CAPTCHA with no rate limiting behind it — slows bots down, doesn't stop a patient attacker.
- "We're secure" trust badges — cosmetic, provide zero technical protection.
None of these are harmful to have, but don't let them substitute for 2FA and rate limiting.
Quick setup checklist
- [ ] Login lockout after 4–5 failed attempts (plugin or edge rule)
- [ ] 2FA enforced on every admin/editor account
- [ ] XML-RPC blocked, or
system.multicallremoved if you need it - [ ] Unique, strong passwords — no shared logins across staff
- [ ] fail2ban or host-level IP lockout if you're on a VPS
- [ ] (Optional) login URL hidden to cut down bot noise
If you're not sure any of this is actually configured correctly on your site, WordPress.org's own hardening guide is a solid technical reference to check settings against — or run our free passive security check to see what's exposed without touching your site.
If you're already seeing signs something's wrong — unfamiliar admin users, spam pages appearing, a host warning you — that's a different problem than prevention; our guide on what to do if your website's been hacked walks through the recovery steps. And if you're just trying to figure out your overall exposure before it gets to that point, our guide on how to tell if your website is hackable is a good next read.
Key takeaways
- Rate limiting plus two-factor authentication stops the overwhelming majority of WordPress brute-force attempts — everything else is secondary.
- XML-RPC's
system.multicalllets attackers test hundreds of passwords in one request, so basic rate limiting alone can miss it — block or restrict it directly. - Hiding
wp-login.phpreduces bot noise but is not a real security control on its own. - Renaming the "admin" username and adding a CAPTCHA are minor helpers, not defenses — don't rely on them alone.
- If you manage your own server, fail2ban with the WP fail2ban plugin adds real IP-level lockout; on managed hosting, confirm your host already does this.
Hardening login is one piece of the picture — it won't catch a vulnerable plugin, an outdated theme, or a misconfigured form elsewhere on the site. A Circuit audit is $49 and gets a real person manually checking your whole site, not just the login page, with a written report of exactly what's wrong and how to fix it. No pressure — it's just the honest next step once the login is locked down.
A real human security engineer audits your whole site by hand and sends a full report — every issue, its severity, and the exact fix. From $49, with a 14-day money-back guarantee.
See pricing