WordPress is an incredibly popular PHP/MySQL CMS system. According to the 2011 Open Source Market Share Report, it is the number one most installed CMS and also ranks number one in downloads. However, popularity combined with open source means that WordPress is a prime target to be hacked. This article will detail some basic and broad steps you can take to recover a hacked site and get it back to (hopefully) an unhacked state. It will also discuss what you can do to prevent your site from being hacked in the first place.
How Do I Know If My Site Is Hacked?
Not all hacks are readily visible and not all site owners check their sites on a regular basis. The most obvious sign of a hack is defaced or injected content on your posts and pages but there can be a number of other signs. Be on the lookout for any of the following:
If your traffic drops suddenly, it may be due to Google or other malware blacklists reporting your site as infected.
You may get emails from your users asking (or blaming) you why your site is attempting to download malware.
Your site may begin running very slowly
If your email is tied to your web hosting (common in shared hosting), you may see your legitamite email being rejected as spam or receive notification that your IP address is on a public blacklist
These are all passive signs of a site that may be hacked but there are also other issues that could cause all of the above. So it is important to know if your site is indeed compromised and to do that we turn to plugins and services that help you detect what's going on with your site.
If you search for "WordPress security plugins" you will get a very long list of plugins that purport to harden your site and/or mitigate attacks as well as making toast and juice in the morning for you. However, all we want to know at this time is if any of our files have been changed and code injected and for that I prefer one plugin: Wordfence. Wordfence does a lot of different things that you can read about at the preceeding link (and does them pretty well, actually) but the one thing that really gives it its value-add as a free plugin is the ability to scan your theme and plugin files and look for changes and/or malicious code. It does this in two ways:
If your theme/plugin is from the wordpress.org repository, Wordfence compares your current files against the current repo files and reports any changes. You can then display the changes in the browser and evaluate them.
Wordfence will also scan all files looking for encrypted PHP code that probably shouldn't be there. Most inserted malicious code is encrypted and its presence usually indicates something to worry about.
Wordfence is free although they offer a paid subscription service that will perform the scans mentioned above remotely and on a schedule. I have not ever used the paid service as I think there are better services that do the same thing, but it's there if you want it. If I'm going to spend money on a monitoring/remote scan service, I'm going to use one of the following.
So far, we have discussed relatively passive ways of monitoring your site for hacks. Whether it's seeing the Google malware message or noticing performance problems on the site or running a manual scan via Wordfence, the common action is you have to be aware of a problem or initiate an action. For the laziersmarter more proactive among you, there are services that you can subscribe to that provide various levels of site monitoring and will report when things change for the worse. In my experience, there are two excellent services out there: Sucuri and VaultPress.
Sucuri provides two products and we'll cover their second offering later. For this section, we will look at their Website Anti-Virus offering and how it detects hacks. This service works in three ways. First, it will scan your site periodically as if it were a regular user and look for defacements or other evidence of hacks. It will also keep track of a large number of web site blacklists including Google, Symantec, Spamhaus, AVG, ESET, and more than 100 others and work to get your site off the blacklists once the hack is resolved. Finally, if you give Sucuri your login information (SFTP or SSH) for your server, it will periodically scan your site's files looking for changed/malicious code similar to what WordFence does.
VaultPress is an Automattic (the company ultimately behind WordPress) product and ir's primary function is realtime backup of your site's files and databases. If you are willing to pay for the next tier of service, though, VaultPress converts to a real-time malware scanner. Each file it uploads as well all entries in your WordPress database are scanned for malware and you are notified when something is found. Because VaultPress is also your primary backup system, fixing the hack is a one-click affair.
So the two above solutions are both excellent, albeit expensive. One of the primary differences between them is that Sucuri is a much more sophisticated remedy to a hack than VaultPress is. If you report a hacked site and are a Sucuri subscriber, they not only fix the hacked files but do additional scans and work to detect and close any vulnerabilities they can find. This extra hardening goes a long way in preventing future hacks. VaultPress doesn't do this, but their backup service is invaluable if you have a large/deep site. If money is no object, use both (I do).
Help, My WordPress Site Has Been Hacked!
If your site has been hacked, you need to clean it right away. Don't wait, hesitate, or procrastinate. The longer you leave a hacked site running the more likely you are to have your domain end up on a malware blacklist and once that happens you will see your traffic drop precipitously, especially if Google reports your site as an attack site.
The single best way to recover from a hack is to start over. Delete the whole site and database files, change all passwords, and reinstall a clean copy of WordPress and all plugins. Restore your theme and content from a known, good backup source. You are regularly backing up your site, right? If not, START NOW or become a VaultPress subscriber.
For those of you who already backing up, good for you. For the other 90% of you reading this article, here's the steps to take to attempt to clean a site. Please note that the following advice is not a substitute for hiring a security consultant to analyze your site and fix security holes in your server environment. If you have the budget for that, I strongly recommend you spend it and get true penetration testing and analysis done. Alternately, if you are a Sucuri subscriber, simply open a ticket via their site and they will fix yours as well as harden it. If you are not, and want to attempt a manual recovery, try the following:
Contact your ISP right away and report the hack and get them to check their logs to see if the attack is just you or if it affects the whole server or multiple servers. If the ISP is suffering a shell breach and the attacker is able to execute scripts with enhanced privileges then they need to fix that before anything else.
Assuming the situation with the ISP is under control, check your site with a Wordfence or free Sucuri scan to get a better picture of what is going on. Be aware that front-facing scans are of limited utility and you really need to scan the core files. This is something Wordfence does well but, as discussed above, you may want to consider a subscription to Sucuri which will allow them to login and fix any problems and vulnerabilities.
Assuming the hack merely altered files and didn't inject anything into your content, you can reinstall the WordPress core and also delete and reinstall any themes and plugins at this time. Sometimes a hack is simply a defacement that does not do any real damage beyond proving to the hacker that you are vulnerable. If this is the case, reinstall everthing but also change every single password associated with this site (ISP login, Shell/FTP login, MySQL passwords, WordPress admin password, all WordPress user passwords). Even though WordPress user passwords are encrypted, assume that any compromise is a complete compromise and treat everything as having been exposed/stolen. Yes, it's a PITA to re-roll all passwords but the alternative is so much worse.
If the hack inserted malware scripts in your wp-content table you have a more difficult recovery ahead of you. Basically you need to go through the whole content table and clean all of the code from it if you don't have a clean backup. This is why having a regular backup of both files AND database is essential to your well-being.
These four steps should bring you back to "normal" but don't assume anything. Actively monitor the site (again, Sucuri scans are invaluable for this) to see if additional problems exist or if you get re-hacked quickly which tends to indicate that the server is compromised or a backdoor still exists in your code somewhere. But assuming your site comes back clean and remains so for 24-48 hours then there are additional steps you should take to prevent being hacked in the first place and/or provide an easier path to recovery.
How to Prevent (or at least make it more difficult on the attacker) WordPress Hacks
Exploits in the WordPress core files are usually discovered and patched very, very quickly (and a big tip of the hat to the WordPress core developers for their work and emphasis on security) and information on potential security holes is readily available to theme and plugin developers. The single biggest thing you can do to protect your site is keep the WordPress core, themes, and plugins up to date! WordPress makes updating everything very easy but if you manage multiple sites it can be a chore. For those you responsible for multiple sites you may want to investigate a service like JetPack or ManageWP which allows you to update core, themes, and plugins on multiple WordPress sites with one click. That being said, there are multiple vectors of attack and WordPress installations usually become infected by malware in one of two ways:
Your server is compromised and the attacker is running scripts from the shell that targets WordPress installations because of how frequently it's used. Why code an attack for a product with less than 1% market share when you can attack something that is used on 1 out of every 4 or 5 sites?
If the server is compromised, there may not be a whole lot you can do. I always report my hacked sites to the ISP support and let them know that they should check to see if a shell user is executing attack scripts. If this is the case, there is really very little you can do to protect your site until and unless your ISP closes this breech. Your only recourse is to move to a new ISP which can be both expensive and time consuming. However, the steps below may give you some relief and/or make you less of an inviting target.
Absolutely, positively back up your site. Whether you just use a simple cron job to rsync the files and do a MySQL dump or use a good backup plugin like BackupBuddy or subscribe to a live backup monitoring service like VaultPress is up to you but do this. VaultPress is a particularly good choice as it will also clean hacked files as it backs up.
Harden your WordPress site. The Codex provides some basic hardening advice (http://codex.wordpress.org/Hardening_WordPress) but you can and should expand on that advice and proactively take steps to prevent hacks. There are plugins that will close some common server/scripting avenues of attack. Beyond that, you should think about a Sucuri or VaultPress subscription if you have the budget for it as both services actively monitor your site for hacks and provide the ability to fix hacked sites.
An alternative to providing your own security is to consider moving to an ISP that specializes in WordPress hosting and provides all of the security, backups, and patching for you. ISPs like Dreamhost, Pagely or WP Engine are positioning themselves as a nice alternative between wordpress.com's completely managed and locked down option and hosting WordPress on your own at an ISP that just provides the web hosting space and nothing else. By switching to managed WordPress hosting, you pay a little more and in return get all of the flexibility to use whatever themes and plugins you want combined with the security and backups provided through the hosting contract. It really does make life a little simpler.
The middle ground between completely rolling your own security and moving to more expensive hosting such as WP Engine is using the newer class of cloud firewalls/botnet protection. Since the original publication of this article, services such as BruteProtect, Sucuri's Website Firewall, and CloudFlare have all stepped up and into the security space. While all of those services work in slightly different ways and offer different features, the common thread between them is that they maintain a database of know attack IP ranges, header calls that are designed to exploit/inquire about the presence of exploitbale code, and look for non-human browsing speeds. By using one of these services, you help contribute to the overall health of the community while protecting yourself from automated attacks. BruteProtect is free and has been acquired by Automattic and will be integrated with Jetpack at some point. Cloudflare is free to start with but if you want some of the more advanced security features, those come at a cost. Sucuri is a paid service.
Even if the plugin and theme files come up clean, you may want to check the changelogs and last update dates before making a decision to install something. If a plugin or theme is not regularly updated as WordPress is updated or has gone more than a year without any update at all, I tend to skip it and I recommend you do the same. You want to find plugins and themes that are actively maintained by the author(s) if it all possible. When purchasing a premium plugin or theme, absolutely make sure there is a path to support and that you review the support forum (if it exists) to see how fast issues are handled and how well.
Hopefully these steps will allow to recover from a hack or prevent one in the future. If you have any questions please post them below or ask them in the WordPress topic area. Good luck!