Due to its flexibility, ease of use, and massive plugin ecosystem, WordPress is a favorite among bloggers, developers, and businesses alike. Given its popularity, attackers do not waste time guessing where sensitive assets live. By default, on every WordPress site the front door is conveniently labeled /wp‐login.php or /wp‐admin/. On even a modest site, server logs can often reveal hundreds of failed logins coming from residential proxies and botnets that rotate addresses. Once a single credential is cracked an attacker could install a malicious plugin, add a backdoor, inject SEO spam, or turn the site into a drive-by malware host, damaging reputation, search rankings, and revenue in one hit.
WordPress ships with essential security features right out of the box. Still, those built-in defenses often aren’t sufficient to stop persistent attackers. The default login page can be exposed to several threats, including:
For stronger protection, you’ll need to move past the defaults and add extra security layers.
Below we’ll go over how attackers target the login page, then walk through some configurations that help close the most common gaps like strong credentials, two-factor authentication, rate limiting, and real-time monitoring.
Credential stuffing campaigns rely on the fact that users reuse passwords across services. Phishing kits and info-stealers dump millions of credentials daily. Attackers feed those lists into scripts that target /wp-login.php looking for credential matches.
Run the following on Linux to identify hard-coded passwords:
sudo grep -Eai 'pass(word)?\s*=\s*["'\''][^"'\'']{0,11}' -R /var/www/htmlIf anything shows up, change it immediately and replace the hard-coded password in the source file/config with an environment variable or pull from a secrets manager.
Commodity scanners are designed to check the default login paths, so use a non‑default path to reduce exposure to scanners that only look for defaults. It doesn’t stop a targeted attacker, but it filters out a massive wave of commoditized scanners.
/wp-login.php and /wp-admin/ and set the rule to Block or CAPTCHA./private-console/ and allow it from the public internet.
/secure-gateway/).location /wp-login.php { return 404; } location /secure-gateway { include fastcgi_params; fastcgi_pass unix:/run/php/php8.2-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root/wp-login.php; }
Request /wp-login.php in a private browser window. A 404 or 403 response means the default path is hidden. Check that /secure-gateway loads the expected login form.
Readily available brute force tools can cycle through password guesses in rapid succession, especially when the site replies quickly.
The Sucuri Website Firewall automatically profiles failed logins and blocks IPs or entire ASNs that cross the threshold of failed attempts. Sucuri firewall users can review further hardening options and which directories or files they apply to under Security > Hardening.

On Ubuntu:
sudo apt install fail2ban cat << 'EOF' | sudo tee /etc/fail2ban/filter.d/wp-login.conf [Definition] failregex = <HOST> .* "POST /wp-login.php EOF cat << 'EOF' | sudo tee /etc/fail2ban/jail.d/wp-login.local [wp-login] enabled = true port = http,https filter = wp-login logpath = /var/log/nginx/access.log findtime = 600 maxretry = 3 bantime = 86400 EOF sudo systemctl restart fail2ban
Intentionally fail four logins and confirm the IP is blocked at the firewall or server level.
Phishing and malware steal passwords every day. Without a second verification factor, those credentials are enough.
/secure-gateway/ or /wp-login.php.
Log in, skip the 2FA step, and confirm access is denied. Use Google Authenticator or Microsoft Authenticator to approve a token and confirm success.
Credential stuffing often originates from headless browsers or CURL. CAPTCHA blocks those automated runs with minimal friction to humans.

