Skip to content
JS

Security

Your WordPress site got hacked: what to do first

Deleting the malware is the easy part — and the part that gets redone next week if you skip the rest. Here's the order that makes a cleanup stick.

Jose Sebastian6 min read

Almost every hacked site I'm asked to clean has been cleaned once already. Someone deleted the suspicious files, the site looked fine for four days, and then it came back.

It came back because deleting the payload doesn't close the door it came through. The cleanup that sticks spends most of its effort on finding the entry point, not on removing files.

Here's the order. Resist the urge to start deleting things — step 1 is the one you can't do later.

1. Take a copy before you change anything

Right now, before any cleanup, take a full copy of the files and the database and put it somewhere offline.

# Snapshot files and database exactly as they are
tar -czf hacked-snapshot-files.tar.gz /var/www/html
mysqldump -u dbuser -p --single-transaction wpdb > hacked-snapshot-db.sql

This feels like keeping the disease, and it's the most useful thing you'll do. It's your only record of how the attacker got in — the modified files, the injected admin user, the timestamps. Once you've cleaned, that evidence is gone and you're guessing.

Do not restore a backup yet either. If the compromise happened three weeks ago and your backups go back two, you'll restore the backdoor along with the site and conclude the cleanup failed. Find out when it started first.

2. Contain it

Stop the damage spreading while you work. In rough order of urgency:

  • Take the site offline if it's serving malware or redirecting visitors to a scam. A maintenance page is better for your reputation than a Google red screen. If it's just spam pages in search results, you can leave it up.
  • Disable public logins temporarily, or restrict wp-admin to your IP address at the host or firewall level.
  • Check for unknown admin users — Users → All Users, filter by Administrator. Attackers add one so they can return through the front door after you clean the files.
-- List every administrator, newest first
SELECT u.ID, u.user_login, u.user_email, u.user_registered
FROM wp_users u
JOIN wp_usermeta m ON m.user_id = u.ID
WHERE m.meta_key = 'wp_capabilities'
  AND m.meta_value LIKE '%administrator%'
ORDER BY u.user_registered DESC;

An admin account registered the same week the trouble started is your strongest clue about timing.

3. Find the entry point

This is the step that gets skipped, and it is the whole job. There are only a handful of ways in, and the logs usually name it.

Look at what changed and when. Files modified at 3am on a day you weren't working are the ones to read:

# Files modified in the last 14 days, newest first
find /var/www/html -type f -mtime -14 -printf "%TY-%Tm-%Td %TH:%TM  %p\n" \
  | sort -r | head -40

Then check the access logs around that timestamp. Your host provides these; look for repeated POST requests to a single file, or requests to files you don't recognise.

The four common entry points, in the order I find them:

Entry pointTell-tale sign
Outdated plugin or theme with a known exploitModified files inside one plugin folder; the plugin has a published CVE
Weak or reused admin passwordA successful login from an unfamiliar country in the logs, no file exploit needed
Nulled or pirated premium pluginThe backdoor was in the download from day one — it never needed an exploit
Compromised hosting or FTP credentialsFiles changed with no corresponding web request in the logs at all

That last row is worth reading twice. If files were modified and there's no matching request in the access log, the attacker didn't come through the website — they had your FTP or hosting password, and cleaning WordPress won't help.

4. Clean it properly

Now the removal, which is mostly replacement rather than editing.

  1. Replace WordPress core wholesale. Download a fresh copy of the matching version and overwrite wp-admin and wp-includes entirely. Never try to clean core files by hand.
  2. Reinstall every plugin and theme from source. Delete the folder, install fresh. Anything you can't reinstall from an official source — nulled plugins especially — delete and do without.
  3. Clean the database. Injected spam usually sits in wp_posts content, wp_options (look for suspicious entries near the top of the autoloaded options), and occasionally wp_users. Compare against your snapshot.
  4. Check the files WordPress doesn't own. .htaccess for injected redirect rules, wp-config.php for appended code, and the uploads folder for .php files — nothing in wp-content/uploads should ever be executable.
# PHP files hiding in the uploads folder are always suspicious
find wp-content/uploads -type f -name "*.php"

5. Rotate every credential, in the right order

Do this after the cleanup, not before. Change passwords while a backdoor is still live and you've just handed over the new ones.

Order matters:

  1. Hosting control panel and SSH or FTP accounts
  2. Database user password (then update wp-config.php)
  3. All WordPress admin passwords
  4. WordPress salts — replace the keys in wp-config.php from the official generator. This logs everyone out, including the attacker, invalidating any stolen session cookie.
  5. Any API keys stored in the site — payment gateways, mail services

Regenerating the salts is the step most cleanups miss. Without it, a stolen login cookie keeps working even after the password change.

6. Get the warnings removed

If Google flagged the site, cleaning it doesn't clear the warning automatically — you have to ask.

In Search Console, open Security & Manual Actions → Security Issues, confirm the issue is resolved, and request a review. Reviews typically come back within a few days. Ask once and wait; requesting again while one is pending doesn't speed it up.

Also check whether your domain landed on an email blocklist — a compromised site often spends its time sending spam, and the reputation damage outlasts the hack.

Then make it not happen again

The cleanup is worthless if the site is in the same state it was on day one. The baseline that prevents almost all of this:

  • Automatic updates on for WordPress core, plugins and themes. Most hacks exploit a vulnerability that was patched months earlier.
  • Delete what you don't use. An inactive plugin is still exploitable code sitting on your server.
  • Two-factor authentication on every admin account.
  • Backups you have actually tested restoring, stored somewhere that isn't the same server.
  • A web application firewall in front of the site — Cloudflare's free tier blocks a meaningful share of automated attacks.
  • Valid HTTPS, checked periodically — see the SSL checklist if the padlock is misbehaving.

What to do first

Take the snapshot. Everything else can wait an hour; the evidence can't, because the first cleanup attempt destroys it.

Then contain, investigate, clean, rotate. If you get through the investigation and genuinely can't tell how they got in, treat the hosting account itself as compromised — rebuild on a fresh server from known-good sources rather than cleaning in place.

And if the site is a live business and you'd rather not learn this under pressure, malware cleanup and hardening is something I do — including working out what went wrong, which is the part that decides whether it comes back.

Related reading

Tips3 min read

Your SSL certificate broke: a 5-minute checklist

Browser shouting about your certificate? Work through these five checks in order — it's almost always one of them, and four take under a minute.

Web Development3 min read

How to speed up a slow WordPress site (without breaking it)

Most slow WordPress sites share the same four causes. Here's how I diagnose them, in the order that finds the problem fastest.

Hosting6 min read

How to move a website to a new host without downtime

A host migration goes wrong in the same three places every time. Do the steps in this order and visitors never see a broken site.

Need a hand with something like this?

I work with businesses in Dubai and remotely worldwide on websites, SEO, hosting and IT. Tell me what you're dealing with.

Get in touch