WordPress Security

Removing WordPress malware, and proving it is gone

Cleaning a WordPress site is the easy half. The half that decides whether it comes back is verification — and on WordPress there is a specific list of places a clean-looking site still hides code.

The problem

The site looks clean and is not

WordPress malware is designed to survive its own removal. A scanner that finds a modified theme function removes the visible symptom, and the persistence mechanism — an injected option, an unexpected administrative account, a scheduled task, a drop-in that loads before WordPress itself — stays behind and re-establishes the compromise days later. The recurrence is what tells you the first removal was incomplete.

  • The site redirects visitors to spam or third-party destinations
  • Search results show unrelated text or pages appearing in the index
  • Hosting or a search engine has flagged the site as compromised
  • A scanner reported the site as clean and it was compromised again within weeks
  • Unexpected files, plugins or themes appeared and nobody installed them
  • Administrative accounts or scheduled tasks exist that nobody recognises
  • The site is slow or sends traffic you cannot account for
  • A previous removal fixed the visible symptom and not the cause
Who this is for

The people who usually bring us this problem

Someone whose WordPress site is actively compromised

You need it cleaned and you need to know the removal was complete rather than hopeful.

Someone whose site was cleaned and reinfected

The first removal missed a persistence mechanism, which is the most common reason for recurrence.

Someone who has to demonstrate the site is clean

A host, a search engine or a security review needs evidence, and a scanner report is not evidence that the mechanism is gone.

What it costs

What this costs while it goes unfixed

Engineering faults are rarely confined to the engineering layer. These are the commercial consequences we see most often.

WordPress has specific places to hide code, and they are enumerable

That is the good news and the whole method. Core files are checkable against official checksums, plugin and theme files against their distributed versions, and the database, drop-ins, scheduled tasks and user table each have a defined shape to inspect. A generic cleanup does not know these places exist.

Removing the symptom is not removing the mechanism

The injected redirect and the persistence mechanism are often separate. Delete the first and the second replaces it, usually within days. This is why a site can be reported clean and be compromised again, and why verification is the part that determines the outcome.

The entry point is still open until you find it

Malware arrives through something: an outdated plugin, a weak or reused administrative password, a compromised hosting account, a vulnerable dependency. Cleaning without identifying the entry point leaves the door open, and the next compromise does not need to find a new way in.

A removal that breaks the site is a second problem

WordPress sites carry custom themes and plugins, and aggressive removal can take the site down or silently break a feature nobody checks for weeks. Removal has to distinguish injected code from legitimate customisations.

What we do about it

Capabilities

Each of these is work we carry out, not an area we advise on.

Core file integrity against official checksums

Every WordPress core file compared against the checksums WordPress publishes for that exact version. This is the fastest way to establish what is original and what is not, and it is a mechanical check rather than a judgement call.

Plugin and theme file integrity

Plugin and theme files compared against their distributed versions where the versions are known and unmodified. For commercial and custom components where no public checksum exists, files are examined directly for injected patterns and unexpected execution.

Database inspection

The content tables for injected scripts, links and hidden text, and the options table for entries that load code or register unexpected behaviour. Malware that lives only in the database survives every file-level clean.

Administrative account and permission review

Every account with administrative capability, its creation time and its authorisation. Compromise almost always creates its own access, and it is usually an ordinary-looking account rather than an obviously named one.

Scheduled task review

WordPress scheduled events are stored in the database and can be registered by anything. An unexpected task is a persistence mechanism with a legitimate-looking name, and it is one of the most commonly missed.

Drop-in and must-use plugin inspection

`mu-plugins`, `object-cache.php`, `advanced-cache.php` and the other drop-ins load before ordinary plugins and are frequently overlooked. They are also among the most effective places to hide, precisely because a plugin list does not show them.

Server configuration and access log review

The web server's configuration and the access logs, for the request that got in, the requests that followed, and any configuration the compromise altered. The entry point is usually visible here once you know what to look for.

Entry point identification and closure

Establishing how the compromise happened and closing it — updating the component, rotating the credential, correcting the permission — so that the removal does not end with the same exposure it started with.

Remediation verification and handover

A documented account of what was found, what was removed, what was changed, and what was checked afterwards — with the specific checks named, so the claim of cleanliness is auditable rather than assertive. Search-engine and host reconsideration requests are handled where required.

How we work

Engineering methodology

