How to Stop Brute-Force Attacks on WordPress Login

By Bug Circuit Security Team
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

DefenseActually stops brute force?Effort
Rate-limit / lock out after failed attemptsYesLow (plugin)
Two-factor authentication (2FA)YesLow–medium
Disable or restrict XML-RPCYesLow
Strong, unique passwords + no shared loginsYesLow
WAF / edge rate limiting (e.g. Cloudflare)Yes, blocks before WordPress even loadsMedium
Hide/rename wp-login.phpPartial — cuts noise, not a real barrierLow
Rename the "admin" usernamePartial — stops the laziest bots onlyLow
Login CAPTCHAPartial — slows automation, not a full stopLow

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:

  1. Lockout after 4 failed attempts.
  2. Lockout duration: 20 minutes, doubling on repeat offenses.
  3. "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.multicall removed 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.multicall lets attackers test hundreds of passwords in one request, so basic rate limiting alone can miss it — block or restrict it directly.
  • Hiding wp-login.php reduces 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.

Want certainty, not guesswork?

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

Common questions

How do I stop brute-force attacks on WordPress?
Limit login attempts with a lockout after 4-5 failures (plugin like Limit Login Attempts Reloaded, or a Cloudflare rate-limiting rule), turn on two-factor authentication for every admin account, and block or restrict xmlrpc.php so attackers can't bundle hundreds of password guesses into one request. Those three steps stop the overwhelming majority of automated login attacks; hiding your login URL and renaming the admin account are minor extras, not substitutes.
Is hiding wp-login.php enough to stop brute-force attacks?
No. Renaming your login URL (with a plugin like WPS Hide Login) just makes your site less visible to mass bot scans — it's security through obscurity, not a real barrier. A single leaked link or a targeted attacker bypasses it instantly, so pair it with login lockout and 2FA rather than relying on it alone.
Should I disable XML-RPC on WordPress?
If you don't use the WordPress mobile app or an older Jetpack connection, yes — block xmlrpc.php entirely with a `Require all denied` rule in .htaccess or a `deny all` in Nginx. If you do need it, don't disable the whole file; instead remove just the `system.multicall` method, which is what attackers abuse to test many passwords in a single request.
Do I need a plugin to limit WordPress login attempts?
It's the easiest route, but not the only one. A plugin like Limit Login Attempts Reloaded works well for most sites; if you're on a VPS you can instead use fail2ban with the WP fail2ban plugin for IP-level lockout, or set a rate-limiting rule at your CDN/firewall (like Cloudflare) so requests never reach WordPress at all.

Keep reading

See what attackers see — free

Run the free passive check on your domain. No login, no impact on your site, results in seconds.

Passive recon only. No login, and no impact on your site. Deeper testing needs domain verification.

Ready for the full manual audit? See transparent pricing →

Published by Bug Circuit. Written with AI assistance and reviewed for accuracy before publishing.