Incident response · 12 Oct 2026

WordPress Hacked? How to Clean It and Get Back Online

WordPress powers over 40% of the web, which is exactly why attackers automated attacks against it years ago. The good news: infections follow predictable patterns, and so does the cleanup.

First signs and what they mean

Most WordPress infections announce themselves in one of a handful of ways. Read the symptoms right and you can narrow down what kind of malware you're dealing with before you open a single file.

Redirects to spam or gambling sites

Visitors get bounced through one or two other domains before landing on a pharmacy, casino, or prize page. This is almost always one of two things: rewrite rules injected into .htaccess, or JavaScript planted in your theme's header, footer, or functions file. If the redirect only fires on mobile, or only for visitors arriving from Google, that's deliberate cloaking - the malware is hiding from you specifically.

Pharma pages and search-result spam

Your site suddenly ranks for pharmaceutical terms, and Google shows Japanese or Chinese characters where your page titles used to be. Attackers plant cloaked doorway pages - often thousands, sometimes generated on the fly - that serve spam content to search engine bots and look normal to human visitors. The pages usually live in odd subdirectories, in the uploads folder as PHP files, or as injected spam posts.

Unknown admin users

An administrator account in wp-admin that nobody on your team created is not a leftover - it's a backdoor the attacker wants you to overlook. Don't delete it yet; note the username, its email address, and when the account was created, because that date tells you roughly when the compromise happened.

Sudden performance collapse

A site that was fine yesterday and now takes ten seconds per page is usually running something it shouldn't: a crypto miner, a spam-sending process, or thousands of brute-force requests hammering wp-login.php and xmlrpc.php. Check server CPU, memory, and the mail queue before you blame the database.

The white screen of death

A completely blank white page can be malware that fatally broke a PHP file, but it can also be a routine crash - a failed plugin update, a memory limit exhausted. The distinction matters. If files you never touched were modified around the same time, you're dealing with an infection. If this started right after you clicked update, it's probably a boring breakage. Either way the steps below apply - just in different moods.

Before you touch anything

The urge to start deleting malware the moment you find it is understandable and wrong. Thirty minutes of preparation saves hours later.

Take a full backup - yes, even infected

Copy the entire web root and export the database before changing anything. The backup is your safety net if a cleanup step breaks the site, and it's your evidence: file timestamps inside it are how you reconstruct the attack timeline. Store it off the server, somewhere the malware can't reach or alter it.

Work out when it happened

Pull file modification dates, check your hosting access logs for unusual POST requests to wp-login.php, xmlrpc.php, or a plugin's AJAX endpoints, and compare against any uptime monitoring you have. The infection time narrows the entry-point search enormously - if files changed at 03:12 on a Tuesday, find out what was exploitable on Monday.

Put the site in maintenance mode

While you work, visitors shouldn't be served malware and Google shouldn't be re-crawling infected pages. A maintenance-mode plugin is fine for this; a temporary HTTP 503 with a Retry-After header is better. Do the hands-on work from a machine you trust, not from a device that was browsing the infected admin panel.

Find the entry point

Cleaning without finding the entry point is mopping the floor while the tap is running. These are the causes, in the order I check them on real incidents.

1. Outdated plugins, themes, or core

Compare every version number in wp-admin against the plugin's release history. A vulnerability disclosed two months ago in a plugin you last updated three months ago is the classic path. Note that auto-updates don't cover everything - many hosts disable them, and major WordPress core releases are never automatic.

2. Nulled or pirated themes and plugins

Now the blunt part: if you installed a free premium theme or plugin from anywhere other than wordpress.org or the vendor's own site, that's almost certainly how you got hacked. Nulled code is backdoored as a business model - the malware ships pre-installed, often dormant for weeks so it won't get linked to the install. The license fee you avoided is now the cleanup bill. Delete every nulled theme and plugin on the server, no exceptions, and buy the real ones.

3. Stolen wp-admin credentials

