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.
Quick definition: Brute-force attack. Ready-made solution: WordPress brute force protection with WP Masquerade.
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.

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 site | Threshold | Lockout duration | Note |
|---|---|---|---|
| Brochure site, one or two administrators | 5 to 8 failures in 15 minutes | 15 to 60 minutes | Few false positives likely |
| Multi-author editorial site | 8 to 10 failures | 15 to 30 minutes | Plan for unlocking by an administrator |
| Store or member area | 10 to 20 failures | 5 to 15 minutes, exponential | Customers often forget their password |
| Any site | Two-factor authentication for administrators | Not applicable | Makes the threshold less critical |
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.
| Method | What it stops | Its weak spot |
|---|---|---|
| By IP address | A bot that keeps trying from the same address | A botnet changes addresses; a shared address blocks innocent users |
| By account (username) | Attempts spread over thousands of addresses against the same account | A stranger can deliberately lock out a legitimate user |
| Both, with two-factor authentication | The vast majority of cases | Slightly more complex settings |
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.

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-Forheader 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.
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-Forwithout 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
- OWASP: Authentication Cheat Sheet (Account Lockout) (opens in a new tab)
- NIST SP 800-63B-4: Authentication and Authenticator Management (rate limiting) (opens in a new tab)
- WordPress Developer Resources: Brute Force Attacks (opens in a new tab)
- Cloudflare: Restoring original visitor IPs (opens in a new tab)
Other sources consulted: official documentation and Wordfence database.


