WordPress is an extremely popular content management system for websites. This makes it a very attractive target for hack attempts, especially as it is not particularly 'secure out of the box'.
- 1 Things to do on the server
- 2 Things to do WordPress when setting it up
- 3 Things to do in WordPress when it's set up
- 4 Things not to do in WordPress
- 5 Consider enforcing SSL for WordPress admin
Things to do on the server
- Depending on how many sites you host, you may get even more brute force attempts to crack WordPress user passwords than you do attempts to break into your server via ssh!
If you are not using IPv6, you can use Fail2Ban to help prevent them at a server level. My favourite filter to do so is..
# Fail2Ban configuration file [Definition] failregex = <HOST>.*] "POST /wp-login.php ignoreregex =
.. which catches any login attempt, successful or otherwise. Save it in /etc/fail2ban/filter.d as apache-wp-login.conf and add..
[apache-wp-login] enabled = true port = http,https action = %(action_mwl)s filter = apache-wp-login logpath = /home/*/logs/*access.log maxretry = 5
.. to /etc/fail2ban/jail.local then restart fail2ban. (Your logs may be elsewhere, in which case you need to alter the logpath line.)
Note that because it catches any login, maxretry needs to be larger than one or you will lock out everyone not from a whitelisted IP address (this may be what you want, but it can make lives harder). Having it set to five allows four goes, whether they're failures or logging into different sites, within a few minutes without being banned.
Alternative filters exist, but they need you to either install a plugin which writes logins to a log file somewhere or alter WordPress themes.
- There should never be any PHP files in the wp-content/uploads directory. So create it, if necessary, and put the following in .htaccess there:
<Files *.php> Deny from All </Files>
(People using something other than Apache may need some other way to stop anyone accessing files that shouldn't be there.) Other suggestions for .htaccess exist, but some will lock you out or block all visitors to the site.
- Have something check for changed files every so often. Look at the results. Plugins exist to do this for you, but if you have many sites, doing it on the server is easier. One particularly interesting exploit against a BitFolk-hosted site used .htaccess files to redirect users on mobiles to a porn site, and some change detection plugins won't check those.
Things to do WordPress when setting it up
- Use the WordPress.org secret-key service to generate the keys and salts - you can do this later, but changing them will log everyone out by invalidating all cookies, including yours.
- Consider using a different table_prefix rather than the default wp_ - should someone break in, it will delay them hacking the database for a few seconds. Don't attempt to do this after you have set it up, and don't let a plugin try: you risk losing content. It is a popular thing for 'security' plugins to want to do.
When accessing the initial set up web page:
- Use a username other than 'admin' for the initial user. Just doing this is not enough, but it will stop most hack attempts.
When you have logged in for the first time after that:
- Once it has been noticed, your new site defaults to being spammed to death because there are two easy to discover sample webpages which allow comments. (A quick look on Google reveals over one and a half million hits for the post's text plus 'viagra'!) So delete the sample page and post. While you're there, view the Post's trash, and permanently delete the sample post. (You may want to write another called 'Hello World' and if your permalink structure includes post names, you'd quite like it not to be called hello-world2 !)
- Then either
- Go to Settings/Discussion and unselect 'Allow people to post comments on new articles', or..
- Go to Plugins and activate Akismet. You will need to sign up for an API key - a free one is fine, but if this is something commercial with any sort of budget, pay for it.
Things to do in WordPress when it's set up
- Install a plugin to protect logins. (Yes, Fail2Ban should do this, but it is possible for plugins to rename wp-login.php, thus bypassing the filter.) Limit Login Attempts is the simplest, banning IP addresses which fail to give a correct password more than so many times (the default is four in twelve hours, with more than that leading to a 20 minute ban, rising to 12 hours if it keeps happening). It is a disgrace that this behaviour is not part of the core WordPress code.
- Better, but more complicated, is Login Security Solution which can also enforce password policies so that no-one can have '123456' as theirs... It also says it works with IPv6.
- Try to educate clients to use an account with editor rights - these can create / edit / delete any page or post - unless they really need to use an administrator one.
- Tell clients who are using an administrator account anyway not to touch the WordPress Address (URL) and Site Address (URL) settings in 'General Settings' (wp-admin/options-general.php) as they are the 'one-click' method of locking everyone out of WordPress. (This can be undone if you have access to the database.) It is a disgrace that there is no warning or error checking on these two and they are on the same page as trivia such as how you'd like dates to be formatted and what day you think the week starts.
- Also tell them not to install plugins or themes without asking you first. It won't work, but you then have an excuse to charge them more when they do and things go worng as a result.
- If you have more than a couple of WordPress sites, consider signing up for the free wpremote.com service and install its plugin on every site. You will then have a one page admin facility to update the WordPress core, themes, and plugins on all the sites as well as being able to make backups of them.
Things not to do in WordPress
- Use the default username, 'admin', for any user. WordPress really shouldn't have a default username, especially for an account with admin rights. Because it does, and will do until they finally change it in version 3.7, it's the one targeted by over 90% of hack attempts. If you have an account with that name, use another admin account to delete it. (Or make it a 'no role on site' account - the lowest privilege, even lower than subscriber - then paste in a new password from the secret-key service, and forget it - this will stop anyone else creating an account with that name.)
- Let anyone you do not trust have an account. Since its creation back in 2003, WordPress has had a user privilege escalation exploit a year. If you want to have a site where you have 'members only' content, do not use WordPress's built-in account system to do this.
- Install any theme or plugin you do not trust. Ones on wordpress.org should have been checked, but there's been one bit of code used there ('tinthumb') which had an exploit (there's a Fail2Ban jail which triggers on a single attempt to access the file). Themes on 'Free WordPress Themes!!!' sites can be incredibly dodgy: pirated, infested, or both.
- Let clients install the Better WP Security or WordFence plugins if they expect any kind of free support from you. As telling them this may not work, you can prevent it by creating two inaccessible directories where they want to install:
mkdir wp-content/plugins/better-wp-security chmod -rwx wp-content/plugins/better-wp-security mkdir wp-content/plugins/wordfence chmod -rwx wp-content/plugins/wordfence
What's so bad about them? If you do not know exactly what you are doing, they are overly paranoid and change far too much. They are particularly problematic if you set sites up for other people: almost the first thing Better WordPress Security does is exclude user #1 - you - from being able to do anything. (This can be undone if you have access to the database.) What happens in practice is that people get scared by the blurb / the Wikipedia page for WordPress into installing one - or worse, both! - then they tick all the 'oooh, you must protect against this' boxes, find themselves locked out, and only afterwards wonder why the bill to fix it all is so large. Plus at least one of the plugins wants to rename wp-login, so breaking your Fail2Ban filter.
- Let clients have admin rights. You will save yourself much hassle if they cannot install plugins or themes. Unfortunately, this is a difficult sell - even if they wouldn't know what a plugin is, people want to be able to change how their site looks. At 3am. Every week. (It would help if WordPress had a level between editor and administrator which could do this without the other admin powers.) At the very least have a policy of 'if you break it, you pay to fix it' at a suitably frighteningly high rate.
- Let clients edit theme and plugin files. Fortunately you can stop anyone (including you) doing this by including
in wp-config.php before the 'stop editing!' notice. Annoyingly, this stops the useful Quick Cache plugin from being able to change its settings.
Consider enforcing SSL for WordPress admin
All this is useless if someone sniffs an admin password over an insecure link. It is unlikely that any clients do all their web browsing over a VPN, for example. Making WordPress enforce the use of SSL for all wp-admin access is simple: add
to the wp-config.php file, before the 'That's all, stop editing!' message.
Before you do that, the necessary server setup is more complicated and is left as an exercise for the reader (otherwise known as 'someone else needs to write a guide for it'!) If you are using self-signed certificates, you will need to tell existing clients about the warnings they will get about them or they will panic.