← All posts

Is my WordPress site hacked? How to check, and how to clean it

If you’re here because something looks wrong, the fastest useful check is this: open your site in a private window, logged out, from a phone. A large share of WordPress infections deliberately hide from logged-in administrators and only show themselves to search-engine visitors or mobile users.

If that looks clean, also search Google for site:yourdomain.com. Injected spam pages show up there long before they show up to you.

Signs worth taking seriously

Strong signals, meaning assume compromise until proven otherwise:

  • Google or your browser shows a “deceptive site” warning
  • site:yourdomain.com returns pages you never created, often pharmaceutical or casino spam
  • Visitors get redirected somewhere else, but you don’t
  • Admin users exist that you didn’t create
  • Your host suspended the account or emailed a malware notice
  • PHP files appear in wp-content/uploads, which should hold media, never executable code

Weaker signals that have innocent explanations but are worth checking:

  • Sudden slowness (also a plain performance problem)
  • Outbound email marked as spam
  • Files with recent modification dates you can’t explain
  • Unexpected scheduled tasks
Strong signals — assume compromise Weaker signals — worth checking Deceptive-site warning Spam pages in site: search Visitor redirects (not you) Admin users you didn't create PHP files in /uploads Sudden slowness Outbound email flagged as spam Unexplained file dates Unexpected scheduled tasks
The strongest single indicator is core-file integrity — core files don't change on their own.

The single most reliable indicator is core file integrity. WordPress publishes checksums for every core file of every release. If a file in wp-admin or wp-includes doesn’t match, there is no innocent explanation. Core files don’t change on their own.

Confirming it properly

Guessing is the enemy here, because both false positives and false negatives are expensive. Three checks, in order:

Confirm it properly — three checks, in order Core integrity core-file checksums Where code shouldn't be /uploads first Scan for the patterns known malware habits 123 cheap & definitive
Guessing is the enemy — both false positives and false negatives are expensive.

1. Core integrity. Compare every core file against the official wordpress.org checksums. Modified means compromised. Missing is suspicious. This check is cheap and definitive.

2. Look where code shouldn’t be. PHP that executes from wp-content/uploads is almost never legitimate. Scan for executable code in the uploads directory first, because that’s where uploaded webshells land.

3. Scan for the patterns. Real malware has recognisable habits: execution functions wrapping decoders, user input flowing straight into execution, long encoded blobs hiding a payload, and the handles of known webshells.

If you have an AI agent connected through a WordPress MCP server, EMCP’s scan-security tool runs all of that in one pass, malware heuristics, core-file integrity, hardening, and outdated software, and returns a scored report with severities and ranked recommendations. It’s read-only, so running it can’t make anything worse.

You: Has this site been compromised?
AI: scan-security({})
→ Score 38 (F)
• 2 core files modified in wp-includes (critical)
• Executable PHP under uploads (critical)
• Obfuscated code execution in a theme (critical)
• File editing enabled in wp-admin (warning)

A realistic cleanup order

Do these in sequence. Skipping ahead is how people get reinfected within a week.

Cleanup order — do these in sequence Backup — even while infected Rotate passwords + salts Replace core / plugins / themes Clean uploads, block PHP Check the database Close the door — the entry point Request review 123 456 7 Order matters Skip ahead → reinfection, within a week.
Cleaning without finding the entry point means doing this again.

1. Take a backup first, even though it’s infected. You will need it if the cleanup breaks something, and it’s evidence for working out how they got in.

2. Change every password and rotate the salts. WordPress admins, hosting, FTP/SFTP, and the database user. Then replace the salt keys in wp-config.php, which invalidates every existing login session and kicks the attacker out.

3. Replace core, plugins, and themes from clean sources. Don’t clean core files by hand. Reinstall WordPress core from a fresh download, and reinstall every plugin and theme from source. Anything you can’t reinstall from a trusted source, that nulled theme, that abandoned plugin, delete it.

4. Clean uploads carefully. You can’t reinstall this, it’s your media. Remove executable code from it, then block PHP execution in that directory entirely so it can’t happen again.

5. Check the database. Look for injected scripts in post content and options, and for admin users you don’t recognise.

6. Close the door. Cleaning without finding the entry point means doing this again. Usually it’s an outdated plugin, a weak password, or a nulled theme that shipped with a backdoor.

7. Request review. If Google flagged you, request a review through Search Console once you’re actually clean.

When to pay someone

Genuinely worth it when:

  • The site earns money and downtime costs more than the cleanup
  • You’ve cleaned it and it came back, meaning you missed the entry point
  • There’s a legal or compliance dimension, like customer data
  • You don’t have server-level access to do the job properly

A cleanup service is not a scam by default. Reinfection is common precisely because the cleanup part is easy and the finding out how they got in part is not.

Preventing the next one

Most compromises come through a small number of doors:

  • Outdated software. Enable auto-updates for at least security releases.
  • Nulled themes and plugins. These frequently ship with backdoors as the business model. There is no safe source for pirated premium software.
  • Weak admin passwords. Use a manager and enable two-factor.
  • Abandoned plugins. Anything unmaintained for years, or pulled from the plugin directory, is a liability. Removed-from-wordpress.org is often a security removal.
  • File editing in wp-admin. Set DISALLOW_FILE_EDIT so a stolen admin session can’t rewrite your theme in the browser.

The hardening checklist covers the full set in order.

← All postsSubscribe via RSS