Hacked WordPress Site Fix: The Complete Step by Step Recovery Guide

If your site is redirecting visitors to a pill store, throwing a white screen or showing a red warning in Google search results, you are in the right place. This guide walks through a complete hacked WordPress site fix, from confirming the compromise to removing the malware, closing the backdoor that let the attacker in and getting your rankings back. It is written for site owners and developers who need to work through the problem methodically rather than guess at it.

Work through the steps in order. Skipping ahead is the single most common reason a cleaned site gets reinfected within days.


The short version: how to fix a hacked WordPress site

To fix a hacked WordPress site, take the site offline, back up the current infected state, rotate every credential, replace WordPress core, plugins and themes with clean copies, clean the database, hunt down backdoors, remove any unauthorised admin accounts, then harden the site and request a review from Google. In practice that breaks down into eleven steps:

  1. Confirm the site is actually hacked rather than broken.
  2. Put the site into maintenance mode and tell your host.
  3. Take a full forensic backup of files and database before you change anything.
  4. Reset all passwords, keys and salts, then force every session to log out.
  5. Scan the site and identify what type of infection you are dealing with.
  6. Replace WordPress core files with a fresh download.
  7. Reinstall plugins and themes from official sources and delete anything unused.
  8. Clean the database of injected scripts, spam posts and rogue options.
  9. Find and remove backdoors, including cron jobs, uploads folder PHP files and must use plugins.
  10. Audit user accounts and remove anything you do not recognise.
  11. Harden the site, then request a security review in Google Search Console.

A straightforward infection on a small site takes two to four hours. A large ecommerce site with a skimmer in the checkout flow can take days and usually needs a specialist. The rest of this article expands each step in detail.


Signs your WordPress site has been hacked

Not every broken site is a hacked site. A failed plugin update, a PHP version bump or an expired SSL certificate can all look alarming without any attacker involved. These are the symptoms that point to a genuine compromise.

Symptoms visitors notice

  • The homepage redirects to a site you have never heard of, often only on mobile or only for first time visitors.
  • Browsers show a full page red warning saying the site contains malware or deceptive content.
  • Pop ups, adult ads or fake download buttons appear on pages that never had them.
  • Defacement, meaning your content replaced with a message from whoever broke in.
  • Customers report card fraud shortly after buying from your store.

Symptoms you see in search results

  • Google shows “This site may be hacked” under your listing.
  • Your indexed pages have titles in a language you do not publish in, commonly Japanese or Russian.
  • Search Console reports a sudden spike in indexed URLs, often thousands of pages you never created.
  • Meta descriptions mention pharmaceuticals, loans, casinos or replica goods.
  • Search Console sends a Security Issues notification.

Symptoms only an admin sees

  • You cannot log in, or your admin account has been demoted to subscriber.
  • New administrator accounts you did not create, often with gibberish usernames.
  • Core files with recent modification dates, especially index.php, wp-config.php, .htaccess or files in wp-includes.
  • PHP files sitting inside wp-content/uploads, where only media should live.
  • Server load and outbound email volume far above normal, which usually means the server is being used to send spam.
  • Your host suspends the account or emails you an abuse report.
  • Scheduled tasks in WP Cron that you do not recognise.

One symptom on its own can be innocent. Two or more together almost always means a compromise, and you should treat it as one until proven otherwise.


Common types of WordPress hacks and where they hide

Identifying the infection type early tells you where to look and saves hours of blind searching.

