WordPress powers 43% of all websites on the internet. That dominance makes it the single most targeted content management system for malware attacks. Attackers automate their exploits against known WordPress vulnerabilities because the sheer volume of potential targets makes the effort profitable. This guide walks through the complete malware removal process, from identifying the infection to hardening your site against reinfection.
Every step here uses tools and techniques that WordPress security professionals rely on daily. You will work with WP-CLI, Wordfence, Sucuri SiteCheck, and manual file inspection. The process takes anywhere from 2 to 8 hours depending on the severity of the infection. If you follow each step carefully, you can clean most WordPress malware infections yourself.
Before diving in, know this: some infections are straightforward, and some are deeply embedded across files and database tables. If at any point you feel overwhelmed, professional WordPress malware removal is a faster path to a clean site with a guarantee against reinfection.
Signs Your WordPress Site Has Malware
Recognizing an infection early limits the damage. Most site owners discover malware weeks or months after the initial breach. Here are the most common symptoms to watch for.
- Unexpected redirects: Visitors land on your site and get sent to pharmaceutical spam, fake tech support pages, or adult content. This often only affects visitors coming from Google or using mobile devices. You might never see it yourself because the malware checks for admin cookies. Our complete redirect malware removal guide covers this specific infection in detail.
- Google Safe Browsing warnings: A red interstitial page appears with “This site may be hacked” or “This site may harm your computer.” Google has detected malicious content and is protecting searchers from your site.
- Suspicious admin accounts: New administrator accounts appear in your WordPress Users panel that nobody created. Attackers create backdoor accounts to maintain access even after you change your password.
- Dramatic performance degradation: Your site suddenly loads in 8 to 12 seconds instead of 2 to 3. Malware often runs cryptominers, sends spam emails, or executes resource-intensive PHP processes in the background.
- Spam pages in Google Search Console: Hundreds or thousands of new pages appear in your index. The Japanese keyword hack creates thousands of doorway pages in Japanese characters. The pharma hack injects pages selling prescription drugs.
- Hosting account suspension: Your hosting provider sends an email stating your account has been suspended for malware, phishing, or spam activity. Hosts like SiteGround, Bluehost, and GoDaddy actively scan for infections and will shut down compromised accounts.
- Modified file timestamps: Core WordPress files show recent modification dates when you have not updated WordPress. A
wp-includes/class-wp-post.phpfile modified last Tuesday when your last update was three months ago is a clear indicator of tampering.
Before You Start: Back Up Everything
A complete backup of the infected site is mandatory before you touch anything. You need this backup for two reasons. First, if you accidentally break something during cleanup, you can restore and try again. Second, the infected files serve as forensic evidence that helps you understand how the attacker got in.
Create a full file backup using SSH or your hosting panel file manager:
tar -czf /tmp/infected-backup-$(date +%Y%m%d).tar.gz /path/to/wordpress/
Export the database separately. WP-CLI makes this simple:
wp db export /tmp/infected-db-backup.sql --allow-root
You can also export content through WP-CLI for a WordPress-native backup:
wp export --dir=/tmp/ --allow-root
Store these backups somewhere off the server. Download them to your local machine or upload them to cloud storage. Do not leave them sitting on the same server that is compromised. If the attacker still has access, they could modify or delete your backups.
Step 1: Identify the Infection Type
Different malware types require different cleanup approaches. Spending 15 minutes identifying the infection type saves hours of unfocused searching later.
Run a remote scan with Sucuri SiteCheck. Visit sitecheck.sucuri.net and enter your domain. This free tool checks for known malware signatures, blacklist status across Google Safe Browsing, Norton, McAfee, and others, and detects outdated software. The scan results tell you which blacklists have flagged your site and what type of malware was detected. Note the specific malware identifiers in the results.
Run a server-side scan with Wordfence. Install the free Wordfence plugin and run a full scan. Unlike Sucuri SiteCheck, Wordfence scans from inside your server, so it catches malware that hides from external scanners. The scan compares every core file against the official WordPress repository, checks plugin and theme files against known signatures, and flags suspicious PHP functions. For a thorough comparison of security scanning tools, see our review of the best WordPress malware removal plugins.
Check your server access logs. Look at /var/log/apache2/access.log or /var/log/nginx/access.log for unusual POST requests to files in wp-content/uploads/. Legitimate uploads go through WordPress media handling. Direct POST requests to PHP files in the uploads directory almost always indicate a web shell.
Common infection types you will encounter include the wp-vcd malware (spreads through nulled themes, injects code into every theme’s functions.php), pharma hacks (inject hidden pharmaceutical links into your pages), Japanese keyword hacks (create thousands of spam doorway pages), and cryptominer injections (load JavaScript that mines cryptocurrency using your visitors’ browsers).
Step 2: Compare WordPress Core Files
WordPress core file verification is the fastest way to detect tampering with the CMS itself. WP-CLI includes a built-in checksum verification command that compares every core file on your server against the official checksums from wordpress.org.
Run this command:
wp core verify-checksums --allow-root
Clean output shows “Success: WordPress installation verifies against checksums.” Any file that has been modified or that exists in core directories but should not be there gets flagged with a specific warning. Pay special attention to files flagged in wp-includes/ and wp-admin/. Attackers commonly inject malicious code into files like wp-includes/class-wp-cache.php or add entirely new files like wp-includes/wp-tmp.php.
If checksum verification flags files, you can manually compare them against a fresh WordPress download. First check your current version:
wp core version --allow-root
Then download that exact version from wordpress.org and use diff to compare specific files:
diff /path/to/your/wp-includes/suspicious-file.php /path/to/clean/wp-includes/suspicious-file.php
Any differences in core files that you did not make yourself indicate tampering. Do not try to manually edit infected core files. You will replace them entirely in Step 6.
Step 3: Scan Plugin and Theme Files
Plugin and theme directories are the most common hiding places for malware. Attackers target these directories because site owners rarely inspect plugin code, and updates do not always overwrite all files.
Search for dangerous PHP functions. These commands scan your entire wp-content/ directory for the most commonly abused PHP functions:
grep -r "eval(base64_decode" /path/to/wordpress/wp-content/
grep -r "str_rot13" /path/to/wordpress/wp-content/
grep -r "gzinflate" /path/to/wordpress/wp-content/
grep -r "exec(" /path/to/wordpress/wp-content/
The eval(base64_decode()) pattern is the most common malware signature in WordPress. It decodes a Base64-encoded string and immediately executes it as PHP code. Legitimate plugins almost never use this pattern. If you find it, that file is almost certainly infected.
Check every theme’s functions.php. The wp-vcd malware specifically targets functions.php in every installed theme. Open wp-content/themes/*/functions.php and look at the very first lines of code, before the opening PHP comment block. wp-vcd inserts a require_once call that loads malicious code from a file like wp-includes/wp-vcd.php or wp-content/themes/starter/starter.php.
Look for PHP files in the uploads directory. The wp-content/uploads/ directory should only contain media files such as images, PDFs, and videos. PHP files in this directory are almost always malicious.
find /path/to/wordpress/wp-content/uploads/ -name "*.php" -type f
Common malicious filenames include wp-content/uploads/2025/03/social.php, files named with random characters like xkwqz.php, or files disguised with double extensions like image.jpg.php. Delete any PHP file found in the uploads directory after verifying it is not part of a legitimate plugin (very rare exceptions exist for some caching or security plugins).
Check for recently modified files. List all PHP files modified in the last 30 days:
find /path/to/wordpress/wp-content/ -mtime -30 -type f -name "*.php"
Cross-reference these dates with any legitimate updates you performed. Files modified on dates when you made no changes deserve close inspection.
Step 4: Clean the Database
Database infections are harder to detect than file infections and they survive file-level cleanups. Attackers inject malicious JavaScript, hidden admin accounts, and modified settings directly into your WordPress database tables.
Check wp_options for suspicious entries. Several wp_options rows are common injection targets:
wp db query "SELECT option_name, option_value FROM wp_options WHERE option_name IN ('siteurl', 'home') OR option_value LIKE '%eval(%' OR option_value LIKE '%base64_decode%' OR (autoload = 'yes' AND LENGTH(option_value) > 10000);" --allow-root
Verify that siteurl and home contain your actual domain. Attackers change these values to redirect your entire site. Large autoloaded options with encoded content are often malware payloads that execute on every page load.
Scan wp_posts for injected content. Malware frequently injects JavaScript into post content:
wp db query "SELECT ID, post_title FROM wp_posts WHERE post_content LIKE '%<script%' AND post_content LIKE '%eval(%';" --allow-root
Legitimate posts may contain script tags if you have embedded widgets or custom functionality. Look specifically for obfuscated JavaScript, external script sources you do not recognize, and eval() calls within the script blocks.
Check for rogue admin accounts. List all administrator accounts:
wp user list --role=administrator --fields=ID,user_login,user_email,user_registered --allow-root
Any administrator account you do not recognize needs to be deleted immediately. Check the registration date. Accounts created around the time the infection started are almost certainly attacker-created backdoor accounts.
Check for malicious scheduled events. Attackers use WordPress cron jobs to reinfect your site on a schedule:
wp cron event list --allow-root
Look for events with unusual hook names or callbacks that point to files in unexpected locations. Legitimate WordPress cron events have recognizable names like wp_scheduled_delete or wp_update_plugins. Events with random-string names or names mimicking core events with slight variations are suspicious.
Step 5: Check .htaccess and wp-config.php
These two files control your site at the most fundamental level. A single malicious line in either file can redirect all your traffic or give an attacker full database access.
Inspect .htaccess thoroughly. The default WordPress .htaccess contains only the standard rewrite rules for pretty permalinks. It looks like this:
# BEGIN WordPress
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress
Anything outside these blocks that you did not add yourself is suspicious. Common malware additions include base64-encoded RewriteRule conditions that redirect mobile users, referral-based redirects that only affect visitors arriving from Google, and ErrorDocument directives that load malicious PHP files. Some infections create additional .htaccess files in subdirectories like wp-content/.htaccess or wp-content/uploads/.htaccess. Check all of them.
Examine wp-config.php line by line. Open your wp-config.php and look for anything that should not be there. Specifically search for eval() calls, base64_decode() calls, require_once or include statements pointing to unusual file paths, and any PHP code placed before the opening comment or after the “That’s all, stop editing!” line.
Verify your database credentials have not been changed. If the attacker modified DB_HOST, DB_USER, DB_PASSWORD, or DB_NAME, your site might be reading from and writing to an attacker-controlled database. Compare these values against your hosting panel’s actual database settings.
Check the authentication keys and salts. If these have been compromised, all existing login sessions remain valid even after password changes. Generate new keys at api.wordpress.org/secret-key/1.1/salt/ and replace all eight key constants in wp-config.php. This forces every user to re-authenticate.
Step 6: Remove Malware and Replace Core Files
Now that you have identified every infected file and database entry, it is time to clean. The safest approach replaces as much code as possible with known-clean versions rather than trying to surgically remove malicious lines from infected files.
Reinstall WordPress core. WP-CLI downloads a fresh copy from wordpress.org and replaces all core files:
wp core download --force --allow-root
This replaces wp-includes/ and wp-admin/ entirely with verified clean files. It does not touch wp-content/ or wp-config.php, so your themes, plugins, and configuration remain intact.
Reinstall plugins from the WordPress repository. For each plugin that came from wordpress.org, reinstall it:
wp plugin install plugin-name --force --allow-root
The --force flag overwrites existing files with a clean download. For premium plugins not available through the repository, download fresh copies from the vendor and upload them manually after deleting the infected versions completely.
Replace your theme if possible. If you are using a theme from the WordPress repository, reinstall it the same way. For custom themes, you need to manually clean each file. Compare against your most recent clean backup or the theme vendor’s original distribution files.
Delete any files you identified as malicious. Remove the PHP files found in wp-content/uploads/, any extra files in core directories that wp core verify-checksums flagged, and any standalone backdoor scripts. Common backdoor filenames include wp-content/cache.php, wp-content/uploads/wpallimport/files/shell.php, and random-named files like wp-content/plugins/akismet/xjq.php.
Clean the database entries. Remove malicious content you identified in Step 4. Delete suspicious wp_options entries, clean injected JavaScript from wp_posts, and remove rogue user accounts. Use WP-CLI for precision:
wp user delete SUSPICIOUS_USER_ID --reassign=1 --allow-root
Step 7: Harden Your Installation
Cleaning the malware only solves the immediate problem. Without hardening, the same vulnerability that let the attacker in the first time will let them right back in.
Set correct file permissions. WordPress files should use 644 permissions and directories should use 755. The wp-config.php file should be set to 440 or 400 for additional protection:
find /path/to/wordpress/ -type f -exec chmod 644 {} \;
find /path/to/wordpress/ -type d -exec chmod 755 {} \;
chmod 400 /path/to/wordpress/wp-config.php
Disable PHP execution in the uploads directory. Create or edit wp-content/uploads/.htaccess and add:
<Files "*.php">
Order Allow,Deny
Deny from All
</Files>
This prevents any PHP file in the media directory from executing. Even if an attacker manages to upload a web shell, it cannot run.
Remove unused themes and plugins. Every inactive theme and plugin is unnecessary attack surface. Deactivated plugins with unpatched vulnerabilities are a leading cause of WordPress compromises. Delete everything you are not actively using:
wp plugin list --status=inactive --field=name --allow-root | xargs -I {} wp plugin delete {} --allow-root
Enforce strong passwords and two-factor authentication. Require all administrator and editor accounts to use passwords with at least 16 characters. Install a 2FA plugin like WP 2FA or use the two-factor authentication module built into Wordfence. This single step blocks the vast majority of brute force and credential stuffing attacks.
Limit login attempts. WordPress allows unlimited login attempts by default, which makes brute force attacks trivial. Install Limit Login Attempts Reloaded or use Wordfence brute force protection to cap failed attempts at 5 per IP address with a 15-minute lockout period.
Keep everything updated. 52% of WordPress vulnerabilities come from plugins according to WPScan vulnerability database data. Enable automatic updates for minor WordPress releases and security patches:
wp config set WP_AUTO_UPDATE_CORE minor --allow-root
Step 8: Request Google Review
Google Safe Browsing protects approximately 4 billion devices worldwide. If your site triggered a Safe Browsing warning, you lose nearly all organic traffic until Google verifies your site is clean and removes the flag.
Submit a review through Google Search Console. Navigate to Security and Manual Actions, then Security Issues. You will see the specific issues Google detected listed with details. After confirming you have resolved each one, click “Request Review.” Provide specific details about what you found and what you did to fix it. Vague descriptions like “I cleaned the malware” get rejected. Write something specific, such as: “Removed injected JavaScript from 47 posts in the wp_posts table, deleted a PHP backdoor at wp-content/uploads/2025/social.php, reinstalled WordPress core 6.7, and updated all plugins to latest versions.”
Check other blacklists. Google is not the only blacklist that matters. Use VirusTotal to scan your domain against 70+ security vendors simultaneously. Also check your domain on Norton Safe Web, McAfee SiteAdvisor, and Sucuri SiteCheck. Each service has its own delisting request process.
Monitor actively for 30 days. Reinfection most commonly happens within the first two weeks after cleanup. Configure Wordfence to email you immediately on any file change. Check Google Search Console weekly for new security issues. Run a Sucuri SiteCheck scan every few days for the first month.
Google review typically takes 24 to 72 hours to process. During this waiting period, do not make unnecessary changes to your site that could trigger additional security flags. If your review is denied, Google will specify what they still found. Go back and clean those specific issues, then resubmit.
When to Hire a Professional
This guide works for straightforward infections where the malware is confined to known file locations and recognizable patterns. Some infections exceed what any step-by-step guide can address.
Consider professional help when:
- The malware keeps coming back after you clean it. Persistent reinfection means a backdoor is hiding somewhere your manual search missed, possibly obfuscated or stored in the database.
- The infection spans multiple sites on the same server. Shared hosting environments can allow malware to spread between accounts through symlink attacks or shared temp directories.
- You find more than three separate backdoor files. Multiple backdoors indicate a sophisticated attacker who invested time in establishing persistent access.
- The database infection is extensive, affecting hundreds or thousands of posts. Cleaning that volume manually is time-consuming and error-prone.
- Your business loses significant revenue for every hour of downtime. A professional can clean a typical infection in 4 to 8 hours versus the 1 to 3 days it might take on a first attempt.
- You do not have PHP development experience. Accidentally deleting a legitimate file can break your site as severely as the malware itself.
If you need guaranteed cleanup with an incident report and a reinfection guarantee, our professional WordPress malware removal service handles the full process. The team combines automated scanning with manual code review and provides detailed documentation of exactly what was compromised and how the attacker gained access.
Conclusion
WordPress malware removal follows a predictable, methodical process: identify the infection type, back up everything, scan files and database, clean infected components, harden your installation, and verify the cleanup with Google and other blacklists. The tools are freely available. WP-CLI verifies core file integrity in seconds. Wordfence and Sucuri detect known malware signatures. Manual inspection catches the obfuscated threats that automated tools miss.
The most important step is hardening after cleanup. Finding and removing malware is only half the job. Closing the vulnerability that allowed the infection in the first place is what prevents it from happening again. Update every plugin and theme, remove what you do not actively use, enforce strong credentials with two-factor authentication, and monitor your site consistently going forward.
For the complete toolkit, our comparison of WordPress malware removal plugins helps you choose the right scanning and protection solution. And if you hit a wall at any step or need the job done with certainty and speed, our WordPress malware removal service is built for exactly that situation.