The sequence is deliberate. The order is usually what determines whether the work holds or has to be repeated.

  1. Contain before investigating

    Credentials rotated and the entry point closed to the extent it can be found quickly, so the site is not being re-compromised while it is being examined. Analysis on a moving target wastes the analysis.

  2. Work from a known copy, not the live site

    Examination happens on a copy, so the live site keeps serving and nothing investigated is disturbed. It also means a removal can be validated before it reaches production.

  3. Establish the original baseline first

    Core checksums, known-good plugin versions, a list of legitimate customisations and the expected administrative accounts — decided before removing anything. Without a baseline, every judgement about what is suspicious is a guess that can delete a working feature.

  4. Distinguish injected code from customisation

    A custom theme contains code no checksum covers, and it is supposed to. Removal has to tell the difference, which is why the baseline comes first and why this step is where careless cleanups do damage.

  5. Check every hiding place, not the ones that found something

    Files, database, accounts, scheduled tasks, drop-ins, server configuration. A compromise often has more than one presence, and stopping at the first finding is how a reinfection is arranged.

  6. Verify against the same list that found it

    The verification checks are the detection checks, re-run after removal. If the list is good enough to find the problem it is good enough to confirm its absence — and a different, weaker check afterwards proves nothing.

  7. Say what was checked, and what was not

    The handover names the specific checks performed. Where something could not be established — an entry point nobody can evidence, a component with no known-good version — that is stated rather than smoothed over, because the reader is relying on this document to decide whether the site is safe.

Deliverables

What an engagement produces

Documentation is a deliverable, not an afterthought. On most of these engagements a large part of the value is a defect report precise enough for another team to act on.

Assessment

  • What was found, where it was, and what it was doing
  • The identified entry point, or a clear statement that it could not be established
  • Every location checked, listed explicitly
  • Which findings are definitely malicious and which need a decision because they may be customisation
  • What the compromise exposed, including whether member or customer data was reachable

Remediation

  • Removal from files and from the database, not one or the other
  • Administrative accounts, permissions and scheduled tasks corrected
  • Entry point closed
  • Legitimate customisations preserved
  • Staged so the live site is not taken down unnecessarily

Verification and handover

  • Detection checks re-run after removal, with the results
  • Confirmation that the site functions correctly after removal
  • Search-engine and host reconsideration requests where required
  • A written account of what was checked, what was not, and why
  • The exposure assessment, if one was produced
Under the hood

Architecture and technology

Where WordPress hides code

  • Core files, checkable against the official checksums for the version
  • Plugin and theme files, checkable against their distributed versions
  • The database: content tables for injected output, options for behaviour
  • Administrative accounts created by the compromise
  • Scheduled tasks registered in the database
  • Drop-ins: `mu-plugins`, `object-cache.php`, `advanced-cache.php`
  • Web server configuration and `.htaccess`-equivalent rules
  • Uploaded files that are not images

Common entry points

  • An outdated plugin or theme with a published vulnerability
  • Reused or weak administrative credentials, including from a breach elsewhere
  • A compromised hosting or control-panel account
  • A nulled or unlicensed plugin carrying its own payload
  • A vulnerable dependency bundled inside a legitimate plugin
  • Server software left unpatched while WordPress itself was kept current
Adjacent problems

If this is not quite your problem

These overlap at the edges. Sending you to the right page is more useful than having you work it out.

The compromise was not WordPress-specific

The general recovery discipline: containment, eradication, verification and restoration.

Hacked website recovery

You want this not to happen again

Preventive hardening: update discipline, access control and the checks that catch it early.

WordPress security hardening

Search visibility was affected

What to do when a compromised site has lost rankings or been removed from results.

SEO traffic recovery

The wider security position

Assessment, edge protection and a remediation order across the whole estate.

Website security
Questions

Frequently asked

A scanner says the site is clean but it was reinfected. How?

Almost always because the removal took out the visible symptom and not the persistence mechanism. The injected redirect and the thing that recreates it are separate, and scanners are much better at the first than the second — particularly where the mechanism is a database option, a scheduled task or a drop-in rather than a file. Reinfection after a reported clean is the single most common reason we are brought in, and it means the previous pass did not cover the whole list.

Will you take the site offline to clean it?

Examination happens on a copy, so the live site normally keeps serving while the work is done. The removal itself is staged and applied when it is validated. Where a compromise is actively harming visitors — redirecting them to malicious content, for instance — taking the site down briefly is the responsible choice, and that is a decision we will put to you rather than make quietly.

Can you guarantee the site will not be compromised again?

No, and we will not put it that way. What can be said precisely is that we check every enumerated location, close the entry point we can identify, and name exactly what was checked in the handover so the claim is auditable. If the entry point cannot be established, that gets said too. Preventive work reduces the chance of recurrence substantially; nothing reduces it to zero, and a provider who says otherwise is selling reassurance rather than work.

Do you need access to the hosting account?

For a complete removal, yes — or cooperation from whoever holds it. Core and plugin integrity, database inspection and scheduled tasks can be reached through WordPress, but the web server configuration, the access logs that usually reveal the entry point, and the hosting account itself are outside it. A removal that stops at the WordPress layer can be thorough and still leave the actual way in open.

Should we restore from a backup instead?

Only if you can establish that the backup predates the compromise, which is harder than it sounds — compromises often run quietly for weeks before the visible symptom appears. Restoring a backup that contains the compromise and then rebuilding rather than examining loses the entry point, the exposure assessment and the record of what was changed. Where the backup is verifiably clean and recent, it can be the faster route, and we will say so if that is the case.

Bring us the problem you have not been able to fix

Describe what is happening rather than what you think the cause is. If we are not the right people for it, we will say so.