DM Logic

Alternative thoughts on securing WordPress

Posted on in wordpress

Overview

I have to confess I was slightly nervous about installing WordPress on my nice, clean server. It’s a few years since I used it and I’ve been vaguely aware of reports of vulnerabilities coming and going during that time.

So I decided to make sure I was applying as much best-practice security as I could.

Basics

I’m not going to repeat anything from the Hardening Wordpress article in the codex. This is all good advice and you should be doing most if not all of it.

I think they miss a few tricks though…

Clean your markup

My earlier post about WordPress markup discussed how many obvious pointers are present to which version of WordPress and plugins you are using. It’s very simple to get rid of most if not all of this, especially with my Theme Wrangler PHP library.

Restrict access to your includes

Add the following line to the start of every PHP file you create for your site:

<?php if(!defined('WPINC')) exit('No direct access permitted'); ?>

That way it cannot be executed from outside of a WordPress entry point (which we will be reducing shortly).

Delete unwanted files

Do not leave unused plugins or Themes on your server. Similarly, if your Theme is not using a file, delete it. There may be no obvious vulnerabilities in these files but not leaving surplus code lying around is a good habit to get into. The next file you fail to delete could be the one an attacker is looking for. I speak from bitter experience.

The root folder of WordPress also deserves some attention here. Are you using comments? If not, you won’t be needing wp-comments-post.php. There are likely many others that can go too. Have a read through the comments at the top each file and take a view on whether you need it.

Rename the wp-content folder

This is really easy to do. Simply re-name as required and add

define ('WP_CONTENT_URL','/your-folder-name');

to your wp-config.php file and at a stroke you’ve made life many orders of magnitude harder for all the bots trawling the net for vulnerable plugins.

Securing the wp-includes folder

WordPress recommend a .htaccess rule of

RewriteRule ^wp-includes/[^/]+.php$ - [F,L]

which throws a 403 permission denied error when browsing to that folder. Fair enough but how about

RewriteRule ^wp-includes/[^/]+.php$ non-existent-file.html

This way a bot will get a 404 error back instead. Much less likely to catch the attention. I expand on this concept below.

Methods to remove index.php from URLs

If you’re very familiar with which files need direct browser access, you can try an alternative rewrite rule to remove index.php from paths.

WordPress suggests the “file and directory check” method

RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L]

Which is fine, but it explicitly allows direct access to any existing file. So how about the “include only” method:

RewriteCond $1 !^(index.php|assets|wp-admin|wp-content|wp-includes|wp-login) RewriteRule ^(.*)$ /index.php/$1 [L]

This way anything not included in the pipe separated list cannot be accessed directly. Significantly more secure.

Granted, you have to declare every single top-level folder and file that can be accessed (you may need more than I’ve added), but is that such a bad thing? This method also means bots won’t be able to establish that you use WordPress by scanning for root files such as wp-settings.php and makes my notes in “Delete unwanted files” above less of an issue.

Securing the wp-admin folder

This is the big one. We should be able to rename this folder, but can’t without considerable hassle. So what’s to be done?

From what I can see, the consensus seems to be either a second layer of password protection (painful) or to add a rewrite rule to require a secret query string. I’m going to suggest an alternative (and I think better) approach to the latter based on a similar principle.

NOTE: The technique below will only work for you if you only need to access the admin system from devices you control and on which you can edit the hosts file. If you need to edit from a non-jailbroken iPad, move along.

First adjust your apache configuration to add a server alias to a made-up domain known only to you

ServerName yourdomain.com ServerAlias made-up-domain

Make that alias as bizarre as you like.

Now add a hosts entry on your PC to the IP address of your server, for example

123.123.123.123 made-up-domain

Finally, add a new rewrite rule to .htaccess

RewriteCond %{HTTP_HOST} !^made-up-domain$ [NC] RewriteRule ^(wp-admin|wp-login) non-existent-file.html

The result of this is that anyone trying to access your wp-admin folder via your normal domain gets a 404 page. Which is exactly what you want to discourage hackers and bots. You can access the control panel via http://made-up-domain/wp-admin on any device for which you’ve set the hosts entry.

There’s one last trick you’ll need to make this work though, and that’s to have a wp-config.php file that allows multiple environments. Mine looks a little like this:

<?php $host = $_SERVER['HTTP_HOST']; $allowed_hosts = array('your-domain.com','made-up-domain'); if(!in_array($host, $allowed_hosts) ) { $host = 'your-domain.com'; } define('WP_SITEURL', 'http://' . $host); define('WP_HOME', 'http://' . $host); ?>

In summary

I don’t claim to be a security expert, just a developer who’s been around the block a few times. I’d welcome any comments pointing out flaws in the above.

I’m aware much of the above makes it harder to use Plug-ins, but I’m a firm believer in using them sparingly anyway.

I’m also aware that this article potentially makes my server a target. Please be gentle, it’s only a cheap little thing!

Comments