Why Your WordPress Site Keeps Getting Reinfected After Cleanup

By · Updated · 6 min read

When a website keeps getting reinfected after cleanup, it means something survived: a backdoor file the scanner missed, a password that never got rotated, a scheduled task quietly reinstalling the malware, an infected neighbor site in the same hosting account, or a backup that restored the infection along with your content. Malware does not come back on its own. Something is bringing it back, and the fix is finding that something.

Reinfection cases are a big slice of my work, and they arrive with a particular kind of exhaustion. The owner has cleaned the site once, twice, sometimes five times. Each time it looks fixed for a few days. Then the spam pages are back, or the redirect is back, and they're starting to wonder if the site is cursed. It isn't. It's just that cleanups which remove what's visible, without removing what's persistent, are really a subscription to more cleanups.

The cleanup wasn't the problem. The leftovers were.

A scanner-driven cleanup finds files that look like malware and deletes them. That handles the payload, the part doing the visible damage. It routinely misses the persistence: the small, boring-looking files and settings whose only job is to let the attacker back in later. The payload is the burglar's mess. The persistence is the spare key he cut while he was inside. Clean up the mess and leave the key, and you'll be cleaning again.

Backdoors: the spare key under the mat

The classic survivor is the backdoor, a small PHP file that accepts commands from outside. They hide in wp-content/uploads where nobody expects PHP at all, in abandoned themes, in mu-plugins (a folder many owners don't know exists), even pasted into the middle of a legitimate plugin file where a casual diff won't catch it. One backdoor is standard. Careful attackers plant several, in different styles, so a scanner that catches one signature misses the next.

Finding them takes more than one scan: it means comparing core files against clean originals, reading what's actually in the upload folders, and checking file timestamps around the infection dates. I wrote a full guide on finding and removing WordPress backdoors, because this single topic explains most reinfection stories I see.

Passwords nobody rotated

The second survivor is access itself. If the attacker had your passwords, and after the cleanup those passwords still work, then they don't need malware to return. They log in like you do. A real rotation covers every WordPress admin, the hosting control panel, FTP and SFTP accounts, and the database password in wp-config.php.

There's also a sneaky one people miss: WordPress application passwords. They live under each user's profile, they let anyone authenticate to the site's REST API without touching the login page, and attackers sometimes create one during a breach precisely because nobody thinks to look there. While you're at it, check for admin users you don't recognize, including ones with innocent names like wpsupport or a lookalike of your own username.

The cron job that reinstalls the malware

This one feels like a haunting until you find it. WordPress has a task scheduler, wp-cron, and attackers can register a scheduled job that re-downloads the malware every day, or every hour, from an outside server. Delete the bad files at noon, and at 1 p.m. the job politely puts them back. The same trick appears one level up as a server crontab entry in your hosting account, which survives even if you wipe WordPress entirely.

If your reinfections happen on a suspiciously regular rhythm, check the scheduled tasks in both places. The wp-cron entries can be inspected with a plugin like WP Crontrol; the server crontab is in your hosting panel. Anything fetching a remote URL you don't recognize deserves a hard look.

Persistence can live in the database too

Not every survivor is a file. Attackers also stash code in the WordPress database, most often in the wp_options table, where certain plugins and themes will happily execute stored PHP or inject stored JavaScript into every page. File scanners never see it, which makes it a perfect hiding spot. If your files are provably clean and the symptoms persist, the database is the next suspect: look for options with names that imitate real ones, script tags stored inside widget content, and recently changed rows you can't explain.

The neighbor site nobody checked

Most hosting accounts hold more than one site. The main site gets the attention and the cleanup; the old blog, the half-finished project, the staging copy from 2021 sit untouched in the same account, often sharing the same file permissions. If any of them is infected, the attacker can usually walk sideways into your freshly cleaned site within minutes.

This is called cross-contamination, and it's why the unit of cleanup has to be the hosting account, not the website. On my cleanups I inventory every install in the account, because I learned the alternative the hard way years ago: a spotless main site, and a forgotten subdomain reinfecting it every weekend.

The dirty backup problem

One more quiet culprit. If your site got infected in March and you've been restoring an April backup every time trouble shows up, you've been restoring the malware too, minus its visible symptoms. Backups made after the break-in contain the break-in. When a restore is part of your recovery, the restored copy needs the same inspection a live site would get, and your backup history is worth keeping long enough to reach back before the original infection date. My backup and recovery guide goes into what a trustworthy backup routine looks like.

How to break the loop for good

Here's the checklist I actually run when someone comes to me stuck in this cycle:

  • Find and remove every backdoor, by inspection and file comparison, not just by scanner signature.
  • Rotate every credential: WordPress admins, hosting panel, FTP, database, application passwords.
  • Audit users and delete any admin you can't account for.
  • Check wp-cron and the server crontab for jobs that fetch remote code.
  • Inspect every other install in the hosting account, active or abandoned.
  • Close the original entry point, usually an outdated plugin or theme, so the whole story can't restart.

When all six of those are genuinely done, reinfections stop. Not usually. Every time. In fourteen years I haven't seen a site keep relapsing after the persistence and the entry point were truly gone.

If you'd rather hand the whole loop to someone who does this daily, my Bulletproof Cleaning covers exactly this list, and I stand behind it. You can also run my free scanner right now to see what's currently visible from the outside. Either way, stop blaming yourself for the relapses. The site isn't cursed. Something survived, and it can be found.

Common questions

Why does malware keep coming back after I remove it?

Because removal only handled the payload, not the persistence. A hidden backdoor file, an unrotated password, a malicious scheduled task, or an infected second site in the same hosting account can each reinstall the malware after a cleanup. Find and remove the mechanism that's bringing it back and the reinfections stop.

Can malware survive if I reinstall WordPress?

Yes. Reinstalling core WordPress replaces core files only. Malware hiding in wp-content (uploads, themes, plugins, mu-plugins), in the database, in a server cron job, or in another site in the same account survives untouched. That's why fresh installs get 'mysteriously' reinfected: the fresh install moved back into an unclean house.

Do I really need to change every password?

Yes, and the list is longer than most people think: all WordPress admin accounts, the hosting control panel, FTP and SFTP, the database password in wp-config.php, and any WordPress application passwords. If the attacker kept even one working credential, they can return without using malware at all, and the cycle starts over.

Can another website on my hosting account reinfect mine?

Yes, and it's one of the most common causes I see. Sites in the same hosting account usually run under the same user, so an infected old blog or abandoned test install can write files straight into your cleaned site. Every install in the account has to be cleaned or deleted, or the clean ones keep getting recontaminated.

How do I find the backdoor on my site?

Look where scanners get lazy: PHP files inside wp-content/uploads, the mu-plugins folder, deactivated themes, and legitimate plugin files with recently changed timestamps. Comparing your files against clean copies of the same plugin and theme versions is the most reliable method. Attackers usually plant more than one, so keep looking after the first find.

Is it normal to get hacked twice in one month?

If the first cleanup missed the entry point or a backdoor, it's practically expected. Attackers' tools keep lists of sites they've compromised and revisit them automatically. Repeat hacks in quick succession almost always mean the same door is still open, not that you've been newly targeted a second time.