WordPress: How to prevent brute force attacks?

2013-09-23 WordPress

Several days ago I found, that my WordPress site was under attack. From two previous days, the whole site was very slow when loading but still reachable. I thought that optimizing it by disabling unnecessary plugins, minifying CSS and JS files, creating sprites instead of multiple images will solve the problem but I was wrong.

In one moment I saw an Internal Error 503 and the whole site gone down. I checked error logs and then I saw thousands of requests into wp-login.php file, that is responsible for login into backend.

213.138.82.33 - - [14/Sep/2013:15:30:35 +0200] "POST /wp-login.php HTTP/1.0" 503 470 "slick.pl/wp-login.php" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_2_7; en-US) AppleWebKit/595.16 (KHTML, like Gecko) Chrome/10.0.567.290 Safari/567.16" 332 745 11122 D; 16 -
62.90.78.86 - - [14/Sep/2013:15:30:35 +0200] "POST /wp-login.php HTTP/1.0" 503 470 "slick.pl/wp-login.php" "Opera/9.80 (Windows NT 6.1; U; ru) Presto/2.9.155 Version/10.10" 266 745 11120 D; 16 -

(cut here)

177.5.80.95 - - [14/Sep/2013:15:30:29 +0200] "POST /wp-login.php HTTP/1.0" 200 4563 "slick.pl/wp-login.php" "Mozilla/5.0 (Windows NT 6.1; rv:19.0) Gecko/20100101 Firefox/19.0" 339 5068 11072 - 15 -
110.93.94.41 - - [14/Sep/2013:15:30:45 +0200] "POST /wp-login.php HTTP/1.0" 200 4563 "slick.pl/wp-login.php" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_1_9; en-US) AppleWebKit/563.16 (KHTML, like Gecko) Chrome/10.0.513.244 Safari/503.16" 398 5068 11214 - 14 -

I knew that it was a brute force attack. Thanks to password strength it was unsuccessful but I decided to increase the security level by doing several steps that are presented below.

Step 1 – Restore the website from Internal Error state

Brute force was in progress. Due to the ammount of requests, I was unable to reach backend. I logged into my hosting panel and quickly locked the whole domain by using .htpasswd file. In that moment, number of attacking requests dropped to 0. This step is temporary. As a final result I won’t use .htpasswd solution. It just helped me to log into Dashboard and do next steps.

Step 2 – Change names of well known and vulnerable files to unique phrases

If attacking script knows, that by default every WordPress page has got wp-login.php file placed in the same relative location, it knows where to attack. I’ve changed /wp-login.php and /wp-admin URL into some random strings. This can be done by installing Better WP Security and going into “Hide Backend” section. Check “Enable Hide Backend” checkbox and change names of login, register and admin slug for somethings that will be easy for You to remember but impossible to strangers.

Step 3a – Change the default username of admin(istrator)

It’s one of the irresponsible things to let Yourself having “admin” or “administrator” or “adm” as an username. With these most popular names, intruder can focus just on the password value. Don’t let him do that. Can be done with Better WP Security.

Step 3b – Active other great features in BWPS

Like:

  • Change the ID of username with ID = 1,
  • Block active scans,
  • Ban after several incorrect login attempts.

Step 4 – Backup

Can be solved (and automated) with awesome BackWPup plugin.

Step 5 – Disable .htpasswd

Or just set it only for Your backend slug that You have defined in Step 2.

Step 6 – Cache

It is opptional but with cache plugin You serve to Your clients static HTML files. It can help when Your site won’t be able to handle PHP requests.

Step 7 – Disallow file edit feature in Dashboard

Who edits PHP files directly in WordPress? For sure no one. Turn this off and don’t let intruder to modify Your source code so easily. Open wp-config.php and after line:

define('WP_DEBUG', false);

add:

define('DISALLOW_FILE_EDIT', true);