Incident Response · Last verified 2026-05-17

WordPress Site Hacked: Recovery Guide (2026 Edition)

Your WordPress site is hacked. You're seeing pharmacy spam in the search results, or Google flagged it as deceptive, or there's an admin user in wp-admin you didn't make, or visitors on iPhones get redirected to scam landing pages. Whatever the symptom, use this cleanup path to preserve evidence, find the entry point, remove persistence, and validate the site before putting it back in front of users. It covers the 2026 pattern that includes CVE-2026-1492 and the usual mix of weak-password and stale-plugin compromises.

Confirm the breach before you change anything

Not every "hacked WordPress site" report is a confirmed compromise. Some cases are broken plugins, hosting issues, or stale Google warnings. Confirm before you start tearing things up. A 2026 compromise commonly looks like this:

Hidden admin users are the most reliable indicator right now. CVE-2026-1492 lets attackers register accounts that bypass the User Registration plugin's role restrictions. The accounts show up in wp_users but sometimes won't appear in the WordPress Users list because the malicious code overrides the pre_get_users filter. Read the CVE-2026-1492 self-check if you want the database query that catches these.

PHP files in wp-content/uploads/ are basically always web shells. WordPress never writes executable PHP to the uploads directory in normal operation. radio.php, wp-uploads.php, cache.php, random hex names. Those are payloads. Check it.

Modified wp-config.php or .htaccess. Pull them up against your last clean backup. Attackers love these two files because they're loaded on every request, which makes them ideal for redirect rules and PHP includes.

Pharmacy or SEO spam in your post content or meta tags. You start ranking for "viagra" or "casino" or "replica watches" out of nowhere. Sometimes Search Console flags it under Security Issues before you notice in the SERPs. Sometimes you get an email from a confused customer instead.

Mobile-only redirects. Site loads fine on your laptop, sends iPhone visitors to a scam page. This is a fingerprinting script that only fires on iOS or Android user agents. Always test from a real phone in incognito mode, not from your admin browser session.

Google blacklist warning. The full-screen red "deceptive site ahead" page. Once Google flags you, you have hours, not days, before organic traffic cratters. Move fast on this one.

Outbound spam from your server. Your hosting provider sends an abuse notice. Mail logs full of outbound mail you didn't send. The site is being used as a relay.

Step 1 — Take it offline if you can

For most small business sites, taking the site offline for a few hours during cleanup is cheaper than serving malware to your customers, getting Google-blacklisted, or having your IP added to spam blocklists. Two ways to do it.

If you can still log in to wp-admin, install WP Maintenance Mode or use Jetpack's built-in toggle. Public traffic sees a clean static page. Behind the scenes you have full access.

If you can't log in, drop an .htaccess rule at the top of your WordPress root that allows only your IP. Three lines, ten seconds, and the public side of the site is dark while you work.

The exception: if you're running a live e-commerce store mid-sale, or a B2B SaaS product where downtime kills the business, skip this and go to step 2. You'll just be cleaning a moving target. That's harder, but sometimes the math works out.

Step 2 — Snapshot before you change anything

Same rule as cPanel recovery. Preserve evidence first, change second. Two artefacts you actually need.

Full database export. wp db export pre-cleanup-backup.sql via WP-CLI is cleanest, or use the phpMyAdmin "Export → Custom → All databases" option if you don't have CLI access. This captures wp_users, wp_options, wp_posts, custom tables, everything you'll need to figure out what the attacker added.

Full file system backup of wp-content/, wp-config.php, and .htaccess. tar czf pre-cleanup-files.tar.gz wp-content/ wp-config.php .htaccess. Pull the archive to your laptop, not back to the server. The naming matters: in two weeks when you're checking whether the cleanup held, you'll diff a fresh snapshot against this one to see if anything new appeared.

Step 3 — Find the entry point

You can't keep them out if you don't know how they got in. Most WordPress incidents start from one of four entry points.

Vulnerable plugin or theme. CVE-2026-1492 is the headline this year but Wordfence and Patchstack publish weekly disclosures across dozens of plugins. Run wp plugin list --update=available and cross-reference active plugins against the Patchstack database. Anything red, that's almost certainly your entry point.