Hack typeWhat you seeWhere it usually hides
Malicious redirectVisitors bounced to an unrelated domain, often only on mobile or from search referrals.htaccess, index.php, theme functions.php, injected scripts in the options table
Pharma or SEO spamHidden links and keyword stuffed text visible to crawlers but not to logged in usersDatabase posts and options, footer templates, cloaking code that checks the user agent
Japanese keyword hackThousands of auto generated pages with Japanese text and affiliate linksRogue sitemap files, generated PHP in the root, unauthorised Search Console owner
Card skimmerNothing visible, but customer cards get used fraudulentlyWooCommerce checkout templates, obfuscated JavaScript in the database, mu-plugins
Crypto minerSlow site, high CPU on the server, browser fans spinning upInjected JavaScript in headers, footers or a cached template
Spam mailerEmails from your domain landing in spam traps, IP blacklistedStandalone PHP scripts in uploads or a plugin folder, sometimes hidden in an image directory
DefacementYour homepage replaced with a message or logoindex.php, the active theme, a modified homepage record in the database
Ransom or wiperContent deleted, a note demanding paymentDatabase tables dropped or renamed, files removed
Fake plugin backdoorNothing visible at allA plugin folder with a plausible name that is not in the WordPress repository

Before you start: what you need

Gather these before touching anything. Half of a difficult cleanup is not having access when you need it.

  • SFTP or SSH access to the web root, plus your hosting control panel login.
  • Database access through phpMyAdmin, Adminer or the command line.
  • A local copy of the site so you can search files quickly with a proper editor.
  • Server access logs covering at least the last thirty days. These are how you find the entry point.
  • Google Search Console verified for the property.
  • A list of every plugin and theme you expect to be installed, with version numbers if you have them.
  • WP-CLI if your host supports it. It turns several of the steps below into single commands.

Do the work from a clean machine. If your own laptop has an information stealer on it, resetting passwords just hands the attacker the new ones.


Step 1: Take the site offline and notify your host

A live infected site keeps harming visitors, keeps sending spam and keeps digging your search reputation deeper. Put it behind a maintenance page or a temporary 503 response while you work.

Then open a ticket with your host. Good hosts will tell you things you cannot easily find yourself: which account was compromised, whether other sites on the same server are infected, whether the intrusion came through FTP or the web and whether they hold older backups than you do. Shared hosting compromises frequently spread sideways between sites on the same account, so if you run several sites in one hosting space, assume all of them need checking.

Step 2: Back up the infected site before you change anything

This feels wrong. Do it anyway. The infected state is your only evidence, and deleting a malicious file before you have read it removes your best clue about the entry point. It also protects you if a cleanup step goes wrong and takes legitimate content with it.

Download the entire web root plus a full database dump. Label the archive clearly as infected and store it away from your working directory.

# From SSH, with WP-CLI available
wp db export ~/infected-db-backup.sql
tar -czf ~/infected-files-backup.tar.gz public_html

While you are here, note the timestamps. Run a listing of recently modified PHP files. That list is often the shape of the whole attack.

# PHP files changed in the last 14 days, newest last
find . -type f -name "*.php" -mtime -14 -printf "%TY-%Tm-%Td %TH:%TM %p\n" | sort

Step 3: Rotate every credential

Cleaning files while the attacker still holds a valid password is wasted effort. Change all of the following, not just the WordPress admin password:

  • Every WordPress user password, starting with administrators.
  • The hosting control panel password.
  • All FTP and SFTP accounts. Delete any you do not recognise.
  • The database user password, updating wp-config.php to match.
  • SSH keys, revoking any authorised key you did not add.
  • Application passwords and API keys issued to third party services.
  • Your DNS registrar and email accounts tied to the domain.

Then invalidate existing sessions by replacing the authentication keys and salts in wp-config.php. Generate a fresh set from the official WordPress secret key service and paste them over the old block. Every logged in session, including the attacker’s, is dropped immediately.

# Replace all salts in one command
wp config shuffle-salts

If you find the entry point later and it turns out to be a stolen credential, you will be glad you did this first.

Step 4: Scan and map the infection

Scanning gives you a map, not a cure. Run more than one scanner, because each catches things the others miss.

  • A server side plugin scanner such as Wordfence or Sucuri Security, which compares your files against known good copies and flags injected code.
  • A remote scanner that fetches your pages the way a visitor would, catching client side injections and cloaked redirects.
  • Google Search Console Security Issues, which tells you exactly which sample URLs Google flagged.
  • A checksum comparison against the official WordPress release, which is the most reliable single test for core file tampering.
