How to Clean a Hacked WordPress Site and Prevent Reinfection
A hacked WordPress site rarely announces itself. Usually you find out because Google has flagged the domain, a customer emails about a strange redirect, or your host suspends the account for sending spam. The instinct is to delete the obvious bad file and move on. That almost never works. Most compromises leave backdoors behind, and the second infection tends to arrive within days of the first cleanup. What follows is the sequence worth following on a live site: contain the damage, find every foothold, rebuild cleanly, then close the doors that were left open.
First, Contain the Damage
Before you delete anything, take a snapshot. You want a forensic copy of the files and the database exactly as they are, because it tells you how the attacker got in and what they touched.
Log into your hosting panel and create a full backup or a server snapshot. Separately, export the database through phpMyAdmin or WP-CLI, and download the wp-content directory. If you can, copy the web server's access logs too, as far back as they go. Store these files somewhere that is not the compromised server.
Then take the site offline. A maintenance page, a password-protected staging copy, or a full account suspension all work; the goal is to stop the site from serving malware or spam while you work. If the site sells anything, decide deliberately how long you can afford to be down rather than leaving it exposed for days.
One more thing before you move on: if customer data, payment details, or user accounts may have been exposed, tell your host and get proper advice about your notification obligations. That is a legal question, not a technical one, and it varies by where you and your users live.
Find Every Foothold
Attackers almost never leave just one file. A typical compromise includes the original entry point, a web shell for re-entry, an admin user they created, and often a scheduled task that quietly repairs the damage you undo. Check all of these:
- Core files. WP-CLI makes this quick: wp core verify-checksums compares your installation against the official copy for your version. Pay attention to anything flagged.
- Plugins and themes. wp plugin verify-checksums --all catches modified files. Also look for PHP files inside wp-content/uploads — there is no legitimate reason for one to exist there.
- Common hiding places. Stray index.php files in upload folders, mu-plugins, drop-ins such as advanced-cache.php and object-cache.php, and .htaccess rules that redirect visitors or hide the site from search engines.
- wp-config.php. Look for injected include statements, obfuscated strings, and constants you did not add. Malware here survives most cleanups because the file is not part of the core checksum.
- The database. Dump it and search for base64_decode, eval(, <script>, and iframes. Check wp_options for a corrupted siteurl or home value, wp_posts for injected content, wp_users for accounts you don't recognize, and wp_usermeta for anyone whose role was quietly raised to administrator.
- Scheduled tasks. The cron entry in wp_options is a favourite hiding spot. Unfamiliar events should be removed.
- Server level. Ask your host to review logs for POST requests to odd paths and outbound connections to unknown addresses. Spam scripts and shells frequently call home.
Clean the Site, or Rebuild It
Given a choice, rebuild. Download a fresh copy of WordPress from wordpress.org, fetch every plugin and theme again from its official source, and restore only two things: your wp-content/uploads folder (scanned first) and your content from the database. Recreate wp-config.php by hand with new credentials. Test on a staging copy, then point the domain at the clean installation.
If a rebuild genuinely isn't possible, cleaning in place means replacing core files, reinstalling every plugin and theme from source, deleting unknown files, and then editing the database directly to strip injected rows from posts, options, and user metadata. It works, but it is slower and easier to get wrong. When the database itself is heavily polluted, export your posts and pages, clean those, and rebuild the rest from scratch.
A site that looks clean is not the same as a site that is clean. The backdoor you deleted this morning is rarely the only one.
Rotate Credentials, Then Audit Users and Plugins
Assume every password the site has ever used is known to someone else. Work through the list methodically:
- WordPress admin passwords for every account, including the old ones you forgot about
- The database user's password, with the matching update in wp-config.php
- Hosting control panel, SSH, SFTP, and any FTP accounts — delete FTP accounts you don't use
- WordPress security salts in wp-config.php, which signs every user out
- API keys stored in wp-config.php or plugin settings: payment processors, mailing services, CDNs, backup tools
Anything that shared a password with your WordPress login needs changing too. Password reuse is the single most common reason a cleaned site gets hit again within a fortnight.
Now remove the weapons. Delete plugins and themes you don't recognize, replace any nulled or pirated plugin with a licensed copy, and retire abandoned plugins that no longer receive updates. Then open the users list and remove every administrator you cannot personally account for, including accounts created by a former developer.
Harden the Site So It Stays Clean
Once the site is clean, make the next attempt expensive:
- Turn on automatic updates for core and for plugins you trust, and delete anything unused
- Enable two-factor authentication for all administrator accounts
- Add login attempt limiting, and restrict access to wp-admin by IP if that suits your workflow
- Set DISALLOW_FILE_EDIT in wp-config.php so nobody can edit theme code from the dashboard
- Disable XML-RPC if nothing on the site depends on it
- Run a currently supported PHP version and let your host patch the server stack
- Use file permissions of 644 for files and 755 for directories, with wp-config.php locked down further
- Keep offsite backups and prove you can restore one
- Add file integrity monitoring through a security plugin or a host-level tool, and keep a staging site for testing changes
After the Cleanup: Proving You're Clean
Cleaning the site is only half the job. Tell Google and Bing through their webmaster tools, review any security warnings in Search Console, and submit a reconsideration request once the malware is gone. Check that your domain is no longer listed as unsafe by the major browsers.
Keep your forensic copy for a few weeks, and watch the access logs for repeat probes from the same addresses; attackers often come back to check whether their shell survived. Give it two quiet weeks before you relax.
Finally, be honest about your limits. If this is a store, a membership site, or a client's livelihood, an incident response specialist or a reputable WordPress security firm is money well spent. Restoring the site is the easy part. Knowing it is genuinely clean is what you are paying for.
Photo: 3844328 / Pixabay


