Cleaning Up a Hacked WordPress Site
What to do when a WordPress site is compromised: contain it, find the entry point, clean properly, get delisted, and stop it happening again.

A compromised WordPress site is stressful and the instinct is to start deleting things. That instinct destroys the evidence you need to stop it recurring, and it rarely removes everything.
Here's the order I work in. It's slower on day one and much faster overall, because you only do it once.
First: contain, don't clean
- Take the site offline or put it behind maintenance mode. A site serving malware to visitors is doing damage every minute it's up.
- Take a complete copy — files and database — and store it somewhere isolated. This is your evidence, not a backup to restore.
- Notify your host. Many have tools and logs you don't, and on shared hosting they may already know.
- Change passwords: WordPress accounts, hosting panel, FTP/SFTP, database, and the email accounts associated with them.
- Rotate the authentication salts in wp-config.php. This invalidates every session immediately, which locks out an attacker who has a live login without waiting for password changes to propagate.
Find out how they got in
Skipping this is why sites get reinfected. Cleaning removes the symptom; the entry point is the disease.
- Check plugin and theme versions against known vulnerabilities. An outdated plugin with a public exploit is the most common answer by a wide margin.
- Look at access logs around the time the first modified file appeared. POST requests to unusual paths, or a burst of requests to one file, usually stand out.
- Check for files modified recently, particularly in wp-content/uploads, which should contain no PHP at all.
- Look for user accounts created around that time, especially administrators.
- Check scheduled tasks for events you don't recognise — a common persistence mechanism.
- Check whether a nulled theme or plugin is installed. These frequently ship with a backdoor as the product.
Where malware hides
- PHP files in wp-content/uploads. Nothing legitimate puts executable code there.
- Modified core files. Compare against a fresh download of the same WordPress version; core files should match byte for byte.
- Appended code at the top or bottom of theme files, especially functions.php, header.php and footer.php.
- Injected content in the database — usually in wp_posts, or in wp_options where an injected script is loaded site-wide.
- Fake plugins with plausible names sitting in wp-content/plugins but not listed in the admin.
- .htaccess rules redirecting some visitors — often only search engine referrals or mobile users, which is why the owner never sees it.
- Extra administrator accounts, sometimes hidden from the user list by injected code.
Cleaning: restore beats picking
If you have a backup from before the compromise, restore it. That's the reliable route, and it's why backup retention depth matters — a compromise discovered two weeks late needs a backup older than two weeks.
Manual cleaning is for when there's no clean backup. It means replacing WordPress core with a fresh download, reinstalling every plugin and theme from official sources rather than cleaning them, and then going through uploads and the database by hand.
The honest problem with manual cleaning is that you can never be certain you got everything. A single remaining backdoor means the whole exercise was theatre. If you're not confident, restore and rebuild rather than clean.
After cleaning, before going live
- Update WordPress, every plugin and every theme to current versions.
- Delete every plugin and theme you aren't using, rather than deactivating them.
- Remove any account you don't recognise, and review the roles of the ones you do.
- Rotate salts again, and force a password reset for all users.
- Set DISALLOW_FILE_EDIT so the dashboard editor can't be used to reinstall a backdoor.
- Block PHP execution in wp-content/uploads at the server level.
- Check file permissions: directories 755, files 644, and nothing set to 777.
- Enable two-factor authentication on every administrator account.
Getting delisted
If Google flagged the site, cleaning it doesn't remove the warning automatically. Go to Search Console's Security Issues report, confirm the problem is fixed, and request a review. That usually takes a few days.
Check the same with your host, who may have suspended the account, and with any blocklist your site ended up on. If the site was sending spam, your domain's email reputation may need attention too — check whether you've been listed on the major email blocklists.
Don't request a review until you're actually confident the site is clean. A failed review sets you back further than waiting a day to be sure.
Working out what was taken
This is the part that has consequences beyond the site. If the compromise gave access to the database, consider what was in it: customer names, addresses, order histories, email addresses, hashed passwords.
Depending on what was exposed and where your customers are, you may have notification obligations. Even where you don't, telling affected people that their password may be compromised — so they can change it on other sites where they reused it — is the right thing to do.
Document the timeline while it's fresh: when the first modification happened, when it was discovered, what was accessible. You'll need it if anyone asks later.
Monitoring afterwards
- File integrity monitoring, so a changed core or theme file is noticed in hours rather than weeks.
- Alerts on new administrator accounts and role changes.
- Uptime and content monitoring that would catch a defacement or a redirect.
- Regular external scans, since some infections only show themselves to search engine crawlers or mobile users.
- Check the site yourself from a phone, on mobile data, occasionally — some redirects only fire for those visitors.
When to call someone
If the site handles payments or personal data, if you can't identify the entry point, or if it's been reinfected after a cleanup, get help rather than iterating. Repeated reinfection means the backdoor is still there and each cleanup is missing it.
If you're in that position and want a second pair of eyes, send me the URL and what you've done so far, and I'll tell you what I'd check next.
Frequently asked questions
How do I know if my WordPress site is hacked?
Common signs: a browser or Search Console warning, unexpected redirects (often only for search referrals or mobile visitors), admin accounts you didn't create, PHP files in the uploads directory, a sudden drop in search traffic, or your host suspending the account. Check from a phone on mobile data too — some redirects only fire there.
Can I just restore a backup to fix a hacked site?
Restoring is the reliable cleanup, but only half the job. If you restore the same vulnerable plugin that let them in, you'll be reinfected within days. Identify the entry point first, then restore from a backup predating the compromise, then update or replace whatever was vulnerable before going live.
Should I use a malware removal plugin?
Scanners are useful for finding known signatures and for file integrity checking. They're less reliable at removing everything, because a single missed backdoor undoes the whole exercise. Use one to help you find things; prefer restoring from a clean backup over trusting automated removal.
How long does it take to clean a hacked WordPress site?
With a clean backup and an identified entry point, a few hours. Without a usable backup, manual cleaning of core, plugins, uploads and the database takes considerably longer and carries real uncertainty about whether you got everything. Getting delisted by Google typically adds a few days on top.
How do I stop my WordPress site being hacked again?
Fix the entry point — almost always an outdated plugin or a weak password. Then keep everything updated, enable two-factor authentication on every administrator, delete unused plugins and themes, block PHP execution in uploads, and set up file integrity monitoring so the next attempt is caught in hours.
Topics
- WordPress malware removal
- hacked WordPress site
- WordPress cleanup
- WordPress security