No two-factor authentication plus a reused or guessable password is an open door. Check the access logs for successful logins from unfamiliar IP addresses or at odd hours. Assume every password is burned regardless, and check whether the attacker's first action was creating a second admin account to walk back in through.

4. A compromised hosting account

If the attacker got your hosting panel or FTP credentials, they can touch every site on the account - this is how one hacked blog takes down four unrelated ones. Other sites on the same plan showing the same symptoms is the tell. On cheap shared hosting, a vulnerability in another customer's site can also expose yours, which is a hosting problem rather than a WordPress problem.

5. A vulnerable upload form

Any plugin that accepts file uploads - contact forms with attachments, page builders, membership plugins - can become a shell upload if it doesn't validate file types properly. Check the uploads directory for PHP files; there should essentially never be any.

6. xmlrpc.php abuse

WordPress's XML-RPC endpoint lets a single request try hundreds of password combinations, and it's enabled by default. If your logs show heavy POST traffic to /xmlrpc.php, that was either the entry point or a parallel attack that found the same weak password.

Clean it

With the entry point identified, removal is methodical work. Do it in this order.

Replace WordPress core

Download a fresh copy of your exact WordPress version from wordpress.org and use it to replace everything except wp-config.php and the wp-content directory. Core files are never legitimately modified, so anything that differs from the official archive - wp-admin, wp-includes, and the loose PHP files at the web root - gets overwritten.

Audit wp-content

This is the slow part. List files modified in the last 30 to 90 days and inspect anything you don't recognize: PHP files sitting in uploads, theme directories you never edited, plugin folders with extra files inside. Compare free plugins and themes against fresh copies from wordpress.org, and premium ones against the vendor's own distribution. Injected code hides in functions.php, header.php, and in files named to look boring - class-wp-system-cache.php, wp-tmp.php, things like that.

Diff wp-config.php against a clean copy

The stock wp-config-sample.php shows what belongs there: database constants, the eight salts, the table prefix, and nothing else. Attackers append require or include statements pointing at files in /tmp or inside uploads. Anything that isn't standard gets removed, and the reference noted so you know what it was doing.

Check .htaccess and the root index.php

.htaccess is the favorite spot for redirect malware - look for RewriteCond blocks testing the referrer or user agent and RewriteRule lines pointing at external domains. index.php at the web root should be the handful of lines that load WordPress; anything more is suspicious.

Clean the database

Search the posts and options tables for the classic injection signatures: base64_decode, eval, gzinflate, assert, and long strings of encoded characters. Check the siteurl and home values in wp_options - hijacked entries redirect your whole site. Delete spam posts and pages created during the compromise, and scan post content for injected iframes and hidden links. Then look at wp_users for administrator accounts you don't recognize, note their IDs and creation dates, and delete the rogue ones once you're certain the entry point is closed.

Don't just clean - reset

Malware's real payload is knowledge: every password that ever touched that server should now be considered public. Cleanup without a credential reset is decoration.

Rotate every password

From a device you trust, change: the hosting control panel, SFTP or SSH, the database password, and every wp-admin account - not just administrators, because privilege escalation from a lowly subscriber account is routine. If any of those passwords is reused anywhere else, change it there too.

Rotate the WordPress salts

The eight security keys in wp-config.php are what encrypt login cookies. Replace them with fresh values from the official WordPress secret-key generator and every session - yours, the attacker's, everyone's - dies instantly. It's a thirty-second change and the single most skipped step.

Update and harden so it doesn't repeat

A cleaned site with the same configuration will be reinfected - attackers share lists of freshly compromised sites, and bots re-probe every wp-login.php on the internet constantly. Hardening is not optional, and none of it is exotic.

Update everything, delete the rest

Update WordPress core, every plugin, and every theme - then delete the themes and plugins you don't actively use. Deactivated code is still reachable code, and half the plugins on a typical hacked site were not even turned on.

Lock down the code