Reused or weak admin password. Drop your admin email into Have I Been Pwned. If your password leaked in any of the big breaches, that's the most likely path in. Brute-force tooling churns through breached passwords against every /wp-login.php on the internet.

Compromised hosting account. If your cPanel password or FTP creds leaked, the attacker didn't need to exploit WordPress at all. They had file system write access from above. If you're on cPanel, run the CVE-2026-41940 self-check in parallel.

Unremoved web shell from a previous incident. If your site was hacked before and someone "cleaned it up", the most common cause of the second hack is a shell that was left behind from the first one. This is exactly why we always replace core and plugins from scratch in step 5 instead of trying to pick out individual infected files.

Step 4 — Clean the database

Most WordPress malware lives partly in the database. The order I work through:

Audit wp_users for accounts you don't recognize. In phpMyAdmin:

SELECT ID, user_login, user_email, user_registered
FROM wp_users
ORDER BY user_registered DESC;

Read every row. Cross-check against wp_usermeta for any user with wp_capabilities containing administrator. If you find an admin you didn't create, delete the row in wp_users AND the wp_usermeta rows for that ID. Don't delete from the WordPress UI. Good attackers register hooks that recreate their account if you delete it that way.

Audit wp_options for malicious entries. Look for option_value containing base64_decode, eval(, gzinflate, or any long encoded blob. Suspicious option names I see often: wp_check_hash, active_plugins_updates, theme_check, anything that doesn't match the format used by core or legitimate plugins.

Audit wp_posts for spam injection.

SELECT ID, post_title, post_status FROM wp_posts
WHERE post_content LIKE '%viagra%'
   OR post_content LIKE '%cialis%'
   OR post_content LIKE '%casino%'
   OR post_content LIKE '%pharmacy%';

Add whatever spam keywords are relevant to your industry. The big sneaky one is invisible CSS-hidden links (search for style="display:none" or visibility:hidden in post content too).

Reset every administrator password via wp user update USERNAME --user_pass=XXXX. Then change the secret keys in wp-config.php (regenerate from the official salt generator). Changing the salts forces every other user to log in again, which kills any stolen session cookies.

Step 5 — Replace core, plugins, and themes

The cleanest move is to delete every PHP file under your WordPress root and re-upload from clean sources. Faster than auditing each file and gives you higher confidence that nothing nasty survived.

Re-download WordPress core from wordpress.org/download. Replace wp-admin/, wp-includes/, and the root PHP files.

Reinstall every plugin from wordpress.org/plugins or from your paid licence portal for premium plugins. Do not copy plugins from the old wp-content/plugins/ folder — that's how unremoved backdoors come back. Fresh download every time.

Reinstall the theme from the original distribution. If you have a child theme with custom code, audit every PHP file in it line by line, or restore from a known-good Git commit. The child theme is the place attackers most often hide a few lines of nasty code because they know you won't reinstall it.

Delete every PHP file under wp-content/uploads/:

find wp-content/uploads/ -name "*.php" -type f -delete

Generate a fresh wp-config.php using the salt generator and copy the database connection details over from the old one. Don't reuse the old file.

Regenerate .htaccess by going Settings → Permalinks → Save Changes. That forces WordPress to rewrite the file with the canonical default rules. Anything the attacker added gets blown away.

Step 6 — Validate before going public

Before you bring the site back online, prove the cleanup worked.

Run an external malware scan. Sucuri SiteCheck and VirusTotal URL scan are the third-party sanity checks. A clean report from both is what you want before flipping the site back on.

Test from a phone in incognito mode. Some malware only fires for non-logged-in or mobile visitors. Test in a state that mimics how your real customers see the site, not from your admin session where you're already authenticated.

Check Search Console → Security and Manual Actions → Security Issues. If a previous warning is still there, click "Request Review" only after you're confident the site is clean. Multiple failed reviews extend the penalty period.

Re-run the wp_users audit query 24 hours after your cleanup. Sometimes sleeper backdoors recreate the admin account on a delayed timer. If a new admin appeared overnight, the cleanup wasn't complete. Back to step 3.

Step 7 — Harden so it doesn't happen again

Recovery without hardening is just an invitation for round two. The non-negotiable list:

Two-factor on every administrator account. Two Factor or WP 2FA plugin, five minutes, done. About 60% of the WordPress hacks I look at would have been impossible with 2FA on the admin account.

Force strong passwords, minimum 14 characters. Force Strong Passwords plugin handles it. Your editors will complain. Hold the line.

Limit login attempts. Limit Login Attempts Reloaded blocks brute-force traffic at the WordPress layer. Higher-traffic sites should also rate-limit /wp-login.php at Cloudflare or the reverse proxy.

Disable file editing. Add define('DISALLOW_FILE_EDIT', true); to wp-config.php. One line, kills the theme editor as an attack surface. If an attacker steals an admin session cookie, they can't immediately drop a PHP payload through the UI.

Enable auto-updates for plugins and themes. WordPress 5.5 and up has per-plugin toggles in the Plugins page. The 28-hour median window between disclosure and in-the-wild attacks against new plugin CVEs makes manual patching a losing strategy for hobby sites and small businesses.

Subscribe to a vulnerability feed. Wordfence Intelligence, Patchstack, or our Active Threat Tracker all do this. The earlier you hear about a new disclosure affecting your stack, the better.

Put a WAF in front of WordPress. Cloudflare's free tier with the WordPress rule set, Sucuri's WAF, or Wordfence Premium all help. The free Cloudflare option is usually enough for sites under a few thousand visitors a day.

Off-host immutable backups. UpdraftPlus to S3, BackWPup to Backblaze B2, BlogVault — pick one and configure it. A backup that lives on the same hosting account as the site can be encrypted along with the site by a determined attacker.

Frequently asked questions

How long does WordPress recovery take?

For a single small business site, an experienced operator gets through steps 1 to 7 in 4 to 8 hours. Without prior experience, plan on 1 to 2 days. The work that slows people down is steps 4 and 5 — database surgery and clean-source reinstalls. Sites with custom themes or e-commerce data add complexity.

Can I recover without taking the site offline?

Possible but harder. You'll be cleaning a moving target. Acceptable middle grounds: maintenance mode for the public side while you keep admin open, or restrict public access to a single static page announcing maintenance. The full lock-down beats both if your business can absorb the downtime.

Will I lose SEO rankings?

Short-term yes if Google added a security warning. Recovery after a clean Search Console review is usually 1 to 4 weeks. The sites that lose rankings permanently are the ones that get re-hacked within 30 days because they skipped step 7. Ranking loss isn't from the hack. It's from the second hack.

Should I tell my customers?

If any customer data was potentially exposed (logins, emails, payment info) or your site was serving malware to visitors, yes. A short factual notice maintains trust much better than discovery from somewhere else later. Mandatory breach notification laws (GDPR, CCPA) have specific timelines if regulated data was involved — quick legal review is cheaper than the fine.

Can I just restore from backup and skip the cleanup?

Only if you have a backup from before the compromise and you've identified the entry point from logs. Otherwise restoring brings the vulnerability back along with the site, and you'll be hacked again in days. Step 7 is what protects the restore, not the restore itself.

I'm not technical. Can I do this myself?

Steps 1, 2, and 6 (offline, snapshot, validate) are doable by any site owner. Steps 3 to 5 need comfort with phpMyAdmin or SQL, FTP or SSH, and basic PHP file management. If those are unfamiliar, hire someone. Sucuri does this for $199 per site one-time. Wordfence Care is $490 per year ongoing. Our own WordPress recovery service walks the full playbook with you. Whoever you pick, do step 1 (offline) before help arrives.

Related guides

References

Wrap-up

A hacked WordPress site is recoverable if you follow the order: offline, snapshot, find the entry point, clean the database, replace core and plugins from scratch, validate, harden. The mistake almost everyone makes is jumping to "restore from backup" before they've worked out how the attacker got in. Restore brings the hole back along with the content, and the second hack happens within a week. If you'd rather hand it off, our WordPress recovery service takes the whole playbook. Whatever you do: don't pay any ransom, don't reuse old plugins, and don't restore without rotating credentials and patching the entry point.