How to Clean a Hacked WordPress Site, Step by Step.

Finding out your WordPress site has been hacked is stressful, and the natural reaction is to start deleting suspicious files straight away. That usually makes things worse: you destroy the evidence of how the attacker got in, miss the backdoor they left behind, and the site is reinfected within days.

Cleaning a hacked site works best in a fixed order: contain it, lock the attacker out, find everything they changed, replace rather than repair, and close the hole they came through. This guide walks through each stage.

Signs Your Site Has Been Hacked

  • Visitors are redirected to spam, scam, or adult sites, sometimes only on mobile or only when arriving from Google.
  • Google shows “This site may be hacked” in search results, or Chrome shows a red “Dangerous site” warning.
  • Search results show pages you didn’t create, often in another language or selling pharmaceuticals.
  • Administrator accounts you don’t recognize, or plugins you didn’t install.
  • Your host suspends the account or reports malware, spam sending, or unusual resource use.
  • Unfamiliar code at the top of wp-config.php, index.php, or theme files.

Some infections only show themselves to logged-out visitors or to search engines, so check the site in a private window and look at what Google shows for site:yourdomain.com.

Stage 1: Contain the Damage

  1. Tell your host. They can often see which files were changed and when, scan the account at the server level, and may have clean backups you don’t know about.
  2. Back up the infected site, files and database. It sounds backwards, but if cleanup goes wrong you need something to go back to, and it preserves evidence of how the attack happened. Label it clearly so it’s never restored by mistake.
  3. Put the site in maintenance mode if it’s redirecting visitors or serving malware, so you stop harming them while you work.

Stage 2: Lock the Attacker Out

Do this early, so the attacker can’t simply log back in while you clean.

  • Change every password: all WordPress administrator accounts, your hosting account, SFTP and SSH, and the database user (then update DB_PASSWORD in wp-config.php to match). Also change your email account password if it receives password reset links.
  • Replace the security keys and salts in wp-config.php with a fresh set from https://api.wordpress.org/secret-key/1.1/salt/. This logs out every session, including the attacker’s.
  • Check for administrator accounts you don’t recognize. Malware sometimes hides its accounts from the Users screen, so check the database directly in phpMyAdmin (adjust wp_ to your table prefix):
SELECT u.ID, u.user_login, u.user_email, u.user_registered
FROM wp_users u
JOIN wp_usermeta m ON m.user_id = u.ID
WHERE m.meta_key = 'wp_capabilities'
  AND m.meta_value LIKE '%administrator%';

Delete any administrator you don’t recognize, assigning their content to a real account if WordPress asks.

Stage 3: Find Everything That Was Changed

Run scanners

Use a security plugin’s malware scan (Wordfence’s free scan is thorough) and your host’s scanner if they have one. Scanners won’t catch everything, but they quickly show the obvious infected files and modified core files.

Check WordPress core and plugins against the originals

With WP-CLI, these commands compare your files with the official versions and list anything modified or added:

wp core verify-checksums
wp plugin verify-checksums --all

The plugin check only works for plugins from WordPress.org. Premium plugins need reinstalling from the vendor instead.

Look in the places backdoors usually hide

  • PHP files in uploads. wp-content/uploads should only contain media. Any .php file there is almost certainly malicious. With SSH, find wp-content/uploads -name "*.php" lists them.
  • Recently modified files. find . -type f -name "*.php" -mtime -14 lists PHP files changed in the last 14 days. Compare the dates with when the problem started.
  • wp-config.php, .htaccess, and index.php in the root, which attackers often modify to load malware or add redirects.
  • wp-content/mu-plugins/, which loads automatically and doesn’t appear in the normal Plugins list, and drop-ins such as wp-content/object-cache.php that you didn’t install.
  • Plugins and themes you don’t remember installing.

Malicious code is often heavily obfuscated, with long unreadable strings combined with functions such as eval(), base64_decode(), gzinflate(), or str_rot13(). Legitimate plugins use some of these too, so they’re a reason to look closer, not proof on their own.

Check the database

  • Search posts and pages for injected scripts and hidden spam links: in phpMyAdmin, search the wp_posts table’s post_content for <script and for unfamiliar domains.
  • Check that siteurl and home in wp_options still point to your own domain.
  • Look for unexpected entries in your hosting panel’s Cron Jobs screen, which attackers use to reinstall malware.

Stage 4: Clean the Site

Replace files rather than trying to repair them. Removing malicious lines one by one is slow, and it’s easy to miss one.

  • If you have a clean backup from before the infection, restoring it is often the fastest route. Then go straight to Stage 5, or the same hole will be used again.
  • Reinstall WordPress core: from the dashboard with Dashboard → Updates → Re-install, with wp core download --force, or by uploading fresh wp-admin and wp-includes folders. Never overwrite wp-content or wp-config.php this way.
  • Reinstall every plugin and theme from WordPress.org or the vendor. Delete the old folders first, rather than uploading over them, so no extra files are left behind.
  • Delete PHP files in uploads, unknown plugins and themes, and anything you found in Stage 3.
  • Clean wp-config.php, .htaccess, and the database entries you found, comparing wp-config.php against wp-config-sample.php if you’re unsure what belongs there.

Then scan again, and check the site logged out, on mobile, and by clicking through from a Google search.

Stage 5: Close the Hole

A site cleaned without fixing the original weakness usually gets reinfected. The most common ways in are:

  • An outdated plugin or theme with a known vulnerability. Update everything, and delete what you don’t use.
  • A “nulled” pirated premium plugin or theme. These very often contain backdoors. Replace them with genuine copies.
  • A weak or reused password. Strong passwords and two-factor authentication fix this. See our guide to stopping brute force attacks.
  • Another site on the same hosting account. On shared hosting, an infected old site can reinfect every other site in the account. Clean or remove all of them.
  • An infected computer used to log in. Run a malware scan on the devices you use for SFTP and admin access.

Then work through our WordPress security checklist, especially blocking PHP in uploads, DISALLOW_FILE_EDIT, and off-site backups.

Stage 6: Recover in Google

If Google flagged your site, open Google Search Console → Security & Manual Actions → Security issues. It lists what Google found, often with example URLs. Once the site is clean and you’ve checked those URLs, click Request review and describe what you fixed. Don’t request a review until you’re confident the site is clean, because a failed review delays the next one.

Spam pages the attacker created may stay in search results for a while. Make sure they now return a 404 or 410 so Google drops them.

When to Get Professional Help

Consider a professional cleanup service, or your host’s security team, if the infection returns after cleaning, the site handles payments or customer data, you can’t find the entry point, or you’re not comfortable working with files and the database. For an online store, a quick, verified cleanup is usually worth the cost.

Summary

Contain first: tell your host, back up the infected site, and stop visitors being harmed. Lock the attacker out with new passwords, new salts, and a check for hidden admins. Find every change with scanners, checksums, and the usual hiding places, then replace core, plugins, and themes instead of repairing them. Finally, close the hole the attacker used, and request a review in Search Console once the site is clean.