How to Secure WordPress Login (wp-login.php)

WordPress login security comes down to strong passwords and two-factor authentication, limiting login attempts, disabling xmlrpc.php, restricting wp-login.php by IP and getting alerted about failed logins right away. The strongest option is to close the login page to outside requests entirely. This guide walks through each step with practical examples.

Last updated: Author: Birtikta 8 min read
Contents

Why does wp-login.php get attacked so often?

Every WordPress site uses the same login address: /wp-login.php and /wp-admin/. Bots simply try passwords against it from all over the world at once: a brute force attack.

  • Usernames are easy to guess. "admin" is still the most tried name, and the author archive (/?author=1) reveals the username on many sites.
  • xmlrpc.php allows hundreds of password guesses in one request. The system.multicall method hides them from plugins that count login attempts.
  • Every attempt costs server resources. Even a failed request runs PHP and the database, so a heavy attack can take the site offline.

One weak password is enough, so WordPress login security means several layers, not one plugin.

A typical brute force attack: the WordPress login screen and hundreds of wp-login.php and xmlrpc.php requests from different IPs within minutes.

WordPress login security checklist

These ten steps fit any WordPress site, from a small blog to an agency portfolio.

  1. Give every administrator a long, unique password.
  2. Remove the "admin" username.
  3. Turn on two-factor authentication for administrator accounts.
  4. Serve the login page over HTTPS only.
  5. Limit login attempts or add a CAPTCHA.
  6. Disable xmlrpc.php if you do not use it.
  7. Restrict wp-login.php by IP or close it to outside requests.
  8. Set up instant alerts for failed login attempts.
  9. Block IP addresses that keep attacking.
  10. Keep core, plugins and themes updated, and scan the site regularly.
Comparison of WordPress login protection methods
MethodProtects againstEffortIn Birtikta
Strong password and 2FAGuessed or leaked passwordsEasy—
Login limits, CAPTCHAAutomated attemptsEasy—
Changing the login URLBot noiseMedium—
Disabling xmlrpc.phpBulk password guessingEasy✓ One click
Closing wp-login.phpAll outside login attemptsMedium✓ One click
Failed login alertsAttacks nobody noticesMedium✓ Mobile, email, Slack, WhatsApp
IP blockingPersistent attackersMedium✓ One click
"admin" and SSL checksRisky configurationEasy✓ Security scan

The basics: passwords, usernames, 2FA and HTTPS

Use a strong, unique password

Use at least 14 characters, never reuse it, and keep it in a password manager. Leaked password lists are the first thing attackers try.

Do not use "admin" as a username

Create a new administrator under Users, log in with it, and delete the old "admin" account while assigning its content to the new one. Set "Display name publicly as" to something other than the username. Birtikta Security Scan flags an "admin" user and missing SSL as risky configuration.

Two-factor authentication (2FA)

WordPress core has no 2FA. Use a plugin such as Two Factor to require a one-time code from an authenticator app on administrator accounts, and store the backup codes away from your password.

Log in over HTTPS

Without HTTPS the password travels in plain text. Once SSL is installed, force it for the dashboard in wp-config.php:

define( 'FORCE_SSL_ADMIN', true );

Birtikta Uptime Monitor warns you before the SSL expiry date.

Hide wp-login.php, limit login attempts and disable XML-RPC

Is changing the login URL enough?

Plugins like WPS Hide Login move the login page from /wp-login.php to an address you choose. That cuts bot traffic, but hiding is not locking: the address can leak, and if the plugin is deactivated the old URL returns. The official WordPress handbook also stresses that it should not be your only defense.

Limit login attempts and add a CAPTCHA

Login limiting plugins lock out an IP for a while after several failed attempts, and Cloudflare Turnstile or reCAPTCHA filter out bots. Both run in PHP, so a heavy attack still loads the server; where possible, apply limits at a WAF or CDN.

Disable xmlrpc.php

XML-RPC is a legacy remote publishing interface, largely replaced by the REST API. If you do not use it, add this to .htaccess on Apache 2.4:

# Block all outside access to xmlrpc.php (Apache 2.4)
<Files "xmlrpc.php">
    Require all denied
</Files>

On Nginx, the line location = /xmlrpc.php { deny all; } in the server block does the same.

