WordPress Login Protection – Brute Force, 2FA, Passkeys, and XML-RPC

Published: May 20, 2026 · Author: Marcin Szewczyk-Wilgan

The WordPress login page is the most attacked endpoint on the internet. Every site running WordPress receives automated login attempts within hours of going live – not because anyone is targeting you specifically, but because bots scan the entire internet continuously. Brute-force attacks on wp-login.php increased by 45% in 2025, driven by AI-assisted botnets that can bypass traditional CAPTCHA and mimic human login patterns. This article covers the complete defence: from limiting login attempts and blocking XML-RPC through two-factor authentication to passkeys, the passwordless future that is becoming practical today.

The Threat Landscape

Understanding what you are actually defending against makes it easier to prioritize measures correctly.

Credential stuffingAttackers use lists of username/password combinations leaked from other breached services. They try these combinations against WordPress logins at scale. If any of your users reuse passwords from other accounts, this is the most likely way a legitimate credential gets compromised.
Dictionary attacksAutomated testing of common passwords against known or guessed usernames. WordPress helpfully tells you when a username exists but the password is wrong – which means discovering valid usernames is trivial. Common usernames (admin, administrator, the site's domain name) are always tested first.
XML-RPC amplificationXML-RPC's system.multicall method allows testing hundreds of username/password combinations in a single HTTP request. This makes XML-RPC brute-force attacks far more efficient than direct wp-login.php attacks, and rate limiting by request count does not help because each request tests many credentials.
REST API auth endpointsThe WordPress REST API /wp-json/wp/v2/users endpoint exposes author usernames by default. This is not a login vector itself but leaks valid usernames that feed credential attacks. Disable user enumeration via the REST API if your site does not require it for public consumption.

Limiting Login Attempts

WordPress has no built-in login attempt limiting. Without it, an attacker can make unlimited requests to wp-login.php. Fixing this is the most basic and highest-priority hardening step.

Plugin approach

Login Lockdown / Limit Login Attempts Reloaded

Plugins like Limit Login Attempts Reloaded or WP Cerber implement lockouts at the application level. After a configurable number of failed attempts from an IP, further attempts are blocked for a period. Application-level limiting is better than nothing but still consumes PHP and database resources for each blocked request.

Web server level

Nginx rate limiting

Rate limiting at the Nginx level with limit_req_zone is more efficient: requests are blocked before PHP executes. A configuration limiting wp-login.php to 5 requests per minute per IP effectively stops automated attacks without impacting legitimate users who log in once and stay logged in.

Fail2Ban

Firewall-level blocking

Fail2Ban watches your web server logs and adds IP addresses to firewall block rules (iptables/nftables) after repeated failures. Unlike application or web server limits, Fail2Ban-blocked IPs are dropped at the network level – they do not consume any web server resources. Requires server access to configure.

IP allowlisting

For admin-only access

If all your admin users access the site from known, static IP addresses (office network, VPN), restricting wp-admin and wp-login.php to those IPs at the web server level is the most effective possible protection. An attacker without an allowlisted IP cannot even reach the login form.

Two-Factor Authentication (2FA)

Even with login attempt limiting in place, a correct username/password combination will succeed. Two-factor authentication ensures that a stolen password alone is not sufficient to access the account.

TOTP authenticator appsTime-based One-Time Passwords (TOTP) from apps like Google Authenticator, Authy, or 1Password are the most practical 2FA method for WordPress. After entering the correct password, the user is asked for a 6-digit code that changes every 30 seconds. Even if the password is compromised, the attacker also needs physical access to the user's phone.
Implementation pluginsWP 2FA, Two Factor Authentication (David Anderson), and Wordfence Login Security all provide TOTP 2FA for WordPress. WP 2FA has the best user onboarding flow for non-technical users. For multisite networks, enforce 2FA for all users network-wide from the network admin.
Enforcing 2FAOffering 2FA is good. Requiring it for administrator and editor roles is better. Most 2FA plugins support mandatory enrollment with a grace period: users must set up 2FA within X days or their access is suspended. This is the right policy for any site with multiple editors or contributors.
Backup codesAlways generate and securely store backup codes when setting up 2FA. If the authenticator device is lost, backup codes are the recovery path. Without them, an admin locked out of 2FA must recover via direct database access to disable the requirement.
Email 2FASome plugins offer email-based 2FA: a code is sent to the user's email address at login. This is better than no 2FA but weaker than TOTP – it is only as secure as the email account. For any site handling sensitive data, TOTP or passkeys are strongly preferred.

Passkeys – Passwordless Authentication

Passkeys represent the next step beyond 2FA. Defined by the FIDO2/WebAuthn standard, they replace passwords entirely with cryptographic key pairs. The private key never leaves the user's device; the server only stores the public key. Authentication happens via device biometrics or PIN.

How they work

Public-key cryptography at login

When a user registers a passkey, the browser generates a key pair. The public key is stored on the WordPress site; the private key is stored in the device's secure enclave (TPM on Windows, Secure Enclave on iPhone/Mac). Login consists of the server sending a challenge that the device signs with the private key, proven by biometric or PIN verification.

Phishing resistance

Why passkeys are fundamentally different

Passkeys are bound to the exact domain they were registered on. A phishing site on a lookalike domain cannot receive a valid passkey authentication even if the user is deceived into visiting it. This is the core security advantage over passwords and SMS/email 2FA, which phishing attacks can intercept.

WordPress support

WebAuthn plugins in 2026

Plugins like WP Passkeys and Passwordless Login by Authsignal implement WebAuthn for WordPress. Browser support is now universal: Chrome, Firefox, Safari, and Edge all support passkeys on both desktop and mobile. The WordPress.org team has passkeys on the roadmap but no core implementation exists as of mid-2026.

Adoption strategy

Gradual rollout

For existing sites, the practical approach is to offer passkeys as an option alongside passwords for users who want to adopt them, while enforcing 2FA as a mandatory fallback. Full passwordless enforcement requires all users to have compatible devices – which in 2026 is true for most, but not all audiences.

Blocking XML-RPC

XML-RPC is a legacy API endpoint (xmlrpc.php) that predates the WordPress REST API. For most sites today, it serves no legitimate purpose but represents a significant attack surface. Blocking it is a simple, high-impact security measure.

Block at web server levelThe most effective approach. In Nginx, add location = /xmlrpc.php { deny all; }. In Apache, use <Files xmlrpc.php> deny from all </Files>. This stops requests before PHP executes. Server-level blocking is more efficient than plugin-based blocking, which still loads WordPress for every request.
Block via pluginIf you do not have server access, plugins like Disable XML-RPC or security suites like Wordfence block XML-RPC at the application level. Add add_filter('xmlrpc_enabled', '__return_false'); to wp-config.php or a must-use plugin for a code-only solution.
When NOT to blockBlock XML-RPC unless you specifically use: the Jetpack plugin (it requires XML-RPC; Automattic provides a bypass), the official WordPress mobile app on older versions, or a third-party service documented to require it. REST API-based integrations do not need XML-RPC.
Verify the blockAfter blocking, verify with curl -s -o /dev/null -w "%{http_code}" https://yoursite.com/xmlrpc.php. You should see 403 or 404. A 200 with an XML body means XML-RPC is still accessible.

Additional Hardening Measures

Beyond the core measures above, these additional steps reduce the login attack surface further:

Remove login error specificityBy default, WordPress tells visitors whether a login failure was due to an invalid username or an incorrect password. This helps attackers enumerate valid usernames. Add add_filter('login_errors', function(){ return 'Incorrect credentials.'; }); to return a generic message for any failure.
Disable author enumerationURLs like /?author=1 redirect to a URL containing the username. Block this in Nginx or via plugin to prevent username harvesting. Also restrict the /wp-json/wp/v2/users REST API endpoint if it is not needed publicly.
Rename the admin userAny WordPress installation using the default “admin” username has already solved half the attacker's problem. Create a new admin account with a non-obvious username, assign all content to it, delete the “admin” account.
Strong passwords with a managerAll WordPress accounts should use unique, randomly generated passwords of at least 20 characters. A password manager (Bitwarden, 1Password, Dashlane) makes this practical. Never reuse passwords between WordPress and any other service.
CAPTCHA on the login formreCAPTCHA v3 or hCaptcha add a layer against automated attacks without requiring user interaction. They are not a substitute for rate limiting (bots can solve CAPTCHAs at scale) but add friction. Cloudflare Turnstile is a privacy-respecting alternative that works well for this use case.

Summary

A well-protected WordPress login combines multiple layers: rate limiting at the web server level to stop brute-force volume, Fail2Ban to block persistent attackers at the network level, two-factor authentication so stolen passwords are not sufficient, and XML-RPC blocking to close the most-abused legacy attack surface. Passkeys are worth implementing for technical users today and will become the primary recommendation within the next 1–2 years as adoption reaches all user segments. No single measure is sufficient; the combination is what makes the login page genuinely hard to breach.

Need Help with WordPress?

If you have questions after reading the articles or need support – we are at your disposal. No commitments, no marketing jargon – a concrete proposal after a brief conversation.

Phone

+48 608 271 665

Mon–Fri, 8:00–16:00 CET

E-mail

contact@weboptimo.pl

We respond within 24h

Company

WebOptimo

VAT ID: PL6391758393