Most WordPress compromises stay hidden for weeks. No defaced homepage, no ransom note.
Often here's no dramatic defacement, no ransom note, no angry emails from customers. Instead, the compromise sits quietly in the background, harvesting credit card details, sending spam, or quietly redirecting your visitors somewhere you really don't want them to go. By the time most site owners notice, the malware has been there for weeks or months.
The good news is that compromises leave fingerprints. If you know where to look, you can catch an infection early, before it trashes your search rankings or gets your domain blacklisted. Here's what I look for when auditing a WordPress site, plus the quick checks you can run yourself today.
The warning signs
1. Unexplained traffic drops or ranking changes
A sudden dip in organic traffic is often the first visible symptom. Malicious scripts injected into your pages can trip Google's Safe Browsing warnings, trigger "this site may be hacked" notices in search results, or cloak content so that search engines see something different from your visitors. Check Google Search Console for security issues and manual actions; it's free and it tells you what Google actually sees.
2. Strange files in your installation
Attackers love to drop files with innocent-looking names into directories nobody watches. Classic hiding spots include:
wp-content/uploads/, which should only ever contain media files, never PHP- Your theme's root directory and child directories
wp-includes/andwp-admin/, where files masquerading aswp-class.phporwp-tmp.phpsit alongside genuine core files
A file modified recently in wp-includes/ almost always means trouble. Legitimate core files only change when you update WordPress.
3. Suspicious cron jobs and scheduled tasks
Few things are as overlooked as WordPress's own scheduler. Compromised sites often gain malicious entries in the wp_options table under cron, silently re-downloading malware even after you've cleaned the files. While you're there, check for phantom admin users. Attackers frequently create accounts with usernames like wp_support or admin_2024 and give them administrator rights.
4. Injected scripts and iframes
Base64-encoded strings, long minified blobs appended to your functions.php, or <script> tags referencing unfamiliar external domains are all red flags. Cloaking scripts are particularly sneaky: they check whether the visitor came from Google or is using a mobile device, then show the malware only to those users. That's why the site owner often browses their own site and sees nothing wrong, while customers are being hit.
5. Your site is slower than it should be
Malware isn't written for performance. Crypto-mining scripts, spam-generation routines, and outbound connections to command-and-control servers all eat resources. If your hosting provider suddenly starts nagging you about CPU limits, and nothing on the site has changed, investigate.
6. Search results you didn't write
Query Google with site:yourdomain.com and look for Japanese pharmaceutical spam, poker pages, or anything in a language you don't recognise. The "Japanese keyword hack" is notorious for injecting thousands of gibberish pages that only appear in search results, invisible when browsing the site normally.
Quick checks you can run today
Diff your core files. Download a fresh copy of WordPress from wordpress.org and compare it against your installation. Any difference outside wp-config.php and wp-content/ deserves scrutiny.
Check file modification times. From SSH, find . -mtime -3 -type f lists everything changed in the last three days. Legitimate updates are obvious; unexpected changes are not.
Inspect the database. Look at the wp_users table for unfamiliar accounts, and search your posts and pages for <script> and base64_decode.
Scan your site externally. Tools like Sucuri's SiteCheck and UpGuard surface injected content, blacklisting status and exposed version information. Nothing beats a proper server-side scan, but external checks are fast and catch a lot.
Review your access logs. Look for POST requests to files that shouldn't accept POST requests, or repeated hits to xmlrpc.php. Which brings us to the biggest single win most WordPress sites can make.
Close the door behind you
Spotting an infection is only half the battle. The same audit should cover your exposure:
- Disable XML-RPC entirely unless you have a specific dependency on it; it's a brute-force magnet and most sites never use it
- Remove version leakage from your page head, feeds and readme files so attackers can't trivially match your site against known plugin vulnerabilities
- Keep plugins updated religiously, and delete the ones you've stopped using; abandoned plugins are the number one infection vector I see
- Set security headers properly, but test them carefully; a misconfigured
Header setdirective in.htaccesscan take a whole site down with a 500 error - Back up regularly, store backups off-site, and actually test restoring one
Technical support for suspected WordPress hacks
Any malicious infection leaves traces. Here's how to find them systematically using the command line.
Core file integrity checks
Start by verifying your WordPress core hasn't been tampered with. Download a fresh copy and compare:
# Download fresh WordPress
cd /tmp
wget https://wordpress.org/latest.tar.gz
tar -xzf latest.tar.gz
# Compare against your site (adjust path as needed)
diff -rq wordpress/ /var/www/html/ --exclude=wp-config.php --exclude=wp-content
Any differences outside wp-config.php and wp-content/ warrant investigation. Core files only change on updates.
File modification hunting
List files modified recently; legitimate updates will be obvious:
# Files changed in the last 7 days
find /var/www/html -type f -mtime -7 -ls
# Specifically look for PHP in uploads (should never happen)
find /var/www/html/wp-content/uploads -name "*.php" -ls
# Find recently modified core files (these are the danger zone)
find /var/www/html/wp-includes /var/www/html/wp-admin -type f -mtime -30
Database scanning for injected content
Malware hides in database content too, not just files. Connect and search:
-- Look for suspicious script tags in posts
SELECT ID, post_title FROM wp_posts
WHERE post_content LIKE '%<script%'
OR post_content LIKE '%base64_decode%'
OR post_content LIKE '%eval(%';
-- Check for unfamiliar admin users
SELECT ID, user_login, user_email, display_name
FROM wp_users
WHERE ID > 2 OR user_login NOT IN ('your-username');
-- Inspect wp_options for suspicious cron entries
SELECT option_value FROM wp_options
WHERE option_name = 'cron';
From the shell you can dump this:
mysqldump -u dbuser -p dbname | grep -i 'base64\|eval\|<script'
Process and resource monitoring
Crypto miners and command-and-control clients consume resources. Check active processes:
# Look for suspicious processes
ps auxf | grep -E 'miner|cryptonight|xmrig|node.*evil'
# Check network connections from your web user
netstat -tunlp | grep www-data
ss -tunlp | grep :80
# Monitor real-time resource usage
watch -n 5 'top -b -c | head -20'
If your hosting provider is nagging you about CPU spikes but you've made no changes, this is worth investigating.
Cron and scheduled task inspection
Attackers persist through malicious cron jobs. Check both system and WordPress scheduler:
# System crontab
crontab -l -u www-data
# WordPress database cron (decode the serialized data)
mysql -u dbuser -p dbname -e "SELECT option_value FROM wp_options WHERE option_name='cron'" | php -r "print_r(unserialize(stream_get_contents(STDIN)));"
# Look for suspicious entries in /etc/cron.d/
grep -r wordpress /etc/cron.d/
XML-RPC abuse detection
XML-RPC is still abused for brute force attacks. Check your access logs:
# Count XML-RPC hits in last 24 hours
grep xmlrpc.php /var/log/apache2/access.log* | wc -l
# See which IPs are hammering it
grep xmlrpc.php /var/log/apache2/access.log* | awk '{print $1}' | sort | uniq -c | sort -rn | head -10
# Block it if you don't need it (add to .htaccess)
# <Files xmlrpc.php>
# Order Deny,Allow
# Deny from All
# </Files>
For Apache running on Lightsail, verify the module is loaded first:
apachectl -M | grep headers
If mod_headers isn't there, Header set directives will throw 500 errors.
Version leakage audit
Attackers fingerprint your setup before exploiting it. Search for exposed versions:
# Check page headers
curl -I https://yourdomain.com | grep -i 'wordpress\|generator'
# Scan feeds for version strings
curl https://yourdomain.com/feed | grep -i 'generator'
# Check for readme.html (classic giveaway)
curl -I https://yourdomain.com/readme.html
If these leak versions, add removal code to your theme's functions.php or use a security plugin.
External reconnaissance
Sometimes the compromise shows up externally before you find it internally:
# Check blacklisting status via curl to public APIs
curl -s "https://www.google.com/safebrowsing/?hl=en&url=https://yourdomain.com" | grep -i blocked
# Run external scans
curl "https://sitecheck.sucuri.net/api/scanner?url=yourdomain.com"
These won't catch server-side malware but will surface blacklisting and cloaking that affects visitors.
Finding hidden PHP files
Look for files that don't belong, including those with odd permissions:
# Files with execute permissions in uploads
find /var/www/html/wp-content/uploads -perm /111 -type f -ls
# Files created without FTP activity (compare against known-good list)
find /var/www/html -name "*.php" -type f -exec ls -la {} \; | grep -v 'your-ftp-username'
# Search for obfuscated function names
grep -r 'eval(\$_REQUEST' /var/www/html --include="*.php"
grep -r 'base64_decode(str_rot' /var/www/html --include="*.php"
Access log forensic analysis
Dig into your access patterns for anomalies:
# Find unusual 404 attempts (probing for vulnerable plugins)
grep '" 404 ' /var/log/apache2/access.log | awk '{print $7, $8}' | sort | uniq -c | sort -rn | head -20
# Spot POST requests to files that shouldn't accept them
grep 'POST' /var/log/apache2/access.log | grep -v 'wp-login.php\|xmlrpc.php'
# Identify high-frequency IPs (brute force or scraping)
awk '{print $1}' /var/log/apache2/access.log | sort | uniq -c | sort -rn | head -20
Immediate remediation steps
When you find something, act fast but document everything:
# Backup the compromised state first
rsync -avz /var/www/html/ /backup/compromised-$(date +%Y%m%d)/
mysqldump -u dbuser -p dbname > /backup/db-compromised-$(date +%Y%m%d).sql
# Change all credentials
# 1. MySQL passwords (update wp-config.php)
# 2. Admin passwords (reset via wp-cli)
wp user update administrator --user_pass='newstrongpassword' --porcelain
# 3. Database user password
mysql -e "ALTER USER 'dbuser'@'localhost' IDENTIFIED BY 'newpassword';"
# Remove malicious users
wp user delete baduser --reassign=administrator
Prevention checklist
Fix the entry point or you'll repeat this. Most infections come from:
- Outdated plugins; run
wp plugin list --status=inactiveand delete what you don't use - Nulled or pirated themes; they're malware carriers
- Weak admin passwords; enforce strong authentication via security plugins
- Missing file permissions hardening; your uploads folder should not be writable by Apache
A few key .htaccess rules worth implementing:
# Block direct PHP execution in uploads
<FilesMatch "\.(php|php7|phtml)$">
Order Allow,Deny
Deny from all
</FilesMatch>
# Disable directory listing
Options -Indexes
# Protect wp-config.php
<files wp-config.php>
Order Allow,Deny
Deny from all
</files>
Test these carefully; misconfiguration takes sites down with 500 errors.
Ten minutes of systematic checks weekly catches most compromises before they cascade. Set a reminder, run the file diffs, review new users, glance at Search Console. Automation helps but nothing replaces periodic hands-on inspection.
If you're managing multiple WordPress installations or simply don't want to think about this at all, I can audit your sites and harden the configuration. Get in touch and we'll sort it.
Ready to elevate your WordPress site?
Whether you're launching a new site, strengthening security, or integrating WooCommerce, I can help transform your vision into a high-performing online presence.
More WordPress posts
—
How to spot a compromised WordPress site before it's too late
Most WordPress compromises stay hidden for weeks. No defaced homepage, no ransom note. Often here's no dramatic defacement, no ransom note, no angry emails from customers. Instead, the compromise sits…
Continue reading "How to spot a compromised WordPress site before it's too late"
—
Modern WordPress security: why management beats manual hardening
Discover why the latest WordPress updates and tools like Wordfence make active management more effective than old-school hardening techniques. A few years ago, I wrote about Hardening WordPress against hacking.…
Continue reading "Modern WordPress security: why management beats manual hardening "
—
Enhancing WordPress Search: The Best Plugins and Tools for 2026
Visitors come expecting to find what they need quickly; when search fails, bounce rates climb and conversions slip. The default WordPress search leaves much to be desired, which means you…
Continue reading "Enhancing WordPress Search: The Best Plugins and Tools for 2026 "
—
WordPress plugin security auditing
In the WordPress ecosystem, plugins are the lifeblood of functionality, yet they represent the single largest attack surface for malicious actors. With thousands of new plugins submitted to the repository…
More Security posts
—
How to spot a compromised WordPress site before it's too late
Most WordPress compromises stay hidden for weeks. No defaced homepage, no ransom note. Often here's no dramatic defacement, no ransom note, no angry emails from customers. Instead, the compromise sits…
Continue reading "How to spot a compromised WordPress site before it's too late"
—
Modern WordPress security: why management beats manual hardening
Discover why the latest WordPress updates and tools like Wordfence make active management more effective than old-school hardening techniques. A few years ago, I wrote about Hardening WordPress against hacking.…
Continue reading "Modern WordPress security: why management beats manual hardening "
—
Securing your domain: Setting up DNS records for non-sending domains
Every domain owner faces the same fundamental security challenge: ensuring their digital identity remains trustworthy. Even if a domain is used exclusively for hosting websites and never transmits an email;…
Continue reading "Securing your domain: Setting up DNS records for non-sending domains "
—
Building cookieless tracking without Google Analytics
The era of ubiquitous third-party cookies is drawing to a close, accelerated by stringent regulations like the GDPR in Europe and the CCPA in California, alongside browser initiatives such as…
Continue reading "Building cookieless tracking without Google Analytics "