Hardening WordPress – Password Protected Directory causing 404 errors

Print Friendly, PDF & Email

Securing WordPress Guide

WordPress SecuritySecuring your WordPress blog is quite important, especially once you start to get any attention – the hackers and script kiddies won’t be far behind! It’s not hard to take a number of steps to make life much harder for people who want to spoil your blog.

I’m going to document “timeless” techniques first, then look at some plugins. There are dozens of plugins for securing WordPress that can help with security, but plugins come and go (apart from a few), so I’m sticking to solid security measures.

Because there are always bug fixes, and new security exploits being patched, I won’t insult your intelligence by stating that you should keep your copy of WordPress up to date on your server  – oops, I just did!

Seriously, though, installing WordPress is the easy bit – you must keep it current to be secure. I could show you excerpts from our application firewall logs, and your toes would curl if you were aware of how many times your blog gets probed for various weaknesses and exploits.

Backup your wordpress database!

Almost as “no-brainer” as using strong passwords… if it all goes pear shaped, you will thank me for reminding you to take a full backup of your hosting account from time to time (more often the better). The backup should include all files and databases – Again, this is normally provided through your hosting account control panel interface. No matter how secure your think your site is, you can still fall prey to Zero Day attacks.

Use a strong password

It’s almost too obvious, but always use a strong password that is difficult to guess! If you have trouble remembering passwords, then install something like 1password (Mac) or KeyPass (Windows) Use digits, special characters and upper/lower case characters. Later versions of WordPress will provide a password strength gauge as you type in your new password.

Change your login username

The default username is admin – not very imaginative. It’s the easiest thing to change, and here’s how:

In WordPress Dashboard, go to Users and set up a new user account. Give this new user administrator role. Log out and log in again with the new user account. Go back to Users, and then you will see the option to delete admin. You will be asked what to do with admin’s posts, select the option to “Attribute all posts and links to” your new username – BE CAREFUL not to accidentally delete all your posts!. This will transfer all the posts to your new user account.

Don’t post anything with your administrator login

It’s easier to login with an administrator account. We all do it. However, it’s easy for people to to see your login username, even if you change your display name. Author links usually show up in themes as your username. This is bad. You can either strip Author links out of your theme, or take another approach.

Set up a dummy user with only contribute rights, or even just as a subscriber. Then, whenever you create a new post on your blog, you just assign it to the dummy user. That way, if someone does manage to gain the login details for the the Author’s account, they actually end up with very few rights at all in return for their hard work.

Finally, you can create a new admin account with a more cryptic name, and then delete your old admin account, REMEMBERING to re-assign all posts to your dummy login beforehand!

Delete your install.php file

This file is in your /wp-admin directory. You don’t need it once you have completed your installation. It was previously the subject of a security exploit. Just remove it, and keep a local copy if you really want to!

Hide your plugins folder

If you have disabled directory indexing on Apache (Highly recommended) then you don’t have to worry about this. If not, then make sure you put a blank index.html file in http://yourwebsite.com/wp-content/plugins. This prevents people from quickly seeing which plugins you have installed.

Password Protect your wp-admin directory with apache http auth password security

Your wp-admin directory contains the files used to administer your blog. Now, you could argue that unless the hacker knows your password that he will never get in anyway, so why place another layer of security on top? Whether or not the hacker has managed to find the username and password for your blog, he/she can still probe any files in wp-admin, and attempt all kinds of exotic exploits. Using apache to secure the wp-admin directory adds another layer of protection, as the hacker won’t even be able to see the contents of wp-admin without first authenticating with apache.

It is quite easy to secure wp-admin, especially if you have Cpanel, DirectAdmin or some other control panel system to administer your hosting account. Our sister company has a video you can watch on securing a directory with a password using Cpanel.

Why does HTTP basic authentication with apache result in 404 error pages when I try to login to my blog?

If your blog is installed in your root directory, then you may get problems with 404 errors everytime you try to login to WordPress. This is because the .htaccess file that WordPress uses, redirects everything plus the kitchen sink back to WordPress’ index.php page.

What goes wrong is this:

HTTP Basic Auth first sends a 401 Unauthorized with it’s request for a password from the browser.