wp core verify-checksums
wp plugin verify-checksums --all

Any file that fails a checksum check and is not something you deliberately edited should be considered modified by the attacker. Note that verify-checksums only covers plugins hosted in the WordPress.org repository, so premium plugins need manual comparison against a fresh download from the vendor.

Write down every flagged path in a plain text file as you go. A cleanup you can audit is a cleanup you can trust.

Step 5: Replace WordPress core

Do not try to repair individual core files. Overwrite the lot. Core contains no user content, so replacing it is safe as long as you leave the right things alone.

  1. Download the current WordPress release from wordpress.org.
  2. Delete the wp-admin and wp-includes directories entirely, then upload the fresh versions.
  3. Overwrite the loose PHP files in the root, including index.php, wp-login.php and wp-settings.php.
  4. Leave wp-config.php, wp-content and your .htaccess in place for now. You will clean those separately.
wp core download --force --skip-content

Now look for files that do not belong. A clean WordPress root has a predictable, short file list. Anything else, especially a PHP file with a random name or a name designed to look official, deserves inspection.

Regenerate .htaccess from scratch rather than editing it. Injected redirect rules are frequently padded with hundreds of blank lines so they sit far below the visible area of an editor. Save a copy for reference, delete the file, then let WordPress write a new one by saving your permalink settings.

Open wp-config.php by hand and read every line. Look for anything above the WordPress bootstrap, any include pointing at an unfamiliar path, any encoded string or any function definition. The file should contain constants and one require statement, nothing more.

Step 6: Clean plugins and themes

This is where most infections live, because outdated plugins are the most common way in.

  • Delete every plugin you are not using. Deactivated plugins are still executable code sitting on your server.
  • Reinstall the ones you keep from source. Delete the folder and install a clean copy rather than running an update over infected files.
  • Check for plugins you never installed. Search the name. If it is not in the WordPress repository and did not come from a vendor you pay, treat it as a backdoor.
  • Remove abandoned plugins. Anything without an update in two years or removed from the repository needs replacing, not reinstalling.
  • Do the same for themes. Keep your active theme, its parent if it uses one and one default theme as a fallback. Delete the rest.

If you have a child theme or custom code in a theme’s functions.php, that file cannot be replaced wholesale, so read it line by line. Injected code in functions.php is usually parked at the very top or the very bottom of the file.

Pay particular attention to wp-content/mu-plugins. Must use plugins load automatically, cannot be deactivated from the dashboard and do not appear in the normal plugins list, which makes the directory a favourite hiding place. On most sites it should not exist at all.

Step 7: Clean the database

File cleanups miss database infections completely, which is why so many sites come back to life still redirecting. Export a copy of the database first, then work through it.

Where to look

  • The options table. Check siteurl and home point at your real domain. Look for injected script tags in widget options, header or footer settings and any autoloaded option with a suspicious name.
  • Posts and pages. Search for hidden link blocks, iframes and encoded strings. Spam is often wrapped in inline styles that push it out of the viewport.
  • Users and usermeta. Look for accounts with administrator capabilities that are not in your expected list.
  • Postmeta. Injected redirect code sometimes rides along in custom fields.
  • Unfamiliar tables. Tables that do not match your table prefix or any installed plugin are worth investigating before you drop them.
# Search the whole database for common injection markers
wp db search "<script" --all-tables
wp db search "base64_decode" --all-tables
wp db search "eval(" --all-tables

Some legitimate plugins store script tags for analytics or embeds, so review each hit rather than deleting in bulk. Work in small edits and reload the front end after each one. If something breaks, you will know exactly which change caused it.

Step 8: Hunt down the backdoors

A backdoor is a small piece of code that lets the attacker back in after you have cleaned everything else. If your site gets reinfected within days, you missed one. Attackers routinely plant several in different places specifically so that a partial cleanup fails.

