Why WordPress Malware Keeps Coming Back After Cleanup
⚡ Tired of cleaning the same site over and over? If your WordPress malware keeps coming back despite multiple cleanup attempts, you’re missing the persistence mechanism. Get professional malware removal — I find what scanners miss. Otherwise, this guide covers all 8 reinfection causes I see across thousands of cleanups.
You cleaned the malware. Maybe twice. Maybe five times. The site looks fine for a few hours, then the same redirects, spam pages, or infected files come right back.
You’re not going crazy. You’re not dealing with a brand new attack each time. You’re dealing with persistence — a hidden mechanism the attacker left behind specifically to survive your cleanup attempts.
I’ve cleaned over 4,500 hacked WordPress sites, and reinfection is the single most common reason clients hire me after a failed DIY cleanup. The pattern is always the same: someone removes the visible malware (the easy part), but misses the persistence layer (the part that actually matters). This guide walks you through every reinfection mechanism I’ve encountered, in priority order.
📋 Quick Diagnosis: 8 Causes of WordPress Reinfection
- Hidden cron job regenerating malware on schedule
- Active backdoor file the cleanup missed
- Hidden admin user still in the database
- Compromised access credentials (FTP, hosting, DB) that weren’t rotated
- Modified core files that weren’t replaced
- Malicious code in the database (not just files)
- Infected sibling sites on the same hosting account
- Vulnerable plugin/theme still installed (original entry point)
Most reinfection cases involve 2 or more of these simultaneously.
How to Tell You’re Dealing With Reinfection (Not a New Attack)
The pattern is recognizable once you know what to look for. You’re dealing with reinfection — not a fresh new hack — if any of these apply:
- The same malicious file returns after you delete it (sometimes within minutes, sometimes within hours)
- Spam pages reappear in Google search results after you removed them
- The same redirect destination keeps coming back, even with different file names
- Your security scanner reports clean, but Google or visitors still see infected behavior
- Your host suspends the account again shortly after you reactivate it
- New admin users keep appearing even after you delete them
- File timestamps keep changing on files you haven’t touched
- The infection follows you across hosting moves (rare, but possible if you moved infected files)
If you’re not sure whether the site is actually compromised again or just showing cached results, run through my WordPress malware detection guide first to confirm.
The 8 Reasons WordPress Malware Keeps Coming Back
I’ve ranked these by how often they’re the actual culprit in real cleanups. If you’ve already eliminated #1, move to #2, and so on.
1. A Hidden Cron Job Is Regenerating the Malware
This is the #1 reinfection cause I find — easily 60–70% of repeat infections. The attacker installed a scheduled task that automatically re-downloads or re-creates the malware on a timer. Delete the file, and the cron job restores it within minutes.
How to spot cron-based reinfection:
- Malware returns at predictable intervals (every minute, every hour, every day at the same time)
- Files reappear with the same content even after thorough cleanup
- Your hosting provider’s logs show repeated outbound connections to suspicious domains
Where to look:
- cPanel users: Cron Jobs section — look for any job containing
eval,base64_decode, orgzinflate - VPS/SSH users: Run
crontab -lfor your user, thensudo crontab -u www-data -lfor the web server user - WordPress users: Install WP Crontrol plugin and inspect WP-Cron events for unfamiliar hooks
Cron-based reinfection is so common and technically interesting that I’ve written a complete deep-dive on it. If your symptoms match this pattern, see my hidden cron job hack explained for the full removal process and a real malicious cron command analysis.
Real example from my client work: how I stopped cron-job malware that was generating 12,000 casino spam posts.
2. An Active Backdoor File the Cleanup Missed
Sophisticated attackers leave multiple backdoors specifically so you’ll find one and miss the others. I commonly find 5–15 backdoor files on heavily compromised sites — and the cleanup only caught 2 of them.
Where backdoors hide that DIY cleanups miss:
/wp-content/mu-plugins/— Must-Use plugins folder. Files here auto-load on every page load. Most site owners don’t even know this folder exists. Note: some legitimate hosts use this folder, so verify before deleting/wp-content/uploads/— PHP files disguised as images (.jpg.php,.png.php) or just plain.phpfiles. No legitimate WordPress site has PHP files in uploads. See how malware hides in JPG files- Theme files — Especially
functions.phpof your active theme. See the ghost admin hack in functions.php - Renamed legitimate files — A file called
wp-confg.php(note typo) orwp-includes/class-wp.php(looks legitimate, isn’t) - Modified
wp-config.php— Code added at the top before WordPress loads, or at the bottom after it loads - Modified
.htaccessat various directory levels — see my htaccess malware removal guide
How to find missed backdoors:
If you have SSH access, this single command catches 90% of PHP backdoors:
# Find PHP files in uploads (these should NOT exist)
find ./wp-content/uploads/ -name "*.php"
# Find files with malware signatures
grep -rnw './wp-content/' -e 'eval(' --include="*.php"
grep -rnw './wp-content/' -e 'base64_decode(' --include="*.php"
# Find recently modified files (last 7 days)
find ./wp-content/ -name "*.php" -mtime -7
For the comprehensive backdoor hunting process, see how hackers hide backdoors in WordPress.
3. A Hidden Admin User Is Still Logging In
Sometimes the “malware” isn’t a file at all — it’s a user account. The attacker created an administrator for themselves, hid it from your dashboard view, and logs in nightly to reinfect the site. Every cleanup is undone by the next login.
Critical insight: Sophisticated malware can hide users from the WordPress Users screen while keeping them fully active in the database. You can’t trust the dashboard alone.
How to find hidden admins:
- Open phpMyAdmin via your hosting control panel
- Select your WordPress database
- Open the
wp_userstable (your prefix may differ — could bewpxx_users) - Look for users that:
- You don’t recognize
- Have suspicious email domains (random Gmail addresses, ProtonMail, mail.ru)
- Were registered on dates you weren’t actively managing the site
- Have usernames like
wp-support,admin123,adminbackup, random numerics
- Cross-check with
wp_usermetatable — admins havewp_capabilitiesset toa:1:{s:13:"administrator";b:1;}
For the complete database-level user hunt, see how to find and remove hidden admin users in WordPress. Also useful: the admnlxgxn user pattern.
4. You Only Changed Your WordPress Password (Not Everything Else)
This is the cleanup mistake I see most often. Site owners change their WordPress admin password and assume they’ve locked the attacker out. They haven’t.
Most attackers maintain access through multiple credential paths. They might have your FTP credentials, your hosting/cPanel password, your database password, your email account (which can reset everything else), or your Cloudflare account. Changing only WordPress is like locking the front door while leaving five windows open.
What you must rotate after a hack:
- WordPress admin passwords (every admin user, not just yours)
- Hosting/cPanel/Plesk control panel password
- FTP and SFTP credentials
- SSH credentials and SSH keys
- Database password (update
wp-config.phpafter changing) - Email accounts that can reset other passwords
- Cloudflare or DNS provider account
- CDN account if separate from your host
- Any third-party service connected via API keys (Stripe, Mailchimp, etc.)
Critical step: Reset WordPress salts. Even with new passwords, existing logged-in sessions remain valid. Generate new salts at api.wordpress.org/secret-key/1.1/salt and replace the matching lines in wp-config.php. This instantly invalidates every active session, including hacker sessions.
Real example of credential-based reinfection: e-commerce DNS hijack via compromised Cloudflare account.
5. Modified Core Files You Didn’t Replace
Your cleanup might have removed obvious malware files but left modifications to legitimate WordPress core files. Files like wp-load.php, wp-blog-header.php, or files inside wp-includes/ can have malicious code injected into them — code that executes on every page load.
The fix: Don’t try to clean modified core files line-by-line. Replace them entirely:
- Download fresh WordPress from wordpress.org
- Delete your existing
/wp-admin/and/wp-includes/folders - Upload the fresh versions
- Replace root PHP files (
index.php,wp-load.php,wp-blog-header.php, etc.) - Don’t delete
/wp-content/orwp-config.php
This eliminates roughly 80% of file-based persistence in one pass. Real example: how I stopped regenerating malware that kept rewriting wp-blog-header.php.
6. The Real Payload Is in the Database, Not Files
Some of the most frustrating reinfection cases I see involve sites that scan completely clean at the file level — but visitors still get redirected, Google still shows spam pages, or hidden links still appear in search results.
The reason: the malware lives in your database, not your files.
Where database malware hides:
wp_optionstable — Especially theactive_plugins,siteurl,home, and any autoloaded options. Search forbase64_decode,<script, or unfamiliar URLswp_poststable — Hidden spam content, injected scripts, hidden CSS spam (display:none,position:absolute,left:-9999px)wp_postmetatable — Custom field injectionswp_usermetatable — Privilege escalation, custom capabilities- Custom plugin tables — Some plugins create their own tables, which malware can exploit
For comprehensive database cleanup, see how to scan and clean WordPress database for hidden malware. For a real case where database malware caused failed Google review requests, see failed Google blacklist request hidden database malware.
7. Another Site on the Same Hosting Account Is Infected
This one gets missed constantly. If you have multiple WordPress sites under one cPanel account, an old staging copy, an abandoned subdomain, or a forgotten dev install — the malware can reinfect your main site from any of them.
Shared hosting plans often allow file-level access between sites in the same account. Malware on oldsite.com sitting in the same hosting account can write files to yoursite.com. You clean the main site, but the infected sibling site reinfects it within hours.
What to audit on the same hosting account:
- Every domain hosted under the account
- Every subdomain (especially old ones you forgot about)
- Staging sites (
staging.yoursite.com,dev.yoursite.com) - Old WordPress installs in subdirectories (
/old/,/backup/,/v1/) - Backups stored in web-accessible folders (download them off-site, then delete)
- Test installs that nobody remembers anymore
If reinfection makes no sense based on the main site alone, this is usually why.
8. The Original Vulnerability Is Still Present
Cleanup removes the malware. It doesn’t always patch the hole the attacker came through. If your initial entry was a vulnerable plugin and you cleaned the malware without updating that plugin, attackers exploit the same vulnerability and reinfect within hours of cleanup.
Common entry points that often go unpatched:
- Outdated plugins with known CVEs (most common)
- Outdated themes (especially nulled premium themes — see why nulled themes are a security nightmare)
- Outdated WordPress core (rare but happens)
- Vulnerable contact form configurations
- Misconfigured file permissions
- XML-RPC enabled with weak passwords
Critical step: Update everything immediately after cleanup. WordPress core, every plugin (active or inactive), every theme. Remove unused plugins and themes entirely. If you can’t update a plugin because it’s been abandoned, find a replacement.
The Permanent Reinfection Fix Workflow
If you’ve cleaned this site multiple times and it keeps coming back, surface-level scanning isn’t enough. Here’s the comprehensive workflow I run on every paid reinfection cleanup:
Step 1: Take a Forensic Backup of the Infected State
Before changing anything, back up the current state to your local computer (not the server). This gives you evidence, lets you compare files later, and protects against accidentally deleting something legitimate during cleanup.
Step 2: Lock the Site Down
Put the site in maintenance mode using SeedProd or a similar plugin. If actively redirecting visitors, restrict /wp-admin/ access to your IP only via .htaccess:
<Files wp-login.php>
Order Deny,Allow
Deny from all
Allow from YOUR.IP.ADDRESS.HERE
</Files>
Step 3: Rotate ALL Credentials (Not Just WordPress)
Cycle through the complete list from #4 above: hosting, FTP, SSH, database, email, Cloudflare, third-party APIs. Then reset WordPress salts to invalidate all sessions.
Step 4: Audit Cron Jobs First
Before doing anything else, check cron — both server-level cron and WP-Cron. If a malicious cron job exists, every cleanup step that follows is wasted effort until cron is clean. See the dedicated cron job malware guide.
Step 5: Replace Core Files
Delete /wp-admin/ and /wp-includes/, replace with fresh WordPress.org copies, replace root PHP files. Keep /wp-content/ and wp-config.php untouched.
Step 6: Audit Every Plugin and Theme
- Compare your
/wp-content/plugins/folder count against the dashboard count — extra folders are ghost plugins - Delete any plugin you don’t actively use
- Replace remaining plugins with fresh copies from official sources
- Same process for themes — only one active theme should remain
- Stop using nulled plugins/themes immediately
Step 7: Database Surgery
Open phpMyAdmin and:
- Audit
wp_usersfor hidden admin accounts (see #3) - Search
wp_postsfor<script,display:none,position:absolute,base64 - Search
wp_optionsfor unusual autoloaded values - Look at
wp_usermetafor unauthorized capability changes
Step 8: Hunt Backdoors with Grep
If you have SSH access, run the grep commands from #2 above. If not, manually inspect:
- Active theme’s
functions.php,header.php,footer.php - Files in
/wp-content/uploads/— there should be NO PHP files here /wp-content/mu-plugins/— verify each file is legitimatewp-config.php— check the very top and very bottom for added code- All
.htaccessfiles — check root,/wp-admin/,/wp-content/,/uploads/
Step 9: Audit Every Site on the Hosting Account
Don’t just clean the main site. Run the same audit on every domain, subdomain, staging copy, and forgotten install on the hosting account. One missed sibling site reinfects everything.
Step 10: Harden Against Future Attacks
After cleanup, implement these protections to prevent the next infection:
- Update WordPress core, all plugins, all themes
- Add
define('DISALLOW_FILE_EDIT', true);towp-config.php - Enable two-factor authentication on all admin accounts (2FA setup guide)
- Hide your login URL (change login URL guide)
- Install a security plugin for ongoing monitoring (Wordfence vs Sucuri comparison)
- Set up off-site automated backups (UpdraftPlus backup guide)
Step 11: Verify and Handle SEO Aftermath
Once clean, verify on multiple devices, browsers, and from logged-out sessions. If Google still shows warnings, request review through Search Console with detailed cleanup notes. If hacked spam URLs are still indexed, see 404 vs 410 for hacked URLs.
Useful follow-up resources:
- What to do after fixing a hacked WordPress site
- Google blacklist removal service
- Dangerous Site warning case study
Why a “Clean” Scan Doesn’t Mean a Clean Site
Here’s an uncomfortable truth: your security scanner reporting clean is not proof your site is clean.
I see this constantly. A site owner runs Wordfence, gets a green checkmark, and assumes everything’s fine. Meanwhile:
- Google still shows the site as flagged
- Visitors on mobile devices still get redirected
- Logged-out users see different content than logged-in users
- Search results still contain Japanese spam URLs
- Customers report seeing scam ads on the site
This happens because modern malware uses cloaking — it shows clean content to security scanners and admin users while serving malicious content to other visitors. Some malware only activates for traffic from Google, only on mobile devices, only in certain countries, or only after certain time delays.
If WordPress malware keeps coming back even though scanners say you’re clean, assume the investigation is incomplete and dig deeper. The cloaking detection guides that help here:
FAQ: WordPress Reinfection
Why does my WordPress malware keep coming back at the same time every day?
That’s almost always a scheduled reinfection — either WP-Cron or a server-level cron job re-downloading or re-creating the malware on a timer. If reinfection happens at predictable intervals, check cron jobs first using cPanel’s Cron Jobs section, crontab -l via SSH, or the WP Crontrol plugin. See my complete cron job malware guide.
Why does Wordfence say my site is clean if WordPress malware keeps coming back?
Security plugins detect known malware signatures, but they miss roughly 40% of modern malware. Common things they don’t catch: ghost plugins that hide from your dashboard, hidden admin users in the database, malicious code in wp_options, cloaked malware that shows clean content to scanners, and custom backdoors with no signature match. A clean scan is a positive signal, not proof.
How do I permanently stop WordPress reinfection?
Permanent fix requires addressing all 8 reinfection causes systematically: kill malicious cron jobs, find missed backdoors, remove hidden admin users, rotate every credential (not just WordPress), replace core files entirely, clean the database, audit sibling sites on the same hosting account, and patch the original vulnerability. Skipping any of these leaves a path back in.
Is it cheaper to clean my site or buy a new domain?
Clean the site. Buying a new domain doesn’t help if your hosting account is compromised — the new domain will get infected too. The malware lives on the server, not in the domain name. The only case where moving makes sense is if your IP address itself is permanently blacklisted across multiple vendors and your host can’t change it.
Can my hosting provider help with reinfection?
Most shared hosts (Bluehost, GoDaddy, HostGator) won’t actively clean malware — they’ll suspend the account and require you to clean it. Some managed WordPress hosts (Kinsta, WP Engine) offer cleanup as a paid add-on, but their cleanup is typically surface-level. For genuine reinfection cases, you usually need WordPress security expertise that goes beyond standard hosting support.
How long does it take to fix a reinfected WordPress site?
Reinfection cleanups take longer than first-time cleanups because you’re working against active persistence mechanisms. Simple cases (single cron job, easy to find): 2–4 hours. Complex cases (multiple persistence mechanisms, sibling site infection, database malware): 6–12 hours. The investigation phase is the longest part — you’re hunting for what your previous cleanup missed.
Should I restore from a backup instead of cleaning?
Only if your backup predates the original infection. Most reinfection victims don’t have a clean pre-infection backup, because they didn’t realize the site was infected for weeks or months. If you do restore, you must still patch the original vulnerability — otherwise reinfection happens again immediately. Test the restored backup on a staging site before going live.
What if my host suspended the account again after cleanup?
That’s a strong signal you missed the persistence mechanism. Hosts re-suspend accounts when their automated scans detect malware activity again. Contact your host for the specific files they detected, then dig into those areas. Often it’s a backdoor file or cron job they specifically flagged.
Get Help Finding the Persistence Mechanism
If you’ve cleaned this site twice and the malware keeps coming back, the next attempt by the same DIY approach won’t work either. The job at this point isn’t “scan again” — it’s finding the one persistence mechanism that survived your last cleanup.
That investigation is the part where most plugins fail and the part I do manually on every reinfection cleanup. I work through cron jobs, hidden users, ghost plugins, database injections, sibling site spread, and credential rotation systematically. Most reinfection cases I take on get fixed within 4–8 hours.
Stop the reinfection cycle
Get the deep investigation that finds what scanners and DIY cleanups miss.
→ Get Professional Malware Removal
Reinfection-proof cleanup · Fixed price · 4,500+ sites cleaned
If your reinfection is paired with Google warnings or a blacklist, also see my Google blacklist removal service. For a deeper dive into the most common reinfection cause — malicious cron jobs — see the hidden cron job hack explained.
About the author: Md Pabel is a WordPress security specialist with 7+ years of experience and 4,500+ successful site cleanups. He documents real-world reinfection investigations and persistence mechanisms at mdpabel.com.



