How You Know Your WordPress Site Has Malware
WordPress malware removal starts with recognising the infection. Malware on WordPress almost never announces itself with a banner. You find out because Google slaps “This site may be hacked” under your title in search results, because Chrome throws a full-page red “Deceptive site ahead” warning at visitors, because a customer forwards you spam email sent from your domain, or because your search results suddenly show Japanese product listings you never wrote.
Paid cleanup services will happily charge you $150–$500 to fix this. Some cases genuinely need them — I will be honest about which at the end. But most WordPress infections are commodity malware that landed through an outdated plugin or theme, and the cleanup is methodical, not magical. If you can use a hosting file manager and paste commands into a terminal, you can do it yourself with free tools. This guide walks you through exactly that, step by step, verified against current official sources in October 2026.
Timeliness note: this week (18–19 October 2026), attackers used stolen UpdraftCentral cloud dashboard keys to install backdoor plugins on WordPress sites — around 99 different plugin names were observed. If you use UpdraftCentral, the fix is deleting those keys, not updating a plugin. Details in the Further Reading section; the rest of this guide still applies.
Before You Touch Anything: Contain the Damage
Do these three things before deleting a single file. They protect your visitors and give you a fallback.
- Back up the infected site. Yes, back up the infected site — files plus database. Label it clearly (“hacked-backup-2026-10-22”) and store it off the server. If cleanup goes sideways, you can restore; and a forensic copy is useful if the infection recurs and you want to see how it got in.
- Put the site in maintenance mode. A short maintenance message keeps visitors off while you work. Some hosts also offer a “pause site” option in the control panel. This stops the malware from infecting visitors’ browsers and stops Google indexing compromised content.
- Ask your host for help. Check whether your host has a malware scan and, crucially, whether they have clean backups and from which dates. Do not blindly roll back to a backup though: the vulnerability that let the attacker in may still be there, and you will be reinfected within days.
Step 1: Scan First So You Know What You’re Dealing With
Never delete files blind. Run two free scans to map the infection:
- Sucuri SiteCheck (sitecheck.sucuri.net) — free remote scan of a URL. It checks your visible pages for malware, blacklist status, and defacement. Important caveat: it can only see what a visitor sees. A clean SiteCheck result does not prove the server files are clean; server-side backdoors often show nothing on the surface.
- Wordfence Security (free plugin from wordpress.org) — installs in your dashboard and scans core, theme, and plugin files against official checksums plus a malware signature database. The free version includes the firewall and scanner; one honest caveat is that free users get new firewall rules and malware signatures on a 30-day delay compared to the paid tier.
Save both scan reports. They are your baseline for knowing when you are actually done.
Step 2: Lock the Attacker Out (Passwords, Rogue Users, Salts)
Malware often re-enters through the same stolen credentials or a rogue admin account it created. Handle this before the file cleanup:
- Change every password: all WordPress admin accounts, hosting control panel, FTP/SFTP, and the database password (update
wp-config.phpto match). - Remove unknown admin users. In the dashboard go to Users → All Users and delete any account you did not create. Attackers commonly create editor or administrator accounts with plausible names (in this week’s UpdraftCentral incident, names like
data-ops43and “Site Tools” were observed). - Shuffle the salts. If you have WP-CLI (most managed hosts and VPS setups do), run:
wp config shuffle-saltsThis regenerates all eight security keys and salts in
wp-config.php, which logs out every user and invalidates every session cookie — including any session the attacker is sitting on. - Turn on 2FA for your own admin account before continuing.
Step 3: Audit Core, Plugins, and Themes With WP-CLI Checksums
This is the fastest way to find which files were tampered with. WP-CLI compares your files against the official checksums from WordPress.org:
wp core verify-checksums
wp plugin verify-checksums --all
wp theme verify-checksums --all
These commands report two kinds of problems: “File doesn’t verify” (an official file whose contents changed — infected) and “File should not exist” (a file that is not part of the official package — very likely a dropper or backdoor). Do not delete or edit anything yet; just make the list.
Step 4: Replace the Infected Files With Clean Copies
For any core file that fails verification, replace the whole core rather than editing individual files:
wp core download --skip-content --force --version=$(wp core version)
The --skip-content flag leaves wp-content and wp-config.php alone, --force overwrites the existing files, and pinning --version= avoids accidentally upgrading WordPress to a version you have not tested.
For infected plugins and themes, reinstall from the official sources rather than deleting them, so you keep your settings and the official file structure:
wp plugin install <slug> --force
wp theme install <slug> --force
Replace <slug> with the plugin or theme’s directory name. The --force flag overwrites the existing files with fresh copies from WordPress.org.
Step 5: Hunt the Places Checksums Can’t See
Checksum checks only cover official packages. Attackers know this, so they hide in the spots checksums never look at:
wp-content/mu-plugins/— must-use plugins load automatically and do not appear in the normal Plugins list. Anything you do not recognise there goes.wp-content/uploads/— this folder should contain media files, not PHP. List every PHP file in it:find wp-content/uploads -type f -name "*.php"Open each one before deleting; a trusted plugin may legitimately drop a file here, but in most infections these are shells or mailer scripts. Delete what you cannot explain.
- Fake
.htaccessfiles. Check the site root.htaccessfor PHP code — if it contains any, replace it with the default WordPress block (WordPress regenerates this itself):# BEGIN WordPress <IfModule mod_rewrite.c> RewriteEngine On RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule> # END WordPressAlso look for
.htaccessfiles hidden insideuploads/,plugins/, andthemes/— any containing PHP, base64 blobs, or long obfuscated strings should be deleted. - Grep for backdoor signatures. Search your install for the classic red flags:
grep -rl --include="*.php" -e 'eval(' -e 'base64_decode' -e 'str_rot13' -e 'gzuncompress' wp-content/ | head -30Many hits will be legitimate (minified libraries use these too), so open each file and check whether the obfuscated code is actually malicious before deleting anything. When in doubt, compare against a fresh download of the same plugin.
Step 6: Clean the Database
Files are only half the infection. Common database hiding spots:
- Rogue users — check the
wp_userstable (or Users → All Users in the dashboard) again; attackers sometimes re-create accounts. wp_optionstable — search for injected<script>tags and for maliciouscronoption entries. Malware often plants fake cron entries (PHP snippets registered as scheduled tasks) so it re-infects the site on a schedule. Delete any cron entry you cannot trace to a real plugin.wp_poststable — search for spam links or scripts injected into post content.- Fake wp-cron events — if WP-CLI is available,
wp cron event listshows scheduled hooks; delete anything you do not recognise.
Always back up the database before deleting rows — one wrong delete in wp_options can take the site down.
Step 7: Check the Rest of the Hosting Account
The scanner report from your host is a starting point, not the full picture. Check every site on the account — old copies, staging sites, test installs in other folders. Abandoned WordPress installs are one of the most common entry points: the attacker gets into the forgotten test blog and pivots to the main site. Also scan for mailer scripts (unknown PHP files in the site root and uploads) if your host suspended the account for spam.
Step 8: Close the Door It Came Through
Skipping this step is why so many sites get “cleaned” and reinfected a fortnight later. After the site is verified clean:
- Update everything — WordPress core, every plugin, every theme. Then delete any plugins and themes you do not actively use, especially abandoned or “nulled” ones.
- Reset file permissions: files to
644, folders to755, and tightenwp-config.phpto600or640. - Disable file editing from the dashboard by adding
define('DISALLOW_FILE_EDIT', true);towp-config.php— this removes the plugin/theme editor, a common post-compromise modification vector. - Enable 2FA on all admin accounts and consider a firewall — the free Wordfence firewall or a host-level WAF.
- Schedule regular scans so the next infection gets caught early, and keep real backups you test-restoring at least once.
Step 9: Get Google to Lift the Warnings
If Google flagged the site, cleaning it does not automatically clear the warnings. In Google Search Console: go to Security & Manual Actions → Security issues, confirm every flagged issue is genuinely fixed, tick “I have fixed these issues”, click Request a review, and describe what was found and fixed. Only request a review when the site is fully clean — do not resubmit while a review is pending. Reviews typically take days for malware flags and longer for hacked-content/spam flags.
When to Skip the DIY Route and Pay a Professional
Be honest with yourself. Call a professional cleanup service if any of these are true:
- The database is encrypted or the site is held for ransom — do not negotiate or attempt recovery yourself.
- Malware keeps reappearing after two full cleanup passes, which usually means the entry point is somewhere you cannot find (server-level compromise, another site on shared hosting).
- The site is a client site or an e-commerce store where a missed backdoor means stolen card data — the liability is not worth saving the fee.
- You are not comfortable reading PHP well enough to distinguish a backdoor from a minified library. Deleting the wrong file costs more than the cleanup would have.
Further Reading & References
- WP-CLI checksum commands — core: https://developer.wordpress.org/cli/commands/core/verify-checksums/
- WP-CLI config shuffle-salts: https://developer.wordpress.org/cli/commands/config/shuffle-salts/
- Hardening WordPress (official): https://wordpress.org/documentation/article/hardening-wordpress/
- Patchstack — UpdraftCentral key compromise backdoors (Oct 19, 2026): https://patchstack.com/articles/updraftcentral-key-compromise-wordpress-backdoors/
- The Hacker News — attackers abuse UpdraftCentral keys (Oct 2026): https://thehackernews.com/2026/10/attackers-abuse-updraftcentral-keys-to.html
- Sucuri SiteCheck (free remote scan): https://sitecheck.sucuri.net/
- Wordfence Security (free plugin): https://wordpress.org/plugins/wordfence/
- How to enable and read the WordPress debug.log (useful when tracing infection behaviour): https://howtoshipit.online/wordpress-debug-log-guide/
- WordPress Cron is fake — disable WP-Cron and use real server cron (audit scheduled tasks for fake events): https://howtoshipit.online/disable-wp-cron-real-server-cron/
Last verified against official sources: 22 October 2026.



