You are working on a WordPress website, say, for a local non-profit. The site is currently under construction, so it is blocked from all search engines; up until a few days ago viewing the site required a password, but that’s since been removed. You send an email to your contact at the non-profit with a link to the development website so they can review it. The next day, you get a response: Their browser is giving them a malware warning about the website. When the malware warning is dismissed, the site redirects from the original URL to a spammy sweepstakes website.
Your carefully constructed website… was hacked.
Because of its popularity, WordPress is a target of many kinds of attacks. Some are focused on finding security flaws in the software; others try to find weaknesses in the users themselves, though things like their passwords. Getting hacked is not only annoying, it can also affect your Google search ranking because the attacks are usually attempts to turn your once beautiful website into a festering mass of spam links, or a hulking, horrifying redirect.
Unfortunately, I don’t know a recipe for keeping every bad guy out of every site I build, but I have found a few tricks over the years that have helped keep sites safer, and that have made things easier to clean up on the off-chance hackers make it in.
First, keep everything up to date. The website horror story at the beginning of this post actually happened to me this past weekend. On Friday, I noticed that WordPress 3.3.2 had been released (speaking of which, upgrade now!). I decided I would start rolling out WordPress upgrades to Stem clients the following week. By Monday morning, I had dealt with the non-profit site being hacked, as well as the WordPress websites of three friends. All were running WordPress 3.3.1, and all were compromised through security holes. (The one bright spot was that all Stem client sites were untouched, and all have since been upgraded).
These sites could have been attacked before the 3.3.2 release, but the timing of the upgrade’s release, followed by the discovery of the compromised sites, shows how quickly these issues crop up. Thankfully, the developers who work on WordPress are fixing security issues about as fast as hackers are finding them; as WordPress users, we just have to make sure to keep on top of our upgrades. The longer a version has been out, the more time there has been to find flaws — and ways to exploit them.
Along with keeping WordPress up-to-date, it’s also important to make sure you are using the latest version of your plugins and themes, as new versions of both can also include security updates.
Second, do what you can to prevent brute force attacks. A brute force attack is when access to your account is gained through exhaustive attempts. Usually with WordPress sites, this means a script written to attempt to log in using a number of password variations, ranging from the most common (password, password1… I wish I was making this up) or simply going through combinations of numbers, letters and symbols in order.
By default, WordPress allows endless login attempts, which unfortunately, allows bots to attempt to log in hundreds of times. I’ve read few recommendations on how to handle this, but the easiest I’ve worked with is the Limit Login Attempts plugin. I know we’ve written about this plugin before, but man! It’s pretty awesome.
Limit Login Attempts works by allowing you to set a number of times a user can try to log in from a specific IP address before being blocked (the default length of the block is 20 minutes, but this can be changed). You also have the option of blocking an IP for longer once it is blocked a few times — say, after being blocked three times, you can block an IP from the site for 24 hours. Lastly, the plugin can email the site administrator, whether after one lock-out or four; it also tracks the locked out IP addresses if you’d like to block them permanently.
Unfortunately, locking out one IP at a time does not stop brute force attempts — oftentimes it just means that you will get many, many emails from your site reporting when someone has attempted to log in. That being said, I’ve found that it helps slow attacks a great deal, and helps you keep your finger on the pulse of these kinds of attacks. After a few IPs have been locked out, there is usually a quick drop off of in attempts.
To make things even trickier, delete or demote the ‘admin’ user. By default, every WordPress site has a user named ‘admin’ with access to everything on the site, meaning brute force attackers only need to figure out the password. Create a new user account, giving it a unique username and the role of Administrator. Next, log in as that new user, and delete the original ‘admin’ user. I’ve also heard of switching the ‘admin’ user’s role to that of a simple (and harmless) Subscriber. I haven’t done this before, but the idea of a hacker successfully getting into a site, only to discover they can only read posts (and edit their profile!) is pretty funny.
The last thing to do against a brute force attack is to always — always — make sure you are using a strong password. Yes, they are hard to remember; yes, they are difficult to type. However, the longer and weirder a password is, the less likely a script will randomly stumble across it. There are a number of password generators online that you can use; as well as using odd characters and numbers, making your password longer — around 15 characters — also helps.
Third, backups are your friend. When the website database or files are compromised, sometimes the easiest way to restore order is to roll back to an older version. I use a simple plugin — WP-DB-Backup — that emails copies of WordPress databases either hourly, daily or weekly, depending on what’s needed. There are a number of WordPress plugins that back-up databases and files; on top of that, many web hosts offer automated back-up services. A little investigative work will help you find a backup service that meets your needs.
Unfortunately, even the best efforts may not be enough. Regardless how hard you prepare, or how careful you think you’ve been, sometimes hackers or bots will get in, and the only thing to do then is pick up the pieces.
Each attack is different, and affects different areas of your site. I’ve dealt with a few different kinds of attacks on WordPress websites, and one common element seems to be that hidden somewhere in the injected code is a snippet that re-infects all the files once they’re cleaned up. Because of this, it’s important to be thorough when removing malicious code, and not to give up.
Plugins like Exploit Scanner can help you track down bits of code that should not be there. Keep in mind that it isn’t perfect; some bits of code that appear ‘bad’ are legit parts of plugins that you may have installed. Even if you don’t have a pre-attacked version of the site to work from, I would recommend copying a version of the compromised site to your computer before deleting or making any changes, just in case.
display: none‘, you find a bunch of hidden
<div>‘s that are not part of the original template; or 3) PHP code has been added to your template files that usually starts with
eval(base64_decode("...")). This isn’t a comprehensive list, but if your site is suffering from any of these symptoms, it’s a sign you should investigate further.
The WordPress Support Forum and WordPress’s ‘My Site Was Hacked’ FAQ can be priceless resources in finding what kind of attack your site has suffered, and how to fix it; there are also many sites and blogs that have attack stories and solutions. All of these attacks are successful more than once, so you’ll never be the only one trying to figure out how to fix things.
Do you have some more WordPress security tips, or a hacking horror story of your own? Please share in the comments!
Also, don’t forget to upgrade your sites to WordPress 3.3.2!