The webserver tries to serve the corresponding, Errordocument, usually 401.shtml.

However, because most people don’t think to configure a 401.shtml file, the mod_rewrite pattern in .htaccess ends up sending the request for the 401 document back to WordPress’ index.php file – and Voila! WordPress keeps giving you the 404 error you love and adore.

The quick fix:

Just make sure there is a couple of files in your root directory (public_html/) to handle Forbidden (403) and Unauthorised (401) errors – for example:

401.shtml
403.shtml

You can put a little message in each file to make anyone getting the errors to know what is going on or leave them blank.

Then, just add the following lines to the end of your .htaccess file (assuming you have RewriteBase / in there already – which WordPress normally puts in there anyway):

ErrorDocument 401 /401.shtml
ErrorDocument 403 /403.shtml

This should make your 404 problems go away!

Move your wp-config.php file out of your virtual web root

WordPress 2.9 upwards should support you moving your wp-config.php to one directory level above it’s normal installation path. For example, when you FTP into your account, if your website files exist within

/public_html/

then you can move your wp-config.php file to

/wp-config.php

and WordPress will still be able to find it. This only works if you have installed WordPress into your website’s root directory. The advantage of doing this is that your wp-config.php file is no longer directly accessible via a web browser. If your wordpress installation is installed into a subdirectory, then this isn’t going to work. Instead you can just create a new config.php file containing just the security sensitive code (I keep the following stuff in it) :

<?php
define('DB_NAME', 'yourdb_name');
define('DB_USER', 'yourdb_user');
define('DB_PASSWORD', 'yourpassword');
define('DB_HOST', 'localhost');
define('AUTH_KEY', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx');
define('SECURE_AUTH_KEY', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx');
define('LOGGED_IN_KEY', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx');
define('NONCE_KEY', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx');
$table_prefix  = 'wp_'
?>

Then, just cut those items out of your wp-config.php file, and in their place put an include statement, so your wp-config.php ends up something like this:

<?php
include('/home/user/config.php'); // use absolute path to reference the file as it is outside the virtual root
/**
 * WordPress Localized Language, defaults to English.
 *
 * Change this to localize WordPress.  A corresponding MO file for the chosen
 * language must be installed to wp-content/languages. For example, install
 * de.mo to wp-content/languages and set WPLANG to 'de' to enable German
 * language support.
 */
define ('WPLANG', '');
/* That's all, stop editing! Happy blogging. */
/** Absolute path to the WordPress directory. */
if ( !defined('ABSPATH') )
	define('ABSPATH', dirname(__FILE__) . '/');
 
/** Sets up WordPress vars and included files. */
require_once(ABSPATH . 'wp-settings.php');

Stopping brute force attack

Hackers can try cracking your login username and password using brute force. If you run your own server, then if you install and run something like APF/BFD from R-fx Networks or ConfigServer Security & Firewall then you can monitor for failed apache http auth attempts, and automatically lock out IP addresses that try it on…

Or, if you have a good hosting provider, they should be able to set this up for you.

There are plugins that do this at the WordPress level as well, such as the Login Lockdown plugin.

Remove WordPress version info

The easiest and most persistent way to do this is via a plugin. Secure WordPress offers a collection of simple security measures (some of which are already covered above), including the facility to hide version information, and error messages (which can give away valuable information to hackers).

To infinity… and beyond!

I’ve tried to provide a good guide to securing your WordPress installation – there are hundreds of security related plugins, but most of them overlap and provide similar functionality – but if you find any that are particularly great, please comment! This is by no means an exhaustive guide, and certainly doesn’t cover every little tweak I’ve done to this site, but it provides a reasonable starting point for running a more robust and secure WordPress installation.

Good luck, and happy blogging!

Tags: , ,

2 Responses to “Hardening WordPress – Password Protected Directory causing 404 errors”

  1. UncleFester May 30, 2010 at 10:17 pm #

    Thanks for the post. Already knew some of the stuff, but the 404 error thing was really helpful. Nice blog.

  2. leeHoMax May 29, 2010 at 2:17 am #

    Yes you made a very good writing. You blog is safe for now as mine also is thanks for you! Best wishes

Leave a Reply

Bot test * Time limit is exhausted. Please reload the CAPTCHA.