Incident response · 11 min read

How to tell if your WordPress site is hacked: 12 warning signs.

Most compromised WordPress sites stay compromised for months because the owner has no idea anything is wrong. The signs are usually there — you just have to know where to look.

If you searched "is my WordPress site hacked," you already have a hunch. That hunch is often right. We clean WordPress sites for a living, and in roughly 60% of the cases that come to us, the owner had a vague feeling something was off for weeks before they finally went looking.

This guide walks through the twelve signals we use, in roughly the order we check them during an initial triage. For each one, you'll get the symptom, a five-minute confirmation step, and a quick read on severity. If you confirm even one of these, treat the site as compromised until you can prove otherwise — and skip ahead to our WordPress malware removal guide.

Before you start: don't change anything yet.

The most common mistake at this stage is rushing to delete files or change passwords before you've confirmed compromise. That destroys the forensic trail and often tips off the attacker. Read first, act second. If you're already certain you're hacked, our incident response post covers the first 60 seconds.

Sign 01 Critical

Google Safe Browsing or Search Console flags your site.

If Google has flagged your site as "deceptive" or "containing harmful content," the malware scan that fires when Googlebot crawls your pages found something. By the time this warning appears in search results, your site has typically been compromised for at least 7–14 days.

How to confirm: Open Google Search Console → Security & Manual Actions → Security issues. Or visit https://transparencyreport.google.com/safe-browsing/search and enter your domain. A "Site status: Not safe" verdict is unambiguous.

Sign 02 Critical

There's an admin user you don't recognize.

This is the smoking gun. When attackers exploit a vulnerable plugin to gain code execution, the first thing they do is plant a backup admin account so they can log back in even if the original vulnerability is patched. Common giveaways: usernames like admin, wpsupport, backupuser, or random eight-character strings.

How to confirm: In wp-admin, go to Users → All Users → Administrators. Cross-check every account with someone who would actually know. Also check the wp_users table directly — sophisticated malware can hide accounts from the admin UI.

Sign 03 Critical

WordPress core files have been modified.