Add define('DISALLOW_FILE_EDIT', true); to wp-config.php to kill the built-in theme and plugin editor attackers love. Protect wp-config.php itself with strict file permissions - 440 or 400 - and block direct web access to it. Where your host allows it, move it one directory above the web root.

Reduce privileges

The database user WordPress runs as needs SELECT, INSERT, UPDATE, and DELETE on one database - not CREATE, not DROP, not access to anything else. Least privilege means a SQL-injection bug or a compromised plugin does far less damage.

Add friction for attackers

Put two-factor authentication on every admin account. Enable automatic updates for minor WordPress releases - they exist purely to ship security fixes - and seriously consider auto-updates for plugins too. Put a web application firewall in front of the site to filter obvious payloads and rate-limit wp-login.php and xmlrpc.php. And know what's actually exposed on your server: run a port scan of your server and close or firewall anything that doesn't need to be public.

Back up off-site, automatically

A backup that lives on the same server as the site is a backup the attacker can encrypt or delete. Use an off-site, automated backup with at least 30 days of history, and test a restore once so you know it actually works when you need it.

Ask Google to re-scan

Google flags infected sites in search results and through Chrome warnings, and it will not remove the flag because you cleaned the files - you have to ask. Open Google Search Console, go to the Security issues report, confirm it shows no remaining problems, then click Request Review. Be specific in the notes: what happened, when you cleaned it, and what you changed. Reviews typically take from a few days to a couple of weeks, and Google will tell you if it finds anything you missed - which loops you right back to the cleaning section. Meanwhile, search site:yourdomain.com for spam URLs and use the Removals tool for anything still indexed.

If what you found was defacement rather than silent malware - the homepage replaced, slogans everywhere - the handling overlaps but the evidence matters more; see what to do when your website is defaced. If you'd rather hand the whole response to someone who does this weekly, the incident response page is the starting point. And once you're clean, the cheap insurance is knowing your site the way an attacker does - a web application penetration test maps that properly, or just get in touch and describe what you're seeing.

WordPress cleanup FAQ

A security plugin is a good first sweep - Wordfence, Sucuri, MalCare and similar tools catch known malware signatures and obvious backdoors. But scanners miss custom malware, modified legitimate files, and anything the signature database doesn't know yet. Use a scanner to narrow the search, then verify by hand: recently modified files, unknown admin users, and unfamiliar code in wp-config.php and .htaccess. If the scan reports clean but Google still flags the site, keep digging. Automated tools are the start of a cleanup, not the end of one.

Being fully updated rules out the most common cause, but not the other five: a nulled theme or plugin with a backdoor pre-installed, stolen wp-admin credentials, a compromised hosting account, a vulnerable upload form in one of your plugins, or xmlrpc.php abuse. In real incidents it's usually one of those, and most often it's a pirated premium plugin or theme installed weeks or months before the infection became visible.

No. Malware lives in files and injected database records - not in your actual content. Cleaning means removing rogue files, injected code, spam posts, and fake admin users; your legitimate posts, pages, and media stay in place. You also take a full backup before starting, so even if a cleanup step goes wrong the content can be restored, and a WordPress export makes moving it elsewhere trivial.

Sometimes, but less often than people assume. Shared hosting adds real risk - a vulnerable site belonging to another customer on the same server can expose yours. But statistically the entry point is on your side: an outdated or nulled plugin, a weak wp-admin password, or credentials reused from a breach. If the provider itself was compromised, every site on the account is usually damaged at once, which is both the signal and your evidence for a support ticket - or a new host.

You can never prove a negative, but you can get close: scanners report clean after a full rescan, no files were modified after your cleanup timestamp, every admin user is one you recognize, the server shows no suspicious processes or outbound connections, and Search Console's security report shows no issues. Then close the entry point and apply the hardening steps - a cleaned site with the same open door is just a countdown to reinfection.

Rather have it cleaned and hardened by hand?

Automated scanners miss what a human finds. Fixed-price cleanup engagements available.

Contact