Note: Some Jetpack features and older mobile publishing apps need xmlrpc.php. If you use one of them, test before disabling it.

Restrict wp-login.php by IP

If you always log in from a static IP, open the login page to that address only:

# Allow wp-login.php only from the listed IPs (Apache 2.4)
<Files "wp-login.php">
    Require ip 203.0.113.15
    Require ip 198.51.100.0/24
</Files>

Note: With a changing IP (home broadband, mobile data) you will lock yourself out. Behind a proxy such as Cloudflare the server sees the proxy's IP, so configure mod_remoteip first. Back up .htaccess and keep FTP or file manager access.

cPanel's "Directory Privacy" can add a second password to wp-admin; leave admin-ajax.php outside the rule.

A simpler approach: close the login page completely

All of the above still let attack requests reach the login form; they only make guessing harder. A stronger approach is to close the door entirely and enter another, secure way.

Every outside request to wp-login.php and xmlrpc.php then gets a 403. On Apache an .htaccess rule applies the block before WordPress loads, so attacks cost the server almost nothing. Logging out, session refresh and the password-protected post form keep working.

With the login page closed, wp-login.php and xmlrpc.php requests get a 403; logout and one-click login from the panel still go through.

Get failed login alerts on your phone

Most steps above are preventive; only monitoring tells you who tried to log in, and when. An early warning can reveal a bigger problem such as a leaked password. Most security plugins report failed logins by email, in batches.

A useful alert shows the username, IP address and country. Unknown usernames are mostly bot scans; a real administrator name means that account is targeted.

Block suspicious IP addresses

Blocking a persistent address at the server level keeps it off your site entirely. On Apache 2.4:

# Block specific IPs from the whole site (Apache 2.4)
<RequireAll>
    Require all granted
    Require not ip 203.0.113.24
    Require not ip 198.51.100.7
</RequireAll>

Attacks usually come from thousands of IPs, so treat IP blocking as a complement to closing the login page, not a defense on its own.

How do you log in when wp-login.php is closed?

Move login from the browser form to a panel you trust. The panel has the site create a short-lived, single-use key that is deleted once used; no password is typed or shared.

Attackers are left with no login form to try.

Monitor login security across multiple WordPress sites

Configuring a separate plugin on each of ten sites always leaves a gap. Agencies need one list of login attempts and protection status for every site.

Updates, a WAF and regular scans

However solid the login page is, a vulnerability in an outdated plugin can let an attacker in without logging in at all. Update core, plugins and themes regularly; in Birtikta you can do it in bulk for all sites. A WAF such as Cloudflare stops bad traffic before it reaches the server, and a weekly security scan catches malicious code and risky settings early. Use one security plugin; two doing the same job can conflict.

Frequently Asked Questions

No. Changing the URL cuts automated bot traffic but does not stop a targeted attack. Combine it with a strong password, two-factor authentication, disabling XML-RPC and monitoring failed logins. The most reliable method is to close the login page to outside requests entirely.

Use a login limiting plugin or WAF/CDN rules to lock out an IP address for a while after a set number of failed attempts. Birtikta takes a different route: instead of counting attempts, it closes wp-login.php and xmlrpc.php to outside requests completely.

For most sites, yes; modern tools use the REST API. Some Jetpack features and older remote publishing apps still need xmlrpc.php. If you use one of them, test before disabling it.

With Birtikta Brute Force Protection on, you open the site from the Birtikta web panel or mobile app with a single-use, short-lived key, without typing a password. While protection is on, the lost password and registration forms are closed too.

Turn on the Failed Login Attempts alarm in the Birtikta alarm system. The alert includes the username, IP address and country. Email is available on every plan; Slack, WhatsApp and mobile app notifications are on paid plans. The alarm is sent at most once per hour for the same site.

To do it by hand on an Apache 2.4 server, add a Require not ip rule to the .htaccess file. In Birtikta, press Block IP on the matching row of the WP Login Entries screen. The block stays until you remove it.

WordPress core has no two-factor authentication. Install a plugin such as Two Factor and turn on one-time codes from an authenticator app like Google Authenticator for administrator accounts. Keep the backup codes somewhere safe.

Close your WordPress login page today.

Close wp-login.php and xmlrpc.php in one click and keep an eye on failed logins from your phone.

Free Trial