To secure WordPress against brute force attacks, understand that the login form is rarely the only door. XML-RPC accepts credential attempts too, and its system.multicall method historically let an attacker try many passwords in a single request — which is why rate-limiting the login page alone leaves the problem open.
On this page
Find every authentication door
Plans to secure WordPress against brute force attacks usually address wp-login.php and stops. A WordPress installation typically exposes several paths that accept credentials or consume server resources, and an attacker will use whichever is least defended.
- The login form. The obvious one, and the one everybody protects.
- XML-RPC. Accepts authentication, and its multicall capability means a single HTTP request can carry many credential attempts — so request-count rate limiting undercounts the attack by orders of magnitude.
- The REST API. Authenticated endpoints, plus user enumeration on some configurations, which hands an attacker valid usernames to target.
- Application passwords. A legitimate feature and a credential path that bypasses interactive login entirely.
- Author archives and the
?author=parameter, which can reveal usernames even when the login form does not.
Disable XML-RPC unless something you rely on requires it — some mobile apps and legacy integrations do. If you need it, restrict it by address or put it behind edge rules rather than leaving it open. And restrict user enumeration so an attacker has to guess the username as well as the password.
Credentials are the actual defense
Rate limiting slows an attack. Credentials decide whether efforts to secure WordPress against brute force attempts can ever fail, because strength whether it can ever succeed, and the guidance here is settled: NIST SP 800-63B requires passwords used as a single factor to be “a minimum of 15 characters in length,” prohibits imposing “composition rules,” and prohibits requiring users to “change passwords periodically.”
Applied to a WordPress installation, that means four things. Long unique passphrases for every account with elevated privileges, stored in a password manager. Multi-factor authentication on every administrator account, because a long password still falls to a convincing phishing page. Least privilege — most contributors need Author or Editor, not Administrator. And no shared accounts, so that a compromise is attributable and revocable.
One more habit that costs nothing: audit the user list quarterly and remove accounts belonging to people who have left. Dormant administrator accounts with old passwords are the most common way a site is breached without any clever attack at all.
Rate limiting that works
Effective limiting, the operational core of any attempt to secure WordPress against brute force traffic, has three properties that naive implementations miss.
Count attempts, not requests. Because of multicall, one request can contain many attempts. A limiter that counts HTTP requests will happily allow thousands of password guesses.
Limit by username as well as by address. Modern credential attacks are distributed across many addresses, trying a handful of passwords per address against the same account. Per-address limits never trigger; per-username limits do.
Fail closed and log. A lockout you cannot see is a lockout you cannot tune. Send failures somewhere you will actually read them.
Add progressive delays rather than fixed lockouts where possible, since fixed lockouts create a denial-of-service vector against your own users — an attacker can lock out a known administrator deliberately.
Why DDoS is a different problem
Brute force is an authentication problem you can solve on your own server. Distributed denial of service is a capacity problem you generally cannot, and conflating them leads people to install a plugin against an attack a plugin cannot reach.
The distinction is where the work happens. A credential attack consumes a little PHP and database time per attempt. A volumetric flood saturates your bandwidth or connection capacity before your application is involved at all — and anything running inside WordPress has already lost, because PHP executing means resources consumed.
Application-layer floods sit in between: requests that look legitimate but target expensive paths such as search, uncached queries or the login page itself. These are the ones a well-configured cache and edge layer genuinely mitigate, because a cached response costs almost nothing to serve.
Push the defense to the edge
The general principle is that a request blocked before it reaches your server costs you nothing, and a request that reaches PHP costs you real capacity. Everything worth doing follows from that.
- Put a CDN or reverse proxy in front of the site so your origin address is not the target.
- Cache aggressively for anonymous visitors. A cached page absorbs a flood that would otherwise be a database problem — see our safe caching setup, which documents failure modes we hit on this site.
- Apply edge rules to authentication paths: rate limits, geographic restrictions if your administrators are in one country, and a challenge on the login route.
- Restrict administrative paths by address where your team has stable addresses. Crude and extremely effective.
- Keep core, plugins and themes updated. Most real compromises exploit a known vulnerability in an extension rather than guessing a password — covered in our WordPress security checklist.
The checklist
- Disable XML-RPC unless a dependency needs it; restrict it if it does.
- Block user enumeration via REST and author parameters.
- Multi-factor authentication on every administrator, without exception.
- Rate limit by username and by attempt count, not by request count alone.
- Cache for anonymous traffic so floods hit the cache rather than PHP.
- Front the site with an edge layer and hide the origin address.
- Audit users quarterly and delete unused plugins entirely.
Work through that and you secure WordPress against brute force attempts at the credential layer and the edge simultaneously, while keeping the denial-of-service question where it belongs — with your host and your CDN, rather than with a plugin that cannot see the traffic.
Join the discussion
Add useful context, ask a focused question or share relevant experience. Comments are moderated to protect readers from spam and promotional links.


Leave a thoughtful comment