futr
Security · WordPress · Forensics · Malware · Recovery · Incident response · from Client maintenance work

Anatomy of a WordPress compromise

How these infections actually get in, what they change, how they persist through a cleanup — and why the honest recovery is a rebuild rather than a disinfection, because you can prove what you found but never what you missed.

Published 2026-08-12 · 9 min read

Image · insight-wordpress-compromise · 16:9

Lead image for “Anatomy of a WordPress compromise”. Prefer a real artefact over an illustration — a screen, a diagram, a terminal, a rendered frame from the build being described. Dark ground, one accent, no stock metaphors.

Save as /public/img/insight-wordpress-compromise.webp

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.

WhereWhat to look for
Uploads directoryExecutable files where only media should exist. An uploads folder should never contain anything the server will run.
Theme and plugin filesObfuscated payloads appended to legitimate files — often at the very end, past hundreds of blank lines so a casual scroll misses them.
Core filesModifications to files that ship with WordPress. These should match the distribution byte for byte, which makes them the easiest place to detect tampering.
DatabaseInjected content in posts and options, and administrator accounts that nobody created.
Scheduled tasksCron entries that reinstate the payload. This is the one that undoes an otherwise clean recovery.
Server configRedirect 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

  1. Take the site offline or behind maintenance mode. Every hour it serves malware to visitors compounds both the reputational and the search damage.
  2. 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.
  3. 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.
  4. Rebuild on clean infrastructure rather than in place, so a missed backdoor on the old host cannot follow you.
  5. 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.
  6. Patch the entry vector before going live. Restoring a clean site onto the same vulnerable plugin buys you a few days.
  7. 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.

Figure outstanding

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.

Figure outstanding

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.

Think you have been compromised?

Take a full file and database copy before you touch anything — that evidence disappears the moment cleanup starts. Then talk to someone. If it is us, we will tell you honestly whether it needs a rebuild or an afternoon.

Four ways in

However you prefer.

Marine and yacht enquiries go straight to a named senior contact, and nothing is published without permission.