Something is wrong with the site. Visitors say it redirected them to a page selling supplements. Google is showing a warning under your listing. There are posts in the dashboard you did not write, or the site loads fine for you and not for anyone arriving from search.
Before spending money on a clean-up, it is worth knowing whether the site is actually compromised. A meaningful share of the enquiries we get with “hacked” in the subject line turn out to be a broken plugin update, an expired SSL certificate or a caching misconfiguration. Those cost far less to fix, and treating them as an infection wastes a day.
This is the order we check things in, what each finding proves, and what it does not.
First: do this before you look at anything
If you believe the site is compromised, change the passwords before you start investigating, not after you finish cleaning. Attackers who still hold a valid login will simply re-infect a cleaned site, and people discover this on the third clean-up rather than the first.
- Every WordPress administrator password
- The hosting control panel and any SSH keys
- FTP and SFTP accounts — these are the most commonly forgotten and the most commonly abused
- The database user in
wp-config.php
Then take a full backup of the site as it currently is, infected and all. You will want it if the clean-up removes something the site turns out to need.
Two findings that settle it
Either of these means the site is compromised. There is no innocent explanation for them.
The site URL in the database no longer matches your domain
This is the classic redirect hack. In phpMyAdmin or Adminer, open the wp_options table and look at the siteurl and home rows. They should both read your own domain. If either points somewhere else, that is the redirect, and it was written by someone with database access.
A variation hides the redirect in a conditional instead, so it fires only for visitors arriving from Google and never for a logged-in administrator. That is why the site looks fine to you and broken to everyone else — the code is checking the referrer and the login cookie and behaving differently for you specifically.
Obfuscated PHP appended to a core file
Open wp-config.php, index.php and the theme’s functions.php and scroll to the very bottom. Injected payloads are appended below the closing content so the file still works and the change is off-screen in most editors.
What you are looking for is a long unbroken string of characters passed through something like eval(base64_decode(, or gzinflate, or a variable built out of concatenated single characters. Legitimate plugins do not write code that way. If you find it, do not simply delete that block and stop — a payload in one file means an entry point somewhere else that is still open.
Three findings that strongly suggest it
These are not proof on their own, but two of them together usually are.
- An administrator account nobody created. Users → All Users, filter by Administrator, and check the registration dates. Attackers often use a plausible name rather than something obvious, so read the email addresses rather than the display names.
- Core files modified after your last update. Download a clean copy of your exact WordPress version from wordpress.org and compare it against
wp-adminandwp-includes. Those two directories should match byte for byte. Any difference is either an infection or a previous developer editing core, and both need dealing with. - PHP files in the uploads directory.
wp-content/uploadsshould contain images, PDFs and documents. It should contain no.phpfiles at all. One there is a backdoor until proven otherwise.
Two things that look like a hack and usually are not
The site suddenly got slow. Slowness is not a symptom of compromise in any reliable way. Most malware is written to stay hidden, and a site that has become noticeably slower is far more likely to have a plugin conflict, a full disk, an exhausted database connection limit or a host that has moved it to busier hardware. Investigate it as a performance problem first.
A Google Search Console warning on its own. Search Console lags reality in both directions. A warning can arrive days after an infection has already been cleaned by a host’s automated scanner, and it can persist for days after a genuine clean-up until a review is requested and processed. Treat it as a prompt to look, not as the finding itself.
Why the entry point matters more than the payload
Most clean-ups that fail, fail the same way: the visible damage gets removed, the site looks normal for a week, and then it comes back. That happens because the malicious files were the symptom and nobody found the door.
There are only a handful of realistic entry points, and access logs usually identify which one it was:
- A known vulnerability in an outdated plugin — by a wide margin the most common, and usually a plugin that had a patch available for months
- A nulled theme or plugin downloaded from a warez site, which arrived with the backdoor already in it
- A reused administrator password that appeared in a breach somewhere else
- A neighbouring site on the same shared hosting account, infected first and with write access across the whole account
The last one is worth dwelling on. If you host six sites in one cPanel account and one is infected, assume all six are. Cleaning one and leaving the rest is how a reinfection happens the same afternoon.
If you are cleaning it yourself
The order matters. Passwords first, then a backup of the infected state, then replace wp-admin and wp-includes wholesale from a clean download rather than trying to repair individual files. Reinstall every plugin and theme from source instead of editing what is there. Then search the database for injected content — wp_options, wp_posts and wp_users are where it lives.
Only then look at the access logs to work out how they got in, and close that. A clean-up without that last step is a delay, not a fix.
Once the site is clean, request a review in Google Search Console under Security Issues. Expect it to take a few days, and expect the warning to remain visible in the meantime.
What this cannot fix
- Data that has already left. A clean-up removes the attacker’s access. It does not un-copy customer records, order histories or anything else taken while they had it. If personal data was exposed, you may have a legal notification duty and that is a question for a lawyer, not a developer.
- Rankings lost while the warning was live. They usually recover within weeks of the review clearing, but nobody can put a date on it or guarantee the position comes back.
- A site with no clean backup and no clean source. If a heavily customised theme has been edited directly for years and every copy of it is infected, sometimes the honest answer is a rebuild rather than an archaeology project.
- The next one, on its own. A clean-up is a point in time. If the plugins go unpatched again, the site returns to exactly the state it was in before.
Questions we get asked
How do I know if my WordPress site is hacked?
Two findings settle it on their own: a siteurl or home value in wp_options that no longer matches your domain, and obfuscated PHP appended to the bottom of a core file such as wp-config.php. Beyond those, an administrator account you did not create, core files modified since your last update, and any .php file inside wp-content/uploads are strong signs. A site that has merely become slow is not evidence of anything.
My site redirects visitors but looks fine when I am logged in. Why?
Because the injected code is checking who you are. Redirect malware routinely tests for a WordPress login cookie and for a search-engine referrer, then behaves normally for administrators and direct visits while redirecting everyone arriving from Google. Test it in a private window with a search-engine referrer rather than by typing the URL, or the site will keep looking healthy to you.
Can I just restore a backup instead of cleaning?
Only if you know the date the infection started and have a backup from before it, and only if you also close the way in. Restoring to a point before the compromise but leaving the vulnerable plugin at the same version reinstates the hole along with the clean files. It is also common for a backup to be older than people think — plenty of infections sit dormant for weeks before doing anything visible.
Will a security plugin remove the malware for me?
Sometimes, partially. Scanners are good at flagging modified core files and known payload signatures, which is genuinely useful as a detection step. They are much weaker at anything living purely in the database, at obfuscation they have not seen before, and at identifying how the attacker got in — which is the part that determines whether it comes back. Use one to find things; do not rely on one to finish.
How long does a professional clean-up take?
For a single site with one infection, usually within a business day. What extends it is scale rather than difficulty: several sites in one hosting account, an infection that has been present for months and reinfected through cron, or a site with no version control and heavy direct edits to theme files. We say which of those applies before quoting, not during the work.
What does a WordPress malware removal cost?
Malware removal starts at $199. That covers the clean-up, identifying and closing the entry point, and submitting blacklist review requests where the site has been flagged. Keeping it clean afterwards is a different job — patching, monitoring and tested backups are maintenance and care, from $299 a month. The free scan tells you which of the two you actually need before anyone quotes.