The places to check, in order

  • The uploads folder. There is no legitimate reason for executable PHP to live in wp-content/uploads.
  • mu-plugins, as covered above.
  • Scheduled tasks. Both WP Cron and real server crontab entries. A cron job that re downloads malware every hour will undo your entire cleanup.
  • Files with a leading dot or names that mimic core files with a small spelling change.
  • Image directories containing files with double extensions.
  • Directories above the web root if your hosting account can reach them.
  • Unauthorised owners in Search Console. Attackers add themselves as verified owners so they can keep submitting spam sitemaps after you clean the site. Check the verification file and DNS records too.
# PHP where it should never exist
find wp-content/uploads -name "*.php" -o -name "*.phtml"

# WordPress scheduled tasks
wp cron event list

# Real cron jobs for the current user
crontab -l

Then block execution in uploads at the server level, so that a future upload vulnerability cannot be turned into code execution. On Apache, add a small .htaccess file inside the uploads directory.

<FilesMatch "\.(?i:php|phtml|phar)$">
  Require all denied
</FilesMatch>

On Nginx the equivalent goes in your server configuration, so ask your host to deny PHP execution under the uploads path.

Step 9: Audit users and permissions

List every administrator and confirm each one is a person who should have that access.

wp user list --role=administrator --fields=ID,user_login,user_email,user_registered

Delete accounts you do not recognise rather than just demoting them. Then check registration date order: an admin account created in the middle of the attack window is your smoking gun, and its email address may appear in your access logs.

While you are here, turn off open registration unless you genuinely need it, and set the default new user role to subscriber. An install that allows anyone to register as a contributor is a much softer target.

Step 10: Find the entry point

You are not finished until you know how the attacker got in, because otherwise the same door is still open. Take the timestamp of the earliest modified malicious file and pull your access logs for the hour before it.

The usual suspects, roughly in order of frequency:

  1. An outdated plugin or theme with a publicly known vulnerability. Look for repeated POST requests to a single plugin path just before the first file change.
  2. A weak or reused password found through brute force or credential stuffing. Look for a long run of failed logins followed by one success.
  3. Stolen credentials taken from an infected computer or an insecure FTP connection. FTP logins from an unexpected country are the tell.
  4. A compromised neighbour on shared hosting, spreading across accounts.
  5. Pirated premium plugins or themes, which very often ship with the backdoor pre installed.
  6. An outdated server stack, or an abandoned staging copy of the site that nobody was patching.

If you cannot determine the entry point at all, assume it was a credential leak and a plugin vulnerability together. Patch everything, rotate everything and add a firewall.

Step 11: Verify the site is clean

Before you take the maintenance page down, confirm the fix from the outside as well as the inside.

  • Rerun your file and remote scanners until both come back clean.
  • Load the site logged out, in a private window, on mobile and on desktop. Cloaked redirects often only fire for logged out mobile users.
  • Fetch a page with a search engine crawler user agent, since spam is frequently served only to bots.
  • Run a site: search on your domain to check for spam pages still in the index.
  • View source on your homepage and skim for anything unfamiliar near the closing body tag.
  • Purge every layer of cache: WordPress caching plugin, host cache, CDN and your own browser.

A site that looks clean to you but dirty to Google is usually a caching problem or a cloaking script, not a mystery.


Should you just restore a backup instead?

Restoring a clean backup is the fastest hacked WordPress site fix when the conditions are right. It is also the most common way people reinfect themselves, because most infections sit quietly for weeks before doing anything visible, which means the backup often contains the backdoor too.

Restore a backup whenClean manually when
You know roughly when the compromise started and have a backup from before itYou have no idea how long the infection has been present
Little content has changed since the backupThe site takes orders, comments or form submissions you cannot afford to lose
The site is small and simpleYour only backups are recent, and therefore probably infected
You can patch the original vulnerability immediately after restoringYou still do not know how the attacker got in

