1 · The WordPress database
Encoded script content in options records — especially autoloaded values — executes on normal requests and survives every file-level cleanup and theme reinstall.
Guide · Reinfection
A site that is cleaned and reinfected — sometimes within days — is not unlucky. It means a persistence mechanism, an access path, or a neighboring compromise survived every cleanup so far. This guide covers the five places routine cleanups miss, and what breaks the cycle.
Published Last reviewed
The pattern
Every reinfection follows the same logic: the visible symptom was removed, and something that can restore it was not. Attackers build for exactly this — the code you can see is designed to be found and deleted while a quieter mechanism waits to rebuild it after the scanner declares victory.
Why the infection appears to come back
The visible symptom is identified.
The page may look normal for a while.
The database, theme, .user.ini, or attacker access remains.
A later request, restart, cache refresh, or deployment loads it again.
The five places
Encoded script content in options records — especially autoloaded values — executes on normal requests and survives every file-level cleanup and theme reinstall.
A .user.ini or php.ini auto_prepend_file directive loads a malicious file before WordPress starts. File scanners focused on WordPress rarely look here, and parent-directory settings can affect several sites at once.
mu-plugins, drop-ins (object-cache.php, db.php), the uploads directory, and cache folders all execute or feed PHP but sit outside what most scans review carefully.
A rogue administrator, an application password, a session that survived the password change, an SSH or SFTP key, or a deployment token lets the attacker simply reinstall after each cleanup — no backdoor file needed.
On shared accounts without isolation, another site under the same user can reinfect a perfectly cleaned one. Cleaning one site in a compromised account is repainting one room of a flooded house.
Also worth ruling out
Breaking the cycle
Timestamps, logs, and artifact structure identify what came first and what merely followed — evidence a delete-first cleanup destroys.
Files, database, theme, PHP configuration, scheduled tasks, and identities are each given an explicit trust decision, not just a scan pass.
Core, plugins, and themes are replaced from trusted sources; legitimate customizations are reconciled separately instead of trusting edited files.
The vulnerable component, exposed credential, or isolation gap that admitted the attacker is fixed — this step is the difference between cleanup and cycle.
Verification continues after caches expire, cron runs, and deployments execute — the exact moments earlier “clean” states collapsed.
Common questions
A rebuild helps only if the entry path is closed and every credential is rotated first. Rebuilt sites are routinely reinfected through the same vulnerable plugin, stolen credential, or compromised hosting account that caught the original.
It is necessary but rarely sufficient. Sessions, application passwords, SSH keys, and deployment tokens can all outlive a password change — and none of it matters while a backdoor still executes on the server.
Sometimes the account-isolation model contributes, especially when several sites share one user. But most reinfection cycles trace to surviving persistence or credentials, so blame the evidence, not the host, until the investigation says otherwise.
One reinfection after a genuine cleanup is already the signal: something structural survived. Each further cycle adds spam indexing, warning risk, and evidence loss, so the second incident is the economical time to investigate properly.