How to Recover a Hacked WordPress Site Step by Step
7 min read
Finding out your WordPress site has been hacked is an awful moment. Before you do anything else, take a breath. Most compromised sites can be fully recovered. It just needs to be done methodically, because the order you do things in matters.
This post covers every step I'd work through, in the order I'd do them.
1. Take the site offline immediately
Do not leave a compromised site serving traffic while you investigate. Visitors may be exposed to malware, phishing pages, or spam redirects. Your reputation and your search rankings take damage for every minute the site stays up.
Put the site into maintenance mode or take it down completely. If you have access to your hosting control panel, suspending the site is the fastest way. If you don't, rename your index.php file temporarily to take the site offline at the server level.
2. Change all passwords immediately
Change every password associated with the site before you do anything investigative. That includes:
- All WordPress admin accounts
- Your hosting control panel
- FTP or SFTP access
- Your database user password
- Any email accounts associated with the domain
If the attacker still has valid credentials, everything you do next can be undone while you work.
3. Regenerate WordPress security keys and salts
WordPress uses security keys and salts to encrypt session tokens and cookies. Regenerating them immediately invalidates all active sessions, including any the attacker may have open right now.
Generate a fresh set from the official WordPress API:
https://api.wordpress.org/secret-key/1.1/salt/
Replace the existing keys in your wp-config.php with the new ones. Every user currently logged in, including any attacker with an active session, will be forced to log in again.
4. Preserve evidence before you restore
This step is easy to skip when you are stressed and want the site back online. Don't skip it.
Before restoring anything, capture the current state of the site. Download your access logs, your error logs, and a snapshot of the current files. You may need these to work out how the compromise happened, and if you restore first you lose the evidence.
5. Check for new or modified admin accounts
Log in to WordPress and go straight to Users. Look for any accounts you don't recognise, particularly administrator ones. Document them before deleting, note the email, the username, and the created date.
Also check for existing admin accounts where the email address has been changed to something you don't recognise. Attackers sometimes modify an existing account rather than creating a new one, because it draws less attention.
6. Scan for malicious files
Run a full malware scan using Wordfence or a similar security plugin. Wordfence compares your WordPress core files, plugins, and themes against known clean versions, and flags anything that doesn't match.
Pay particular attention to:
- PHP files in the uploads directory, which should never be there
- Recently modified PHP files you didn't change
- Files with unfamiliar names in the WordPress root
You can find recently modified PHP files via the command line:
find /var/www/html -name "*.php" -newer /var/www/html/wp-config.php -type f
And specifically check the uploads directory:
find /var/www/html/wp-content/uploads -name "*.php" -type f
If either of those commands returns anything, investigate every file listed.
7. Review your access logs
Your server access logs are a timeline of everything that happened. Look for:
- POST requests to unusual file locations
- Requests to
wp-login.phporxmlrpc.phpfrom unfamiliar IPs - Spikes in traffic that correlate with when the compromise occurred
- Requests for files that shouldn't exist
This is how you find the entry point. Without understanding how the attacker got in, you can't properly close the door before the site goes back online.
8. Identify a clean backup
Go back through your backup history and find a backup taken before the compromise occurred. Use your log review from Step 7 to narrow down the timeframe.
If your most recent backup is already compromised, you need to go further back. This is why backup retention matters. Keeping only the last few days of backups isn't enough if a compromise goes undetected for a week.
If you don't have backups, this is the moment you'll wish you did. You'll need to clean the site manually instead of restoring from a known good state.
9. Restore to a clean environment
Do not restore on top of a compromised server without first removing everything. Malicious files left behind can reinfect a restored site within minutes.
The safest approach is to restore to a fresh environment. If that isn't practical, wipe the document root completely before restoring your files, and then restore your database from the clean backup.
After restoring, verify the site loads correctly and that your content is intact before moving to the next step.
10. Update everything
Before bringing the site back online, update WordPress core, every plugin, and every theme to their latest versions. If the compromise came in through a vulnerable plugin, there's a reasonable chance the patch is already out.
Delete any plugins or themes you aren't actively using. An inactive plugin with a vulnerability is still a risk, because the code is still on the server.
11. Close the entry point
This is the step most people rush past, and the one that decides whether the site gets hacked again. If you don't understand how the attacker got in, you can't be confident they won't come back in through the same gap tomorrow.
Common entry points include:
- An outdated plugin with a known vulnerability
- A weak or reused admin password
- File permissions that were set too loosely
- An exposed
xmlrpc.phpendpoint - A PHP file in the uploads directory that was executed
Match what you found in your log review against this list and fix whatever applies.
12. Harden before going back online
With the site restored and the entry point closed, run through the key hardening steps before making it live again:
- Change the default login URL
- Enable two factor authentication on all admin accounts
- Block PHP execution in the uploads directory
- Set correct file permissions
- Disable the built in file editor in WordPress
- Set up or verify your firewall
13. Bring the site back online and monitor closely
Bring the site out of maintenance mode and watch it carefully for the next 24 to 48 hours. Review your Wordfence logs and your server access logs. Check your uptime monitoring. A second compromise in the days after a recovery is common if the entry point wasn't properly closed.
14. Notify anyone who needs to know
If your site collected user data and that data may have been exposed, you may have legal notification obligations depending on your jurisdiction. In the UK and EU, GDPR requires notification to the ICO within 72 hours of becoming aware of a breach if it poses a risk to individuals. Take this seriously and get advice if you are unsure.
15. Write a brief post mortem
Even a short one. What happened, how it happened, what you did, and what you changed. Without this, it's easy to end up fixing the wrong thing and finding yourself doing all of this again in six months.
One last thing
If you've worked through this post, you already know how much time and stress a compromise costs. Most WordPress compromises are preventable with the right setup in place before anything goes wrong.
The Protect My WP handbook covers hardening a WordPress site properly, from server configuration and file permissions through firewalls, backups, and ongoing maintenance. If this is an experience you don't want to repeat, that's where to look next.
Available here for £19.
Get the free WordPress Security Checklist
The security checks I'd run through on any WordPress site, delivered straight to your inbox.
Want to go deeper?
The first chapter of Protect My WP is free. Start with the foreword, then read Chapter 1 on hosting and server security.