WordPress Security

Securing the WordPress Login: 2FA, Rate Limits and More

How WordPress logins are actually attacked, and the controls that stop it — two-factor authentication, rate limiting, password policy and account hygiene.

By 6 min read
Shield with a tick mark over three stacked layers

The login page is the most attacked part of a WordPress site, and the attacks are relentless and entirely automated. Bots find WordPress installs, try lists of usernames and passwords, and move on. Nobody is targeting you personally; you're a row in a list.

That's good news, because unoriginal attacks are stopped by unoriginal defences. Here's what actually works, in order of effect.

How logins are actually broken into

  • Credential stuffing: the attacker has real email and password pairs from a breach elsewhere and tries them on your site. This works because people reuse passwords, and no amount of password complexity helps if the password is already known.
  • Brute force and dictionary attacks: guessing passwords against a known username, usually 'admin' or a name lifted from the site's author archives.
  • Session hijacking: stealing a logged-in cookie, typically over an insecure network or via a cross-site scripting hole in a plugin.
  • Password reset abuse: exploiting a weak reset flow or a compromised email account to take over the WordPress account.
  • XML-RPC amplification: using the multicall method to try many credential pairs in a single request, which sidesteps naive rate limiting.

Two-factor authentication

This is the one that matters most. With 2FA enabled, a correct password alone is not enough — which means a credential-stuffing hit, a keylogger or a shoulder-surfed password all fail at the second step.

Use a time-based one-time password from an authenticator app, or a hardware security key. Avoid SMS where you can: SIM swapping is a real and well-documented attack, and in India it has been used successfully against high-value targets.

Enforce it for every administrator and editor account, not just your own. One unprotected admin account undoes the control for the whole site. And make sure recovery codes are generated and stored somewhere the person can actually reach when their phone is lost.

Rate limiting and lockouts

Limiting failed login attempts turns a brute-force attack from a matter of hours into a matter of years. Most security plugins do this; so do some hosts at the edge, which is better because the request never reaches PHP.

  • Limit by IP address, with an escalating lockout rather than a fixed one.
  • Don't lock out by username alone, or an attacker can lock your administrators out deliberately as a denial of service.
  • Add a CAPTCHA or proof-of-work challenge after a few failures rather than on every login, so normal use isn't punished.
  • Make sure the limiter also covers XML-RPC and the REST API, not just wp-login.php. Attackers moved to those endpoints precisely because they were unprotected.
  • Watch out for sites behind a proxy or CDN where every request appears to come from one IP — the limiter needs the real client address or it will lock everyone out at once.

Passwords, realistically

Length beats complexity. A long passphrase from a password manager is stronger and more usable than a short string of symbols that someone will write on a sticky note or reuse.

What actually matters is uniqueness. A password used nowhere else can't arrive through someone else's breach. That means a password manager, per person, for every account — including the hosting panel and the domain registrar, which are the keys to everything else.

Forcing frequent rotation is counterproductive and no longer recommended by any serious guidance. It pushes people towards predictable variations. Rotate when there's reason to think a password is exposed, not on a calendar.

Account hygiene

  • No account named admin, and no account whose username can be read from an author archive or the REST users endpoint.
  • One account per person. Shared logins make it impossible to attribute an action or revoke access cleanly.
  • Lowest role that does the job. Most people who have Administrator only need Editor.
  • Remove accounts when people leave — including the developer's, once handover is complete.
  • Audit the user list quarterly. Unexpected administrator accounts are one of the clearest signs of a compromise.

Sessions and cookies

WordPress sessions are long-lived by default, and 'remember me' extends them substantially. On a shared or public machine, that's a meaningful window.

Shorten the session length on sites that warrant it, and make sure the whole site is HTTPS so session cookies are never sent in the clear. If you suspect a compromise, rotating the authentication salts in wp-config.php invalidates every session immediately and forces everyone to log in again — a much faster response than changing passwords one at a time.

XML-RPC and the REST API

XML-RPC's system.multicall lets a single HTTP request attempt many credential pairs, which is why attackers favour it. If nothing on your site needs XML-RPC — and most sites don't — disable it. If something does, restrict it to the specific methods needed.

The REST API's users endpoint publishes account slugs by default, which is a ready-made username list. On a site with no public need for user data, restrict it. Neither of these is a substitute for 2FA; they just remove the easy starting points.

What about hiding the login page?

Moving wp-login.php to a custom URL is popular, and it does reduce the volume of automated traffic hitting your login — which makes your logs readable and saves a little server load.

It is not a security control. The URL is discoverable in several ways, and anyone actually targeting your site will find it. The automated traffic it deflects would have been stopped by rate limiting and 2FA anyway. Do it if the log noise bothers you; don't count it as protection, and definitely don't do it instead of the things above.

Monitoring

  • Alert on successful logins from new locations or devices, not just failures.
  • Alert on new administrator accounts and on role changes. These are high-signal events.
  • Keep an audit log of what admin users do, so a compromise can be reconstructed rather than guessed at.
  • Watch for logins at implausible hours for your team.
  • Review the log occasionally when nothing is wrong, so you know what normal looks like.

A practical order of work

If you do three things: turn on 2FA for every administrator, add rate limiting that covers wp-login.php, XML-RPC and the REST API, and move every account to a unique password from a manager. That covers the overwhelming majority of real attacks.

Then tidy up the account list, restrict the users endpoint, and set up alerting on new admin accounts. Everything else on this page is refinement.

Frequently asked questions

Is two-factor authentication worth it on a small WordPress site?

Yes, and site size is irrelevant — the attacks are automated and don't care who you are. 2FA makes a leaked or guessed password useless on its own, which is the difference between a failed login attempt and a compromised site. Enable it for every administrator, plus your hosting panel and domain registrar.

Should I change my WordPress login URL?

It reduces log noise and a little server load, and that's a reasonable thing to want. It isn't security: the URL is discoverable, and the automated traffic it deflects would have been stopped by rate limiting and 2FA anyway. Do it as housekeeping, never instead of the real controls.

How do I stop brute force attacks on WordPress?

Limit failed attempts per IP with an escalating lockout, and make sure the limiter covers XML-RPC and the REST API as well as wp-login.php — attackers moved to those because they were unprotected. Rate limiting at the host or CDN is better than a plugin, because the request never reaches PHP.

Should I disable XML-RPC?

If nothing uses it, yes. Its multicall method lets an attacker try many credential pairs in one request, which defeats naive rate limiting. Check first whether anything depends on it — some mobile apps and older integrations do — and restrict it to the required methods rather than disabling it if so.

How often should WordPress passwords be changed?

Only when there's a reason: a suspected compromise, a shared password, or someone leaving. Scheduled rotation is no longer recommended by serious security guidance because it pushes people towards predictable variations. Uniqueness matters far more than freshness — one password per account, from a manager.

Topics

  • WordPress login security
  • WordPress 2FA
  • WordPress brute force
  • wp-admin security