If you do restore, patch everything and rotate all credentials in the same session. An unpatched restored site gets hit again through the same hole, sometimes within hours, because automated scanners have already recorded your domain as vulnerable.

A practical middle path: restore the clean backup for files, then carefully merge in newer content from the database instead of taking the whole infected database back.


Getting your site out of Google’s blacklist

Cleaning the site does not clear the warnings. Those come off through a review process, and the review fails if any trace of the infection remains, so only start once you are confident the site is clean.

  1. Open Security Issues in Google Search Console and read the sample URLs. Confirm each one is clean now.
  2. Remove any verified owner you do not recognise, and delete stray verification files and DNS TXT records.
  3. Delete rogue sitemaps and resubmit your real one.
  4. Click Request Review and describe what happened, what you removed and what you changed to prevent it. Specific descriptions get processed more smoothly than one line requests.
  5. Wait. Malware reviews typically clear in a few days. Spam reviews can take longer.
  6. For spam pages that were indexed, let them return a 404 or 410 status. Do not redirect thousands of spam URLs to your homepage.

Separately, check whether your domain or server IP landed on an email blacklist. If the site was used to send spam, your legitimate email deliverability will suffer until you request delisting from the major reputation providers.

Recovering lost rankings

Traffic usually recovers, but not instantly. What helps:

  • Getting the warning removed quickly, since the length of exposure matters more than the fact of it.
  • Making sure your important pages return 200 and render correctly for crawlers.
  • Removing spam pages properly so crawl budget goes back to real content.
  • Checking for a spike in spammy inbound links, which some attacks create as a side effect.
  • Publishing normally again. A site that goes quiet after an incident recovers more slowly than one that keeps shipping.

How to stop it happening again

Most compromises exploit something that had a fix available for months. Hardening is unglamorous and it works.

Do these first

  • Enable automatic updates for WordPress core, plus for plugins where you can tolerate the risk of a broken update. Pair this with staging for anything critical.
  • Turn on two factor authentication for every administrator. This alone neutralises credential stuffing.
  • Use unique passwords from a password manager for hosting, WordPress, database and email.
  • Limit login attempts and rate limit requests to wp-login.php and xmlrpc.php.
  • Run a web application firewall at the edge, so known exploit attempts never reach PHP.
  • Take off site backups automatically, keep at least thirty days of versions and test a restore once. An untested backup is a hope, not a plan.

Then tighten the install

  • Disable the file editor so a stolen admin session cannot write PHP through the dashboard.
  • Give every person the lowest role that lets them do their job. Editors rarely need administrator access.
  • Delete unused plugins, themes and old staging copies. Reduce the amount of code you are responsible for patching.
  • Never install pirated premium software. Free versions of paid plugins are one of the most reliable sources of pre installed backdoors.
  • Use SFTP or SSH, never plain FTP, which sends credentials in the clear.
  • Set correct file permissions, typically 644 for files and 755 for directories, and never 777 on anything.
  • Block PHP execution in uploads, as shown earlier.
  • Monitor for file changes and set up uptime and malware alerts so you hear about problems before your customers do.
  • Keep PHP and the database current. An unsupported PHP version stops receiving security patches entirely.
// Add to wp-config.php above the require statement
define( 'DISALLOW_FILE_EDIT', true );
define( 'DISALLOW_FILE_MODS', false ); // set true only if you deploy code via version control
define( 'FORCE_SSL_ADMIN', true );
define( 'WP_AUTO_UPDATE_CORE', 'minor' );

Finally, write down who does what if this happens again: who has hosting access, where the backups live, who talks to customers and who declares the site clean. Ten minutes of planning now saves a chaotic afternoon later.


DIY or hire someone: how to decide