WordPress core files (wp-login.php, wp-includes/*, index.php) should match the official release exactly. When attackers backdoor a site, they frequently inject obfuscated PHP into wp-blog-header.php, wp-load.php, or other always-loaded files because it survives plugin updates.

How to confirm: Install the official Health Check & Troubleshooting plugin and run "File integrity." Or, via SSH, run wp core verify-checksums with WP-CLI. Any file that fails verification is suspicious until proven otherwise.

Sign 04 High

Spam pages appear when you search your site on Google.

Run site:yourdomain.com in Google. If you see pages about pharmaceuticals, replica handbags, payday loans, or anything in a language your site doesn't publish in — your site is hosting SEO spam. The attacker is using your domain authority to rank pages for high-value keywords and either link-building to client sites or cloaking redirects.

How to confirm: Try these searches: site:yourdomain.com viagra, site:yourdomain.com casino, site:yourdomain.com .php. Cloaking is common, so visit suspicious URLs with a Googlebot user-agent — see what Google sees, not what your browser sees.

Sign 05 High

Your hosting provider warns you about outbound spam.

If your host emails you about high SMTP volume, blacklisted IPs, or "abuse," your WordPress install has likely been turned into a spam relay. Common via the wp_mail() function or PHP's mail() after a vulnerable contact form plugin gets popped.

How to confirm: Check your mail logs. On most hosts: tail -n 200 /var/log/maillog. Look for outbound mail you didn't send, especially to addresses unrelated to your business.

Sign 06 High

WP-Cron has tasks you didn't add.

Many malware families schedule themselves through WordPress's internal cron system to maintain persistence — re-injecting payloads after they're cleaned, or beaconing out to a command-and-control server every hour.

How to confirm: Run wp cron event list via WP-CLI. Look for hooks with random names, base64-encoded callbacks, or anything you can't trace to an installed plugin. Also check the cron entry in wp_options.

Sign 07 Critical

Unexpected PHP files in wp-content/uploads.

The uploads folder should contain images, PDFs, and the occasional video — never PHP. A .php file living in uploads/ is almost always a webshell, used by attackers to maintain access and run arbitrary commands on your server.

How to confirm: Via SSH: find wp-content/uploads -name "*.php" -type f. Any result is suspicious. Also look for .phtml, .phar, and innocent-looking image filenames containing PHP code (file -i suspicious.jpg tells you the actual MIME type).

Sign 08 Medium

Traffic graphs show a sudden spike — or drop.

Compromise often shows up in analytics before it shows up anywhere else. A sudden surge of traffic to URLs you didn't create usually means SEO spam is being indexed. A sudden drop usually means Google has demoted you or attackers are redirecting your visitors to another domain.

How to confirm: In Google Analytics or Plausible, check the top landing pages over the last 30 days. If pages you don't recognize are pulling traffic, follow the URLs.

Sign 09 Critical

Browsers display a warning when visiting your site.

Chrome's "Deceptive site ahead" or Firefox's "Reported as a deceptive site" warnings mean your domain has been added to a public blocklist (Google Safe Browsing, PhishTank, or similar). Visitors are being turned away by the browser itself, which means revenue impact starts immediately.

How to confirm: Open your site in an incognito window in Chrome, Firefox, and Safari. If even one of them warns, treat the site as live-compromised.

Sign 10 High

Your security plugin has been silently disabled.

If Wordfence, Sucuri, or any security plugin shows as "inactive" in the dashboard but you didn't disable it, an attacker did — usually after gaining admin access. Some malware also strips file-modification monitoring while leaving the plugin's UI looking active.

How to confirm: Check the security plugin's own logs (most write to wp-content/uploads/wp-security/ or similar). Also look at the plugin's "last scan" timestamp — if it's been months since a scheduled scan ran, something is suppressing it.

Sign 11 Critical

Your .htaccess file has redirects you didn't write.

Apache-based WordPress sites sometimes get a poisoned .htaccess that redirects mobile users, search-engine referrers, or both, to spam domains. The redirect is conditional, so when you visit the site logged in from a desktop, everything looks normal.

How to confirm: Open .htaccess in the WordPress root. Look for RewriteCond rules that check HTTP_USER_AGENT or HTTP_REFERER against unusual patterns, and any RewriteRule that sends traffic off-site. Compare against the default WordPress .htaccess block — anything outside the # BEGIN WordPress / # END WordPress markers needs scrutiny.

Sign 12 High

OS-level cron jobs you didn't create.

The most persistent malware doesn't live inside WordPress at all — it lives in the host's crontab. After cleanup, the cron job re-downloads and re-installs the payload. Many cleanups fail because the technician fixed the WordPress side and missed the OS-level persistence.

How to confirm: Run crontab -l as your web user, then cat /etc/crontab and ls -la /etc/cron.d/ /var/spool/cron/. Any task referencing curl, wget, base64-decoded commands, or unfamiliar binaries is a red flag.

What to do if you see any of these signs.

Even one confirmed sign on this list is enough. The right next steps, roughly in order:

  1. Don't tip off the attacker. Don't immediately rotate passwords or change anything visible. They have alerts too.
  2. Snapshot the evidence. Take a full filesystem and database backup labeled compromised-YYYY-MM-DD. Store it offline. This is your forensic record.
  3. Take the site offline if possible. A maintenance page is better than a live malware host. If revenue depends on uptime, put Cloudflare or similar in front of it and block all traffic.
  4. Run a proper cleanup. Either follow our step-by-step WordPress malware removal guide, or hire someone who does this professionally. DIY cleanup misses persistence ~40% of the time.
  5. Harden after recovery. Once clean, walk through every step in the WordPress hardening guide. The same vulnerability will be re-exploited within weeks if you skip this.

How most WordPress sites get hacked in the first place.

Three vectors account for nearly all of the compromises we see:

  • Outdated plugin with a known CVE (~78%). A vulnerability is published, the patch ships, attackers reverse-engineer the patch, and they spend the next 90 days scanning the internet for sites that haven't updated. If your plugins are 60+ days behind, this is statistically your most likely entry point.
  • Weak or reused admin password (~12%). Brute-force attacks against wp-login.php and XML-RPC are still wildly effective. If any admin account has a password under 14 characters or no 2FA, this is your second-most-likely vector.
  • Compromised hosting account (~6%). The attacker got in via your hosting provider's control panel — usually a leaked SFTP credential or a reused password from a breach dump. Site cleanup alone won't fix this; the host account itself is compromised.

The remaining ~4% is everything else: nulled themes, malicious plugins from sketchy marketplaces, supply-chain compromises in legitimate plugins, and good old-fashioned social engineering of admin staff.

The one-paragraph prevention plan.

Patch plugins and core weekly, not when you remember. Every admin account gets a 20+ character password and TOTP 2FA — no exceptions. Disable XML-RPC unless a specific app needs it. Lock wp-config.php down to chmod 440. Run an automated scan (the SecureAuditWP plugin will do it for free) on a schedule and alert on diffs to core files. Keep off-site backups, and actually test the restore quarterly. That's it. Nine sites in ten that follow that paragraph never get hacked.

Run all 12 of these checks automatically.

SecureAuditWP scans for every sign on this page (and 60 more) on a daily schedule, and emails you a PDF report when something changes.