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.
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./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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.add_filter('xmlrpc_enabled', '__return_false'); to wp-config.php or a must-use plugin for a code-only solution.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:
add_filter('login_errors', function(){ return 'Incorrect credentials.'; }); to return a generic message for any failure./?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.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.