ApproachTypical costTypical timeBest for
Fix it yourself with this guideYour time only2 to 8 hoursSmall sites, comfortable with SFTP and databases, no payment data involved
Security plugin with a paid cleanup serviceRoughly 100 to 300 USD per incident or bundled with a subscription12 to 72 hoursStandard infections where you want a documented clean bill of health
Managed host cleanupSometimes included, otherwise a flat feeVaries widelySites already on managed WordPress hosting
Independent developer or agencyHourly, often 75 to 200 USD per hour1 to 3 daysCustom builds, heavy plugin stacks, sites you cannot afford to break
Incident response specialistFour figures and upDays to weeksCard skimmers, data breaches, anything with legal or regulatory exposure

Get help immediately, without attempting a DIY fix, if any of these apply: customer payment card data may have been exposed, personal data was accessed and you have breach notification duties, the site has been reinfected more than once, or the compromise reaches beyond WordPress into the server itself. In those cases, preserving evidence matters as much as restoring service, and an amateur cleanup destroys the evidence.


Frequently asked questions

How much does it cost to fix a hacked WordPress site?

Nothing but your time if you clean it yourself. A paid cleanup service usually runs somewhere between 100 and 300 USD per incident, a developer or agency charges by the hour and a full incident response engagement on an ecommerce site can reach four figures. The cost scales with the sensitivity of the data involved, not with the size of the site.

How long does it take to clean a hacked WordPress site?

A simple infection on a small site takes two to four hours of focused work. Complicated cases with multiple backdoors and database injections take a day or more. Add a few days on top for Google to lift any warning after you request a review.

Can I fix a hacked WordPress site without a backup?

Yes. Backups make the job faster but they are not required. Core, plugins and themes can all be replaced with clean copies from source, which leaves only the database and your uploads folder to clean by hand. Take a copy of the infected site first so you can recover anything you delete by mistake.

Will I lose my Google rankings?

Usually you lose traffic temporarily rather than rankings permanently. The damage tracks how long the warning stayed up and how many spam pages got indexed. Sites cleaned within a few days typically recover over the following weeks. Sites left infected for months take considerably longer.

Why does my site keep getting hacked again?

Almost always one of three things: a backdoor you did not find, the original vulnerability still unpatched, or a credential still in the attacker’s hands. Check mu-plugins, cron jobs and the uploads folder, confirm every plugin and theme is current and rotate hosting, FTP, database and WordPress passwords together rather than one at a time.

Is it easier to delete everything and rebuild?

Sometimes, and it is a legitimate option for a small brochure site with a handful of pages. A clean install with content copied over by hand carries no risk of a missed backdoor. It stops making sense once you have a large content archive, an ecommerce catalogue or significant custom development, where the rebuild costs more than the cleanup.

Can a hacked website infect my computer?

It can attempt to. Some infections serve drive by downloads or fake update prompts to visitors. Run a reputable antivirus scan on any machine you used to browse the infected site, and be especially careful if you were prompted to download or install anything.

Do I need to tell my customers?

If personal data or payment details may have been accessed, yes, and depending on where you and your customers are based you may be legally required to notify a regulator within a set window. For a defacement or SEO spam incident with no data exposure, a short public note is good practice but rarely mandatory. Take legal advice if you are unsure.

Is WordPress less secure than other platforms?

WordPress core is actively maintained and patched quickly. Its risk profile comes from scale and from the plugin ecosystem: a very large number of sites running third party code of varying quality makes it a productive target for automated attacks. A well maintained WordPress site with a small, current plugin set and two factor authentication on admin accounts is a hard target.

Will a security plugin alone keep my site safe?

No single tool is enough. A firewall and scanner catch a great deal, but they cannot compensate for outdated plugins, shared passwords or an admin account without two factor authentication. Treat the plugin as one layer among several rather than the whole defence.


Your next steps

A hacked WordPress site fix is a process, not a single action. Take the site down, preserve the evidence, rotate credentials, replace code with clean copies, clean the database, find the backdoor, close the entry point, then harden what remains. Do those in order and the site stays clean. Skip the backdoor hunt and you will be reading this guide again next week.

If you are partway through and stuck, or if payment data is involved, stop and bring in help. There is no prize for cleaning it alone.