A compromised WordPress site rarely announces itself. The owner does not find it — Google does, or a customer does, or the host suspends the account. By the time anyone looks, the interesting question is not whether the site is infected. It is how long it has been infected, and what else the attacker reached from there.
This is what these incidents actually look like from the recovery side, in the order you meet them.
It is almost never the password
Owners assume someone guessed a login. Occasionally true, and worth ruling out, but the common route is an outdated plugin with a known vulnerability. Not an exotic one — a published advisory, months old, with working exploit code circulating, against a plugin that was installed for one feature in 2021 and never touched again.
This is why "we have a strong password and a security plugin" is not a security posture. Neither addresses the actual entry vector, and a security plugin installed alongside twenty stale ones has increased the attack surface it was bought to reduce.
- Abandoned plugins — no update in two years, author unresponsive, still active on the site.
- Nulled or pirated premium themes and plugins, which frequently ship with the backdoor pre-installed. This is a substantial category and clients rarely volunteer it.
- File upload handlers that do not validate what was uploaded, in forms nobody remembers adding.
- A stale PHP version the host stopped patching, usually kept because an old plugin breaks on anything newer.
What actually changes
Once in, the pattern is consistent enough to be a checklist. The goal is almost never to damage the site — a defaced site gets fixed. The goal is to keep using it.
| Where | What to look for |
|---|---|
| Uploads directory | Executable files where only media should exist. An uploads folder should never contain anything the server will run. |
| Theme and plugin files | Obfuscated payloads appended to legitimate files — often at the very end, past hundreds of blank lines so a casual scroll misses them. |
| Core files | Modifications to files that ship with WordPress. These should match the distribution byte for byte, which makes them the easiest place to detect tampering. |
| Database | Injected content in posts and options, and administrator accounts that nobody created. |
| Scheduled tasks | Cron entries that reinstate the payload. This is the one that undoes an otherwise clean recovery. |
| Server config | Redirect rules that serve different content to search engines than to logged-in visitors. |
Persistence is the part people miss
Any competent compromise installs more than one way back in. This is why the most common outcome in this work is not a failed cleanup — it is a cleanup that appears to succeed and is re-infected within days, at which point the owner concludes the attacker is still actively watching them. Usually nobody is watching. A scheduled task ran.
The mechanisms recur: a cron entry that rewrites the payload, a second backdoor in a directory nobody thought to check, an extra administrator account, a rogue application password or API key that survives a password reset, and an SSH or FTP credential added at the host level entirely outside WordPress. Miss any one and the site comes back infected while you are still writing the report.
Why "clean it" is the wrong instinct
The instinct is to remove the malicious code and carry on. It is the wrong instinct, for a reason that is uncomfortable rather than technical: after a compromise you cannot prove what else was changed. You can prove what you found. Those are different claims, and only one of them is honest to give a client.
So the approach is rebuild rather than disinfect. Fresh WordPress core from source. Plugins and themes reinstalled from their originals, never copied across from the compromised install. The database migrated with content reviewed rather than trusted wholesale. Uploads copied across with anything executable stripped. What you keep is content; what you rebuild is everything that runs.
It takes longer and it is harder to sell than a two-hour cleanup. It is also the only version where the answer to "are you certain it is gone" is yes.
The recovery sequence
- Take the site offline or behind maintenance mode. Every hour it serves malware to visitors compounds both the reputational and the search damage.
- Preserve a forensic copy before touching anything — full file archive and database dump, stored separately. You will need it to determine scope, and once you start cleaning, the evidence is gone.
- Establish the window. Modification timestamps and access logs give you roughly when it started, which determines what data was exposed and therefore what has to be disclosed.
- Rebuild on clean infrastructure rather than in place, so a missed backdoor on the old host cannot follow you.
- Rotate everything: all administrator passwords, database credentials, hosting and FTP and SSH access, API keys, application passwords, and any credential that was ever stored in the site config.
- Patch the entry vector before going live. Restoring a clean site onto the same vulnerable plugin buys you a few days.
- Request review through Google Search Console if the site was flagged, and monitor for re-infection daily for the first fortnight.
What prevents the next one
Very little of it is exciting. Updates applied on a schedule rather than when someone remembers. Plugins audited annually and removed when unused, because every one you keep is a permanent liability for a feature you may no longer use. Administrator accounts limited to people who need them and removed when they leave. Backups stored off the host and, more importantly, restored occasionally to prove they work. File integrity monitoring so core changes raise an alert the same day rather than the same quarter.
The honest framing for a client is that none of this makes a site un-hackable. It changes the compromise from a fortnight of recovery and an awkward disclosure into an alert and an afternoon.
Time between infection and detection on the incident this was written from
From the log analysis. The gap between compromise and discovery is the single most persuasive number in this piece.
Number of separate persistence mechanisms found in that recovery
Backdoors, cron entries, rogue admin accounts and credentials, counted. Makes the "cleanup is not enough" argument concrete.
You can prove what you found. You cannot prove what you missed. That asymmetry is the entire argument for rebuilding rather than cleaning.