After you save the path, it’s added to your protected pages and will be secured from automated attacks by the Sucuri Firewall.
Use CURL to POST credentials. The response should return the CAPTCHA form rather than authenticating.
If an attacker reaches the dashboard or gains file write access they can inject backdoors through the theme editor or plugin installers. Disabling those features forces attackers to find a server-side write primitive, raising the bar.
Add the following lines above /* That's all, stop editing! */
define('DISALLOW_FILE_EDIT', true); define('DISALLOW_FILE_MODS', true);
Move wp-config.php one directory above the web root if your hosting provider allows:
/home/user/wp-config.php /home/user/public_html/index.php
Set strict file permissions:
chmod 400 /home/user/wp-config.php chown www-data:root /home/user/wp-config.php
DISALLOW_FILE_MODS when a legitimate update from the dashboard is needed.Many automated tools run the enumeration scan /?author=1 which returns a redirect to /author/username/. That leak hands the attacker half the login puzzle.
Add the following to your .htaccess:
RewriteCond %{QUERY_STRING} author=\d RewriteRule ^ /? [L,R=301]
Or configure the Sucuri firewall to block requests matching “author=” in the query string.
Visit /?author=1. Expect an instant redirect to the home page or a 403. Blog posts should show the nickname but not the actual login name.
Old contractors, ex-employees, test accounts, or compromised email addresses provide attackers with a foothold. Least privilege is a core security principle that unused accounts violate.
wp user list --field=ID --role=author --field=user_registered | while read id; do last_login=$(wp user meta get $id last_login) if [ $(date -d "$last_login" +%s) -lt $(date -d '90 days ago' +%s) ]; then wp user delete $id --reassign=1 --yes fi done
Run penetration testing scripts to verify no default usernames like admin, test, or demo are present.
Serious vulnerabilities in plugins and themes are disclosed on a recurring basis. Keeping unused or outdated components installed increases risk even if they’re deactivated, as they can be executed directly via file inclusion.
Again, deactivating does not neutralize risk. Remove entirely unless needed for staging.
wp plugin delete $(wp plugin list --status=inactive --field=name) wp theme delete $(wp theme list --status=inactive --field=name)
Lock wp-content/plugins/ to root:root and deny write via chmod 550 when no new installs are planned.
Scan the site with our SiteCheck remote scanner to verify no references to deleted plugins.
Some vulnerabilities see broad exploitation soon after disclosure, but prompt patching shortens the time your site remains exposed. Apply fixes immediately and consider a web application firewall to reduce risk while you update.
WP_AUTO_UPDATE_CORE to minor.0 */4 * * * cd /var/www/html && wp plugin update --all --quiet >> /var/log/wp-updates.logThis cron job will auto-update all WordPress plugins every 4 hours and log the results.
The Sucuri Website Firewall blocks known exploit signatures even when the vulnerable code still exists. This buys the admin time to test updates in staging.
wp core verify-checksums to ensure files are pristine.Place an additional password at the web server layer, effectively requiring credentials before PHP executes. Example for Nginx:
auth_basic "Restricted"; auth_basic_user_file /etc/nginx/.htpasswd; location /secure-gateway { # existing fastcgi config }
Restrict wp-admin to a fixed office VPN range.
allow 203.0.113.15; deny all;
Reduce the impact of XSS by limiting where scripts can load.
add_header Content-Security-Policy "default-src 'self'; frame-ancestors 'none';" always;Attackers leverage xmlrpc.php for brute force multicall methods.
# Block xmlrpc.php requests
<Files xmlrpc.php>
order deny,allow
deny from all
allow from ALLOWED.IP.GOES.HERE
</Files>Replace the ALLOWED.IP.GOES.HERE with the IP address you want to allow. If you want to disable XML-RPC requests entirely, you can remove this line.
As touched on earlier, hand out permissions sparingly. Each account should get only the rights it needs to complete its tasks. No more, no less. If that account gets hijacked, the fallout stays contained.
WordPress offers these built-in roles:
Assign roles with care, and create custom roles with tailored permissions whenever the defaults don’t fit.
If applying updates and patches right away is a challenge, a web application firewall can fill the gap. By adding virtual patches for known weaknesses, a WAF helps block familiar threats such as cross-site scripting and SQL injection.
Locking down the WordPress login page is not a one-time project. Attack techniques evolve, infrastructure changes, and human habits shift. Effective defense therefore relies on continuous reinforcement.
If you need help hardening authentication or cleaning up after an intrusion, the Sucuri team is on call. Implement the steps above, validate them regularly, and keep the WordPress login page a silent guard rather than the weakest link in your security chain.