Attacks and brute force

How to limit login attempts on WordPress: thresholds, durations and pitfalls

Limiting login attempts on WordPress

WordPress puts no limit on the number of password attempts: a bot can try as many as the server will accept. Limiting attempts is therefore one of the first protections people add to a site. Configured badly, though, it locks out your own users, or blocks nothing at all behind a CDN. Here are the settings that matter and the most common pitfalls.

The principle and its three settings

The OWASP Authentication Cheat Sheet describes three parameters:

  • the threshold: the number of failures allowed;
  • the observation window: the period during which those failures are counted;
  • the lockout duration: how long login stays refused once the threshold is reached.

Some applications use an exponential lockout: a very short duration at first, which doubles with each new lockout. It barely bothers a human who makes two mistakes, but slows a bot down considerably.

Diagram of a counting window: five failures in orange, the sixth triggers a lockout of the address
Threshold, window and duration: the three settings behind any limit.

Which numbers to pick

There is no universal official value. The available reference points:

  • NIST (SP 800-63B-4) requires verifiers to limit consecutive failed attempts on a single authenticator to no more than 100, noting that this is an upper bound and that lower limits are possible;
  • OWASP stresses the balance between protection and the risk of locking out legitimate users;
  • for comparison, WP Masquerade Pro allows 8 failures by default, then blocks the address for 15 minutes.
Type of siteThresholdLockout durationNote
Brochure site, one or two administrators5 to 8 failures in 15 minutes15 to 60 minutesFew false positives likely
Multi-author editorial site8 to 10 failures15 to 30 minutesPlan for unlocking by an administrator
Store or member area10 to 20 failures5 to 15 minutes, exponentialCustomers often forget their password
Any siteTwo-factor authentication for administratorsNot applicableMakes the threshold less critical
A reasonable starting point by type of site (adjust based on your logs)

These values are an editorial starting point, not a standard: look at how many legitimate failures show up in your logs before tightening.

Count by IP address or by account?

This is the most important choice, and each option has a weakness.

MethodWhat it stopsIts weak spot
By IP addressA bot that keeps trying from the same addressA botnet changes addresses; a shared address blocks innocent users
By account (username)Attempts spread over thousands of addresses against the same accountA stranger can deliberately lock out a legitimate user
Both, with two-factor authenticationThe vast majority of casesSlightly more complex settings
The two ways to count

OWASP recommends tying the counter to the account to counter attacks coming from many addresses, while warning about the opposite risk: letting an attacker lock out other users. It suggests, for example, keeping the "Forgot password" link working even when an account is locked.

Most WordPress plugins count by IP address. That works well against persistent bots, but as the WordPress documentation points out, these attacks often come from botnets, and therefore from a very large number of addresses. Wordfence's 2024 report mentions nearly 136 million distinct addresses behind password attacks during the year. Most general security plugins also include login limiting: our comparison of the best WordPress security plugins shows which ones.

The proxy and CDN trap

When a CDN such as Cloudflare sits in front of your site, it is no longer the visitor who connects to your server, it is the CDN. As far as PHP is concerned, the connection address (REMOTE_ADDR) is then the CDN's.

Diagram: a visitor and a bot both go through a CDN; without restoring the real address, the server sees the CDN address for everyone and a lockout hits everyone
Behind a proxy, a poorly configured limit blocks everyone or no one.

Two opposite mistakes are possible:

  • counting the CDN address: every visitor seems to come from a handful of addresses. A bot's failures then lock out your users, or the lockout is so broad that it becomes unusable;
  • trusting the X-Forwarded-For header without verification: this header is sent by the client and can be forged. A bot that sends a different address with each request escapes any counting.

The right approach is to restore the real address at the server level. Cloudflare documents this setup: the mod_remoteip module for Apache with the CF-Connecting-IP header, or the realip module for Nginx, declaring only Cloudflare's address ranges as trusted proxies. Cloudflare notes that these ranges change and must be kept up to date. Once that is done, REMOTE_ADDR contains the visitor's address and every plugin benefits.

Shared addresses

Even without a CDN, an IP address does not always map to one person.

  • Corporate networks, schools, public Wi-Fi: dozens or hundreds of people go out through the same address.
  • Mobile carriers: many use carrier-grade NAT (CGN), for which the IETF reserved a dedicated address block (RFC 6598). The same customer can change addresses and share theirs with other subscribers.
  • IPv6: a subscriber usually receives a whole block of addresses (RFC 6177 recommends assigning each site at least a /64, and often much more). Counting address by address in IPv6 lets a bot try thousands of them without ever reaching the threshold; counting by prefix makes more sense.

In practice: keep a list of trusted addresses for your offices, never block an address permanently, and provide a simple way for an administrator to unlock themselves.

False positives: what to expect

  • A user who changed their password and whose browser or mobile app keeps resending the old one.
  • An application or service that connects to XML-RPC or the REST API with an expired password.
  • A store customer who tries all of their usual passwords.
  • An administrator behind the same address as an infected machine on the network.

In each case, two-factor authentication and application passwords reduce the need for a very low threshold.

With WP Masquerade

WP Masquerade Pro includes login attempt limiting by network address: 8 failures allowed by default, adjustable from 3 to 30, with a lockout duration of 15 minutes by default, adjustable from 1 to 60. A successful login resets the counter, and the troubleshooting tab lets you unlock your own address. The plugin counts the server's connection address and never trusts an X-Forwarded-For header sent by the client: behind a CDN, the real address must therefore be restored at the server level, as described above. Two-factor authentication failures also count toward this limit. Its guide is explicit: this is neither network traffic rate limiting nor a sufficient defense on its own against a distributed attack.

Setting up login attempt limiting on WordPress with a plugin.

Key takeaways

  • WordPress does not limit login attempts out of the box.
  • Set three parameters: threshold, observation window and lockout duration; favor short or exponential lockouts.
  • Behind Cloudflare or another CDN, restore the real address at the server level and never trust X-Forwarded-For without verification.
  • An IP address can be shared by hundreds of people; in IPv6, count by prefix.
  • Limiting slows bots down; two-factor authentication protects the account.

Sources

Other sources consulted: official documentation and Wordfence database.

Attacks and brute force6 min

How to spot and stop a brute force attack on WordPress

Dictionary attacks, credential stuffing, networks of compromised machines: what really happens behind the thousands of login attempts a WordPress site receives, and the defenses that matter.

WordPress security, without the noise

One e-mail when something matters: new attacks seen in the wild, plugin updates and practical guides. No spam, unsubscribe in one click.

Start free, go Pro when you’re ready

The free version already hides WordPress and moves the login page. Pro adds aliases, two-factor authentication and monitoring.