Troubleshooting

My WordPress site was hacked: a recovery checklist.

Work in this order. The instinct is to delete the bad files immediately — doing that first destroys the evidence of how they got in, which is how sites get compromised twice.

Before anything else

Take a copy, then take the site down

Download a complete copy of the files and database before you clean anything. It is the only record of how the attacker got in, and cleaning overwrites it. Keep it somewhere isolated — it contains live malware.

Then put the site into maintenance mode. Every minute it stays up it may be serving malware to visitors and deepening a search engine penalty.

Confirm

Is it actually a compromise?

Not every strange symptom is an attack. A blank page is usually a plugin conflict, and a database error is usually a credentials problem. What distinguishes a compromise is content or behaviour nobody on your team created.

  • Visitors redirected to unrelated sites, often only from search results or only on mobile
  • Pages, posts or outbound links you did not add — frequently pharmaceutical or gambling spam
  • A browser interstitial or a Google Search Console security notice
  • Administrator accounts you do not recognise
  • .php files inside wp-content/uploads, where executable code never belongs
  • Your host suspending the account for sending spam

Check from the outside

Many attacks specifically hide from logged-in administrators, serving clean pages to you and spam to everyone else. Check in a private window, from a different network, and look at what search engines have indexed for your domain. The version of your site that Google sees is often the one carrying the payload.

Recovery

The checklist, in order

1. Preserve evidence

Full file and database copy, stored offline and clearly labelled as infected. Also download your server access logs if the host provides them — they often show the request that established access, and the timestamp narrows which backup is safe.

2. Contain

Maintenance mode or an offline holding page. If the host has suspended the account, leave it suspended while you work; arguing for reinstatement before cleaning wastes time you need.

3. Rotate every credential

Hosting control panel, FTP and SFTP accounts, the database user, and every WordPress administrator. Then replace the salts in wp-config.php — the block of keys beginning AUTH_KEY. Fresh values are generated by the WordPress salt API, and replacing them invalidates every existing session, ejecting anyone still logged in. Changing passwords without this leaves active sessions intact.

4. Audit users

Remove administrator accounts you cannot account for. Check registration dates against the incident window. Also check whether new user registration was silently enabled and the default role set to administrator, which is a quiet, common persistence trick.

5. Restore, or clean

If you have a backup from before the compromise, restoring is faster and materially more trustworthy than cleaning — you are replacing an unknown state with a known one. The trap is that a restore also reinstates the vulnerability, so step 6 is not optional.

Without a clean backup, replace rather than repair: delete WordPress core files and reinstall the same version fresh, then reinstall every theme and plugin from source. Keep only wp-config.php (after inspecting it) and wp-content/uploads (after checking it for executable files).

6. Close the entry point

This is the step that determines whether you are back here next month. Update WordPress core, every plugin and every theme. Delete anything unused. Identify which component was vulnerable — the logs and the disclosure timeline usually make this clear — and if it is abandoned by its author, replace it rather than reinstalling it.

7. Verify, then request review

Scan again, check the site from outside as an anonymous visitor, and confirm search results are clean. If the site was flagged, request a review through Google Search Console. Reviews fail most often because a backdoor was missed — so verify properly before submitting rather than submitting hopefully.

Prevention

How to stop it happening again

The uncomfortable finding in almost every WordPress post-mortem is that the vulnerability had been patched before the site was compromised. The exploit was available, the fix was available, and the update had not been applied.

  • Update promptly, especially plugins. Disclosure is public, so the gap between patch and application is exactly when scanning traffic finds you.
  • Delete unused plugins and themes. Deactivated code still sits on the server and can still be reachable.
  • Use unique passwords and two-factor authentication on administrator and hosting accounts.
  • Keep off-site backups with enough history. Compromises are often found weeks later; seven days of retention is not enough to reach a clean copy. How to back up a WordPress site covers retention and testing the restore.
  • Prevent PHP execution in the uploads directory. Legitimate uploads never need to execute.
At scale

If you manage this across multiple sites

A disclosed vulnerability in a plugin you have standardised across a client portfolio is not one incident, it is a countdown across every site running it. The response that matters is measured in hours, and it has to be one action across the fleet rather than a queue of logins.

Recovery is also where snapshot history earns its keep. Knowing precisely what changed and when — and being able to reverse a specific change rather than rolling an entire site back to last night — is the difference between a contained incident and a lost day of client data.

Managing multiple WordPress sites covers fleet-wide updates, and one-click undo covers reversing individual changes.

Questions

Hacked WordPress sites, answered.

How do I know if my WordPress site has been hacked?

Common signs are unexpected redirects to other sites, spam content or pages you did not create, a browser or search engine warning, administrator accounts you do not recognise, unfamiliar files in the uploads directory, a sudden traffic or performance change, and your host suspending the account. Search engines often notice before the site owner does.

Should I restore from a backup or clean the site?

Restore if you have a backup from before the compromise and can identify roughly when it happened — it is faster and more reliable than hunting for injected code. But restoring alone is not enough: it returns the site to the state that was vulnerable, so you must patch the entry point immediately afterwards or you will be compromised again.

How did they get in?

Overwhelmingly through a known vulnerability in an outdated plugin or theme, rather than a targeted attack. Automated scanners look for specific vulnerable versions across the entire web and exploit whatever they find. Weak or reused administrator passwords and compromised hosting credentials account for most of the remainder.

What are salts and why change them?

Salts are cryptographic keys in wp-config.php used to secure login cookies. Replacing them invalidates every active session, which forces any attacker still logged in to be logged out. Changing passwords without replacing salts leaves existing sessions valid — a step people frequently miss.

My host says the site is clean but it keeps getting reinfected. Why?

Almost always a backdoor that survived the cleanup, or an entry point that was never closed. Backdoors are often placed far from the original infection — in the uploads directory, a mu-plugin, or a legitimate-looking core file — specifically so that cleaning the visible damage does not remove them. Reinstalling core, themes and plugins from fresh source files is more reliable than selective cleaning.

Patch every site before the scanners find them.

One instruction across your whole portfolio, with a snapshot before every change.

Start free