Skip to content

Brute force attack

A brute force attack is a program trying one username and password after another until one works. On WordPress it is aimed at wp-login.php and xmlrpc.php. Failed attempts in a log are not a break-in, but enough of them can slow a site down.

By
WP Ministry
Published

In short

  • It is automated guessing at wp-login.php and xmlrpc.php. It is not special to WordPress, and it is aimed at every site with a login.
  • Failed logins are not a break-in. A login or an account you cannot explain is the thing to look for.
  • A strong, unique password and a second login step make the guessing fail. Limits and firewalls cut the load.

A brute force attack is a program trying one username and password after another until one works. WordPress's documentation calls it the simplest way to break in. It needs no flaw in the site, only a password that can be guessed, and it is not special to WordPress: anything with a login gets the same treatment.

It does harm in two ways. A guess can succeed. And because the attempts are automated and often come from many addresses at once, the ones that fail can still overwhelm a site.

Where you meet it

  • In the access log. An attack shows as POST requests to /wp-login.php or /xmlrpc.php, many of them and close together. Both files take a username and a password, which is why both are tried.
  • On the login screen, as the guesser sees it. A wrong password gets "Error: The password you entered for the username admin is incorrect." A name that does not exist gets "Error: The username nobody is not registered on this site." WordPress has no limit of its own on how many times that can happen. A limit comes from a plugin, the web server or a firewall.
  • As a 429. Where something does limit logins, it may answer the extra requests "429 Too Many Requests", the status for a client that has sent too many in a given time.

What goes wrong

  • Failed logins are taken for a break-in. A failed attempt got nowhere. What matters is a login nobody on your side made, or an administrator account you did not create. How to protect WordPress from brute force attacks says what to check and puts the defenses in order of worth.
  • The site slows down in bursts. Every guess is a request WordPress has to answer, and a plugin that limits logins still runs for each one. Stopping the requests at a firewall or the web server costs less. If the load is on admin-ajax.php and not on the login files, it is another problem: see admin-ajax.php high CPU usage.
  • Your own limit locks you out. A few wrong passwords, or an office that shares one address, and the limiter refuses you too. How to fix "429 Too Many Requests" shows how to find out which layer answered.
  • The login page is moved and the job is thought done. WordPress's guidance says obscuring the login address can reduce noise and should not be the only defense. Changing the login URL explains what it does and does not protect. xmlrpc.php stays where it is, and how to disable XML-RPC covers closing it.
  • The password is the only defense. Two-factor authentication makes a guessed password useless by itself.

How to look at yours

Ask your host for the access log, or find it in the hosting control panel. This counts the POST requests to the two files, by address and by the status each got. It reads the usual "combined" log format.

bash
awk '$6 == "\"POST" && ($7 == "/wp-login.php" || $7 == "/xmlrpc.php") { print $1, $7, $9 }' access.log | sort | uniq -c | sort -rn | head

Each line of the answer is a count, an address, the file and the status. On a site with no second login step, wp-login.php answers a wrong password with 200 and a right one with 302. Hundreds of 200s from one address are guesses that failed. A 302 from an address you do not know is worth a closer look. xmlrpc.php answers 200 either way, so its lines show the volume and nothing more.

Common questions

Do failed login attempts mean my site was hacked?

No. They mean a program tried and was refused. Signs that a guess worked are different: an administrator you did not create, or a login from an address nobody on your side uses.

Why is xmlrpc.php attacked as well as the login page?

It accepts a username and a password too, from programs instead of people. WordPress's documentation calls it a frequent brute force target.

Not sure what is wrong?

Tell us what you see. We reply with the cause and a fixed quote, and the diagnosis is free.