Got malware? How to fix, clean and secure a hacked WordPress website
Has your WordPress website been hacked? Does it redirect users to sordid offers and unsavoury pharmaceuticals? Perhaps you’ve noticed spammy content appear in your Google search results. This could be the result of malware: trojan code that’s snuck through the back door to serve nefarious ends. The effects of malware range from mildly embarrassing to massively costly. Either way, this won’t do.
How to remove malicious scripts: an exhaustive safety checklist
Below is your comprehensive checklist on how to fix a hacked WordPress website. If it looks intimidating, don’t worry! This is my overly cautious “leave no stone unturned” approach. It might not be necessary to follow every last step. Just do what you can and reach out to a professional if you get stuck.
- Step 1: Precautions
- Step 2: Restore Files
- Step 3: Reinstate WordPress Core
- Step 4: Cleaning Your Server
- Step 5: Security Scrubbing
- Step 6: Secure For The future
Stage 1: Some Precautions
1.1 Raise a support ticket with your hosting company
Some support agents are happy to get their hands dirty, while others tell customers to fix it themselves. In any case, it’s worth flagging the issue in case the hosts have a breach on their end.
1.2 Back up the hacked website (files AND database)
Take a bulk download of your website files, the affected database, and any error logs. This will be your snapshot of what went wrong and could help diagnose the problem later. If you resort to hiring a security expert, they’ll ask for this upfront.
1.3 Download files and database from BEFORE the breach
You might have a backup plugin like UpDraft Plus or WP BackUp Buddy. Or, your hosting company might run scheduled backups. If either of these are available, download a copy of the website from before it was infected.
1.4 Scan your website
Use an online scanner like Sucuri, Wordfence or Anti-Malware Scanner to pore through your files and give an initial diagnosis. A malware scan might provide an early signal of where the breach occurred.
Stage 2: Restore Your Files
With the backups ready, it’s time to patch up your website piece by piece. Your host might offer a one-click restore feature. If so, you are welcome to do that and skip to section 2.4.
2.1 Restore database from your clean backup
If your backups contain a database from before the hack, reinstate it using PHPMyAdmin or the equivalent tool on your control panel. Later, I will advise you to change the database name, user and password entirely.
2.2 Restore wp-content from your clean backup
Your website is made up of hundreds of files and subfolders. If malware spreads into the system it can be very difficult to manage. Instead of weeding out specific files and folders, replace everything in your wp-content folder with the clean equivalent from your backup (step 1.3). Don’t just merge files, delete the old wp-content folder and add the new one.
2.3 Restore your WordPress theme
Although we just replaced wp-content, we want to know your theme is still the real deal. If you bought it online, download the latest version straight from the source. Replace the version you had with this clean copy. Again, don’t merge the files, delete and reupload them.
If your theme was developed by an agency, ask them for their source copy.
2.4 Replace plugins with clean versions
You plugins might have become compromised, or a vulnerability in older versions may have given the malware a back door. For each plugin in your website, download a clean and up to date equivalent from the official WordPress.org repository.
Unzip each plugin folder and temporarily rename it. Upload the lot, delete the old plugins then quickly rename your clean versions so the file paths are correct. Do this via the file manager/SSH and NOT via WordPress. If you delete plugins via WordPress, you might wipe valuable settings.
Stage 3: WordPress Core
WordPress websites runs on a common foundation. Like your themes and plugins, WordPress is made of many parts that might have been compromised during the hack. To be safe, we’re going to strip your site of WordPress core and replace it with the vetted version straight from the source.
3.1 Download a clean copy of WordPress
Head to WordPress.org and download a fresh copy of its latest version.
3.2 Remove old WordPress core files
Remove the following files and folders from your website directory:
- wp-admin (folder)
- wp-includes (folder)
3.3 Restore clean copy of WordPress
Unzip your clean WordPress folder and add the files and folders above to your website directory.
By now, you should have:
- A working database from before the hack
- A wp-content folder with clean plugins, themes and uploads
- A clean and untained version of WordPress
You’re doing great! Now let’s sniff around the server and make a few extra tweaks…
Stage Four: Clean Your Server
4.1 Check htaccess file
.htaccess is a file in your root folder that performs vital functions. Besides basic WordPress setup, it can control firewalls, site caching, redirects and more.
Look through it carefully and flag any code that looks unfamiliar or suspicious. Google that code. It may be something perfectly harmless such as gzip compression, in which case a quick search should confirm its purpose. If forum posts suggests it’s something suspicious, make a note of the code then remove it from .htaccess. If searching doesn’t yield any results, ask a professional.
4.2 Check wp-config file
As above, cross reference any unusual looking rules with Google search. If you’re not sure, download a clean copy of wp-config.php from WordPress.org and add your database details.
4.3 Check for suspicious files in your root directory
Sniff around your site directory for suspicious-looking files or folders. With years of staging websites and developer leftovers, servers can become quite messy. Keep a special eye out for WordPress installations. It’s not uncommon to find these and other backups in the root directory. These could be responsible for a trojan “back door”. Remove them.
Stage Five: Nitty Gritty Security Improvements
All being well, you should now have a working, uncorrupted website. Good as that feels, it doesn’t stop hackers from exploiting the same vulnerability in future. To reduce the chances of this happening, here’s a post-hack security checklist for your freshly recovered website.
5.1 Change FTP/SFTP Accounts
Delete the old FTP login and make an entirely new set. If you were using FTP to move files, switch to SFTP/SSH for a more secure method of transfer.
Likewise, if you were using SSH for file transfer, consider resetting your logins and/or authentification certificate. You can never be too careful!
5.2 Change database name and user
Create a new database and user account on your control panel. Export the fixed database (step 2.1) to this location. Now, update wp-config.php with the new database credentials. Once you’re happy it works, delete the old database and user.
5.3 Check file permissions
Most hosts do this automatically, but it’s best to double check. The recommended file permissions for WordPress are:
- Files: 644
- Folders: 755
- wp-config.php: 600
5.4 Update PHP Version
Older php versions can slow down and compromise vulnerable websites. Switching to 7.2 or higher ensures speed, security and performance benefits for your plugins.
5.5 Clean your WordPress accounts
First, create a new WordPress administrator account and give it a strong password. If you have the option, perform a great purge and delete your other WordPress users (assigning their posts to your new account).
If this is not possible because of contributors and subscribers, take a careful look at your accounts and consider deleting those that aren’t mission critical.
5.6 Disable directory browsing
Add this line of code to your .htaccess file, right underneath the WordPress code.
This stops somebody from being able to browse your wp-content or wp-admin directories and learn about potential vulnerabilities.
5.7 Disable WordPress theme editing
Theme editing via the browser is rarely a good idea. Disable this feature altogether. No need. Nada.
Add the following to wp-config.php
define( 'DISALLOW_FILE_EDIT', true );
5.8 Regenerate Salts
5.9 Clean your database
Install a trusted plugin like WP Optimise or Advanced Database Cleaner. Run a backup, then strip the database of transient settings, unwanted drafts and revisions. This will prune database of any unused settings, plus it might help to improve the overall site speed.
5.10 Disable PHP Execution
Create a .htaccess file in the following directories:
Next, add the following code:
<Files *.php>deny from all</Files>
This will disable hidden, malicious files from executing php scripts without you knowing. See this article on WP Beginner for more information about PHP Execution.
Stage Six: Final Checks + Secure For The Future
6.1 Check WordPress Health
WordPress 5.4 introduced a Health checker that pointed out security and performance traps. Take a look at this area and make sure everything is up to scratch. If you have any errors, here’s a handy list of Site Health fixes.
6.2 Install a fresh version of Wordfence/Sucuri
Whether you used it before, install the plugin from scratch and set up its firewall, blocking limits and notification settings. After setup, run a scan. The software will pore through your files and detect anything that slipped through the cracks.
6.3 Get a second opinion with Anti-Malware Scan
You can’t be too careful. Even if Wordfence gave the thumbs up, check again with the Anti-Malware Scan plugin. This has been a long and frustrating process; best not let it happen again, eh?
6.4 Install 2-factor authentification
Whether through Wordfence or an authenticator plugin, make sure your site can’t be accessed without approval from a mobile device. Remember to do this for all site admins, not just yourself.
6.5 Change WordPress admin URL
Any old schmuck can visit yoursite.com/wp-admin and begin guessing passwords. You can avoid this by changing the login URL to something less predictable.
6.6 Bonus: limit logins to specific IP addresses
This only applies if you and your staff work from a fixed location. If you don’t edit your site on the go, consider limiting logins to your specific IP addresses. This can be done via your security plugin or via your .htaccess file.
Looking ahead: How to safeguard against future hacking attempts
First of all, treat yourself to something nice. Malware removal isn’t fun work, so well done for getting this far.
Looking to the future, ask yourself the following questions about your website security…
Keep an eye on Google Search Console
In the pandemonium, your site might have accrued some dodgy backlinks. Keep checking Search Console and Google Analytics for blackhat backlinks or incoming traffic. If so, consider using Google’s disavow tool to disassociate your website from the internet’s dingy hideouts.
Is my hosting company reliable?
Consider the reply to the support ticket you raised earlier. Follow up with questions about the hosts’s security measures. Judge their response on its specificity; don’t accept vague answers. This is serious business and hosting companies must earn your trust.
Do my plugins reassure me?
Websites can accrue an ugly amount of baggage through their plugins. Look at yours and check that they are:
- Highly rated on WordPress.org
- Frequently patched (check last update)
- Absolutely necessary?
If certain plugins look dodgy, consider replacing them with a more trustworthy solution. While no plugin is foolproof, you’ll fare better with one that is regularly vetted by the WordPress community.
Was my theme built properly?
If your theme was bought online, check how recently it was updated. Have other users reported security complaints? If it’s been long abandoned or you’re not confident about its integrity, consider switching to a better theme.
Am I informed on vulnerabilities?
I’m not usually one for newsletters, but Wordfence’s digest is essential for WordPress site owners. Occasionally, a perfectly decent plugin will have a vulnerability exposed and be forced to update. Should that happen, you want to be sure that your version is patched ASAP.
Congratulations + Feedback!
Well, I think that’s it! Hopefully this has helped you clean your website and arm it for the future. If you think I’ve missed anything or have suggestions then get in touch!