WordPress is a huge success story, not only in terms of global numbers, but also, in what may surprise some, in terms of big names that use the platform.
On the Internet when you have both a sizable installed user base and high profile users you simply can’t avoid becoming a target for hackers and spammers. From peddling pills, to promoting warped ideologies, to stealing data and breaking sites just because they can, getting hacked could easily be a major headache for your business.
In this article I’ll take a look over some of the tips, tricks and hacks you can employ to offer yourself more protection from the seedy underbelly of the web.
Whilst you may think some of these elements should go without saying just think about how many times you’ve seen not only clients but fellow developers, designers and agencies who should know better be guilty of some of these?
Start by making your passwords hard to guess. How can you make it hard for them but easy for you? Perhaps you can forget about dodgy letter substitutions such as ‘h3ll0’, mixing cases and throwing in punctuation and instead use a mnemonic. By chaining three or four words together to make an amusing image your password will be way easier to remember than ‘t3r%?9.Fq!G’ and orders of magnitude harder to crack. Just don’t use ‘CorrectHorseBatteryStaple’. For a full and funny explanation of this principle check out XKCD 936.
You should also be keeping your plugins and WordPress core up to date. This is now easier to do with later versions of WordPress. From WordPress 3.7 you can configure four types of automatic updates: core files, plugins, themes & translation files. A word of caution – depending on your setup you may wish to disable some of these so you can test prior to deploying updates. Though even if you leave them live and experience problems you still have daily backups to rely on, right?
Make managing multiple sites, plugins and backups easier with something like InfiniteWP. The basic features are free!
In addition to superior password strength you should also be looking at moving your default admin URL and using something other than ‘admin’ for your username. Unless the hackers have a specific target in mind they’ll usually look to run bots to automate the process. These bots look for WordPress, try the default settings and the most common passwords – so let’s move away from the defaults to make this task harder.
Perhaps the easiest way to change your login url is to take a look at plugins such as HC Custom WP-Admin URL. Of course – run a backup first!
To change your admin username the simplest way is to make a new admin user with your chosen username and delete the old one. If you’re locked out of your admin because you don’t remember your username you’re going to need a slightly more drastic solution. Log in to phpMyAdmin and load up your WordPress database. Scroll down the left hand side and look for the table ‘ks29so_users’. Find the username you wanted to change, i.e ‘admin’ and edit the user_login value to be your new name.
Before we move away from the login process there are a couple more tasks to tackle. Remember those bots that are guessing passwords? Let’s make it harder for them by saying that you can only make so many attempts within a certain time frame and that before you do you have to correctly transcribe a CAPTCHA. For Captcha you could try installing this plugin and away you go. Side benefit – the premium version integrates with BuddyPress and Contact Form 7 to secure your contact forms from spam submissions.
To limit login attempts you can either add plugins such as Limit Login Attempts or you can ask your hosting provider who may have a solution – Wpengine for example have this configured by default.
I hope you’re ready to get your hands a little dirty as we move on to suggestions a little more tricky than ‘install a plugin’! Add these suggestions after the #END WORDPRESS line.
The first element to add is going to help protect wp-config.php, this file would be dangerous in the wrong hands as it holds important information on your site and its database.
<Files wp-config.php> orderallow,deny deny from all </Files>
That’s a great start, what else can we do? Well we can block the nosy folk from having a look around your files and folders – I think the benefits of this are pretty self-explanatory!
The following is a coverall to block directory browsing:
# directory browsing Options All -Indexes
If you wanted to block one file specifically, use the following:
<Files “private.php”> Order allow,deny Deny from all </Files>
Now we’re starting to make progress – removing access from those that don’t require it. To take this to it’s logical conclusion let’s look at how we can ban someone we know is a bad actor from accessing anything at all on your server.
Once you know the IP, simply add these lines replacing 127.0.0.1 with the bad IP:
Order Deny,Allow Deny from 127.0.0.1
To update this with new IPs simply add new ‘deny from’ lines. Should you need to block an entire range just leave off the range in question. In other words, to block everything from 127.0.0.0 to 127.0.0.255 you would add:
Deny from 127.0.0.
The final tip in this section is to protect .htaccess itself. There are quite a few sites circulating methods that are good, but not great. The following method comes courtesy of Jeff Starr on Perishable Press and is a lot more thorough:
# STRONG HTACCESS PROTECTION <Files ~ "^.*\.([Hh][Tt][Aa])"> order allow,deny deny from all satisfy all </Files>
Another advantage of WordPress for hackers is that in a standard installation they will know what your database tables are called. WordPress uses the prefix ‘ks29so_’ by default, by changing this we’re again moving away from the hackers’ assumptions.
First we’ll tell wp-config.php that we’re changing the table prefix. Open up that file and edit the following:
$table_prefix = ‘ks29so_’;
Add some numbers or letters:
$table_prefix = ‘ks29so_3drt5_’;
You then need to go through and change each of the table names in your database. For each of your 11 tables run a command in the following form:
RENAME TABLE ‘ks29so_commentmeta‘ TO ‘ks29so_3drt5_commentmeta‘;
There will probably be a few other references to the old prefix you need to clear up. Run this query to list everything from the options table using the old prefix:
SELECT * FROM ` ks29so_3drt5_options` WHERE `option_name` LIKE'%ks29so_%'
Unfortunately you’ll need to go through each one and update.
Then we need to look at the UserMeta table, same process as before:
SELECT * FROM ` ks29so_3drt5_usermeta` WHERE `meta_key` LIKE'%ks29so_%'
Finally you can also restrict your MySQL database user to only having the following read and write privileges: SELECT, INSERT, UPDATE and DELETE. Thus you can revoke privileges for database structure and admin: DROP, ALTER and GRANT. However this can make updating the core and adding new plugins tricky as they may genuinely need to alter the database structure. If you go down this route you must be thorough about your backups and testing.
Your secret keys are stored in wp-config.php. However, they’re not so secret if you leave them as the default values! Improve your security by altering these – I recommend, however, that you don’t rely on your own sense of randomness and complexity. Use something like this service – this not only defines keys for you, but it does them all at once in the correct format for you to paste it directly into your file. Pressing refresh demonstrates that you get a new set of keys each time you load this up.
Plugins are a big enough attack vector when exploits are discovered and distributed amongst hackers, so you should at least ensure you trust the source of the plugin. Otherwise you may be the one to place the exploit on your own site by adding a dodgy plugin containing malware.
Because themes and plugins are a potential vulnerability, we keep them updated when we can. If you’ve stopped using a plugin/theme delete it completely. Disabling isn’t good enough – just get rid of it! If a plugin has been abandoned by its developer it would also be a good idea to find something new and delete the old one – if a security vulnerability is found it will not be patched & getting a custom fix done will likely be very expensive.
Along the same lines delete any logins you no longer need. Perhaps you trust your ex-employees, and that’s fine, but this isn’t entirely about trust. It’s also about reducing the available attack area where you can, limiting people to the minimum level of access they need. Typically an ex-employee or author needs no access – I’m sure they’ll understand!
I’ve separated this from the other .htaccess tips as this is potentially a slightly more serious step to consider. As opposed to the earlier step of banning known bad IPs, this is about allowing only known good ones. It does improve your security but at a cost to your convenience as you’ll be restricted to where you can log-in to work on your site. Go ahead with it if you won’t move around much, if you’ve been under consistent attack attempts or simply if you think it’s worth that extra peace of mind.
orderdeny,allow allow from 127.0.0.1 deny from all
(again, replace 127.0.0.1 with your IP).
You shouldn’t access your admin on a public Wi-Fi service – if you do the credentials are sent through the air in plain text. The nefarious hacker could be sat next to you, sipping a latte and secretly doing a man in the middle attack to obtain your passwords and other sensitive details.
However, if you must you can at least offer yourself a little more protection by enabling SSL. First ensure that your server supports it, then open up your wp-config.php file and add the following line:
define('FORCE_SSL_ADMIN', true);
That’s it for my main set of tips but there are other aspects to look at. You can further harden your .htaccess, for example, by stopping php scripts running where they shouldn’t be. You can also ensure your file permissions are set appropriately – not just in your WordPress files but throughout the server.
My last important tip, however, would be to back up. This whole article is based on the idea that prevention is better than cure, but regular, usable, tested backups should be there just in-case you need them. Let me emphasize both regular and tested – a backup from a year ago is essentially no backup for most sites that will have grown greatly in that time. If the backups are not tested you don’t have a backup. You seriously don’t want to get to the point where a backup is needed and just have to cross your fingers and hope it works!
What have you done to secure your WordPress website? Where do you draw the line between security and accessibility/usability? Let me know in the comments.
Very very useful post for those who worry about the security of there wordpress sites.
This is really helpful, thanks. Every WordPress website should at least have the above security fixes. Aa mentioned, the automated update feature is important to protect from new vulnerabilities occurring on daily basics. I also recommend in investing more on advanced backend hardening too.