If your WordPress site got hacked, every minute counts. One compromised admin account or a hidden backdoor can mean stolen data, ruined SEO, lost revenue and a long, expensive recovery. This guide is a no-fluff, step-by-step emergency playbook designed to move you from panic to containment, cleanup and long-term recovery — fast.
You’ll find exactly what to do first (the actions you must take in the first minutes and hour), what safe commands and scripts to run or hand to your host, how to preserve forensic evidence, and the proven remediation sequence to remove malware, close persistence and restore trust. There are clear verification steps so you know when it’s truly safe to re-open the site, plus communication templates for stakeholders and customers and a 30/60/90-day hardening plan to prevent repeat attacks.
Whether you’re a site owner, developer, or IT responder, this playbook gives practical, prioritized actions you can implement immediately — or hand off to your web host or incident response team. Ready to stop the bleeding and take back control? Start with the “Immediate priorities” section below.
Immediate priorities
- Breathe & document. Note who found it, when, symptoms (redirects, defacement, popup, Google warning), and any first actions taken.
- Put site into maintenance mode / block public access.
- If you can log in to WP, enable a maintenance plugin or set a static
index.html
holding page at webroot. - If not, ask host to restrict site by IP or enable CDN/WAF “Under Attack” / “Maintenance” mode.
- If you can log in to WP, enable a maintenance plugin or set a static
- Preserve a snapshot (do not modify files yet).
- Ask host for a server snapshot or create an archive of current files and DB (read-only).
- If you have shell access, run the non-destructive snapshot script below (it only collects information).
- Change all critical passwords immediately (but do not delete logs or snapshots): hosting, control panel, SSH/SFTP, database, WP admin, payment API keys. Force logout of all sessions.
- Notify your host & (if applicable) your incident response team. Ask host to isolate the instance or suspend outgoing network if exfiltration suspected.
Signs your site is hacked
- Unexpected redirects to other websites
- Spam content appearing on your site
- Google warning “This site may be hacked”
- Defaced homepage
- Can’t login to admin panel
- Slow performance or site crashes
- Unknown admin users
- Hosting account suspended
- Strange files in directories
Document everything:
- Take screenshots of suspicious activity
- Note the time you discovered the hack
- Record any error messages
- Check when the hack likely occurred
Enable Maintenance Mode. Prevent visitors from seeing the compromised site
Option A: Using Plugin (if you can still login)
Install "WP Maintenance Mode" or "Coming Soon" plugin
Activate maintenance mode
Option B: Manual Method (via FTP/File Manager)
Create a file named .maintenance
in your WordPress root directory:
<?php
$upgrading = time();
?>
Option C: Via .htaccess
Add this to your .htaccess
file:
apache
RewriteEngine On
RewriteBase /
RewriteCond %{REMOTE_ADDR} !^123\.123\.123\.123$ # Replace with YOUR IP
RewriteCond %{REQUEST_URI} !^/maintenance\.html$
RewriteRule ^(.*)$ /maintenance.html [R=307,L]
Then create a simple maintenance.html
file.
Change ALL Passwords IMMEDIATELY
Critical passwords to change (in this order):
- WordPress Admin Password
- Go to: Users → Your Profile → Generate Password
- Use a strong password (20+ characters, mixed case, numbers, symbols)
- Hosting Control Panel (cPanel/Plesk)
- Login to your hosting account
- Change main account password
- FTP/SFTP Password
- Through hosting control panel
- Update credentials in any FTP clients
- Database Password
- cPanel → MySQL Databases → Change Password
- Update
wp-config.php
with new password
- Email Accounts
- All email addresses associated with the domain
- Other Users
- Force password reset for all WordPress users
Contact Your Hosting Provider or Website Security Professional
Call or create support ticket immediately:
Tell them:
- “My WordPress site appears to be hacked”
- “Please check server logs for suspicious activity”
- “Can you restore from a recent clean backup?”
- “Has my account been suspended?”
Ask them to:
- Review server access logs
- Check for compromised accounts
- Scan for malware
- Identify attack vector
- Confirm if other sites on server are affected
Request:
- Recent clean backup (before the hack)
- Log files showing suspicious activity
- Any security alerts or notifications
Identify the Hack Type
Common WordPress hack types:
A. Malware Injection
- Symptoms: Redirects, popup ads, hidden iframes
- Look for: Obfuscated code, base64 encoded strings
B. Pharma Hack
- Symptoms: Spam pages selling pharmaceuticals
- Look for: Hidden pages, cloaking scripts
C. SEO Spam
- Symptoms: Spam keywords, hidden links
- Look for: Injected links in footer/comments
D. Backdoor
- Symptoms: Recurring infections, hidden admin accounts
- Look for: Shell scripts, suspicious PHP files
E. Brute Force Success
- Symptoms: Unauthorized admin access
- Look for: Login logs, new admin users
F. Defacement
- Symptoms: Homepage replaced with hacker message
- Look for: Modified index.php, wp-config.php
Backup Current Site (Even if Infected)
Why backup infected site?
- Preserve evidence
- Reference for what was changed
- Recover content if needed
How to backup:
Via cPanel:
1. cPanel → File Manager
2. Select public_html folder
3. Compress → Create Archive
4. Download the archive
5. Also backup database from phpMyAdmin
Via FTP:
1. Connect via FileZilla
2. Download entire /public_html/ directory
3. Download from root directory (above public_html)
Database backup:
1. phpMyAdmin → Select database
2. Export → Quick → SQL format
3. Download file
4. Store securely offline
Remove Malicious Code
Critical files to check first:
wp-config.php (WordPress root)
Should only contain database configuration
Look for: Extra code at beginning or end
Compare with fresh WordPress wp-config-sample.php
index.php (WordPress root)
Should be minimal and clean
Look for: Redirects, obfuscated code
.htaccess (WordPress root)
Should only have WordPress rewrite rules
Look for: Redirects, suspicious RewriteCond
functions.php (In your theme folder)
/wp-content/themes/your-theme/functions.php
Look for: Base64 strings, eval(), unknown functions
Footer.php / Header.php
Look for: Hidden iframes, suspicious scripts
Common malicious code patterns:
php// Base64 encoded malware
<?php eval(base64_decode('...')); ?>
// Obfuscated code
<?php $a='base'.'64_dec'.'ode';$b=$a('...'); eval($b); ?>
// Hidden iframes
<iframe src="http://malicious-site.com" style="display:none"></iframe>
// Suspicious functions
eval()
base64_decode()
gzinflate()
str_rot13()
assert()
preg_replace() with /e modifier
create_function()
How to clean:
Compare with clean files
Download fresh WordPress from wordpress.org
Use diff tool to compare files
Restore clean versions
Manual removal
Open suspicious files in text editor
Remove malicious code if you can. If not we suggest you to order website malware removal services from us.
Save and upload clean version
Check Database for Malicious Content
Access database via phpMyAdmin:
A. Check for Rogue Admin Users
sql
SELECT * FROM wp_users;
SELECT * FROM wp_usermeta WHERE meta_key = 'wp_capabilities';
Look for:
- Unknown usernames
- Recently created accounts
- Users with administrator role
Delete rogue users:
sql
DELETE FROM wp_users WHERE user_login = 'suspicious_username';
DELETE FROM wp_usermeta WHERE user_id = 'suspicious_user_id';
B. Search for Spam Content
sql
-- Search posts for suspicious content
SELECT * FROM wp_posts WHERE post_content LIKE '%viagra%';
SELECT * FROM wp_posts WHERE post_content LIKE '%<iframe%';
SELECT * FROM wp_posts WHERE post_content LIKE '%base64%';
-- Search for hidden posts
SELECT * FROM wp_posts WHERE post_status = 'private' OR post_status = 'draft';
-- Check for spam in comments
SELECT * FROM wp_comments WHERE comment_approved = '1' ORDER BY comment_date DESC LIMIT 50;
C. Check wp_options Table
sql
-- Look for suspicious entries
SELECT * FROM wp_options WHERE option_name LIKE '%hack%';
SELECT * FROM wp_options WHERE option_value LIKE '%<script%';
SELECT * FROM wp_options WHERE option_value LIKE '%base64%';
-- Check critical options
SELECT * FROM wp_options WHERE option_name IN ('siteurl', 'home', 'admin_email');
D. Clean Spam Content
sql
-- Delete spam posts (BE CAREFUL!)
DELETE FROM wp_posts WHERE post_content LIKE '%viagra%';
-- Delete spam comments
DELETE FROM wp_comments WHERE comment_content LIKE '%<a href%';
-- Remove suspicious options
DELETE FROM wp_options WHERE option_name = 'suspicious_option';
⚠️ BACKUP DATABASE FIRST before running DELETE queries!
Replace WordPress Core Files
Download fresh WordPress:
- Go to https://wordpress.org/download/
- Download latest version (or your current version)
- Extract ZIP file locally
Replace core files via FTP:
DO NOT delete these:
wp-config.php
(your database configuration)wp-content/
folder (themes, plugins, uploads).htaccess
REPLACE these folders/files:
/wp-admin/
(entire folder)/wp-includes/
(entire folder)- All files in root (except wp-config.php and .htaccess)
Steps:
1. Connect via FTP
2. Download wp-config.php as backup
3. Delete /wp-admin/ folder from server
4. Delete /wp-includes/ folder from server
5. Upload fresh /wp-admin/ folder
6. Upload fresh /wp-includes/ folder
7. Upload fresh root files (index.php, wp-login.php, etc.)
8. Restore your wp-config.php
Review and Clean Plugins
Identify problematic plugins:
A. Deactivate All Plugins
1. Dashboard → Plugins
2. Select all plugins
3. Bulk Actions → Deactivate → Apply
Can’t access dashboard? Via FTP:
- Rename
/wp-content/plugins/
to/wp-content/plugins-old/
B. Check Each Plugin
For each plugin:
- Is it from wordpress.org repository?
- Is it recently updated?
- Does it have good reviews?
- Is it nulled/pirated? (DELETE IMMEDIATELY)
C. Delete Suspicious Plugins
Red flags:
- Unknown plugins you didn’t install
- Plugins with random names (wp-system, wp-cache, etc.)
- Nulled/pirated premium plugins
- Plugins not updated in 2+ years
- Plugins from unknown sources
D. Reinstall Clean Versions
1. Delete plugin folder via FTP
2. Download fresh from wordpress.org
3. Upload via FTP or
4. Install from Dashboard → Plugins → Add New
Review and Clean Themes
A. Check Installed Themes
Dashboard → Appearance → Themes
Delete:
- Unused themes (keep only active theme + one default)
- Themes from unknown sources
- Nulled/pirated themes
- Old abandoned themes
B. Scan Active Theme
Check these files in /wp-content/themes/your-theme/
:
functions.php
(most commonly infected)header.php
footer.php
index.php
- Any
.php
files in theme root
C. Download Fresh Theme
If theme is from:
- WordPress.org: Download fresh copy
- ThemeForest: Download from your purchases
- Theme author: Download from official source
D. Replace Theme Files
1. Backup current theme (even if infected)
2. Delete theme folder via FTP
3. Upload fresh theme
4. Reconfigure theme settings if needed
Check Uploads Directory
Scan wp-content/uploads/
Look for:
.php
files (shouldn’t exist in uploads!).js
files.ico.php
files- Files with double extensions (.jpg.php)
- Recently uploaded suspicious files
Find PHP files in uploads:
Via SSH:
bash
find /path/to/wp-content/uploads/ -name "*.php"
Via FTP:
- Browse uploads folder
- Sort by “Type” or “Extension”
- Look for anything except images/videos/documents
Action:
- Delete any
.php
files from uploads - Check for suspicious image files with code injected
- Review recently uploaded files
Secure wp-config.php
Add security measures to wp-config.php:
php
<?php
/**
* WordPress Database Configuration
*/
define('DB_NAME', 'database_name');
define('DB_USER', 'database_user');
define('DB_PASSWORD', 'strong_password_here');
define('DB_HOST', 'localhost');
define('DB_CHARSET', 'utf8mb4');
define('DB_COLLATE', '');
/**
* Authentication Unique Keys and Salts
* Generate new ones at: https://api.wordpress.org/secret-key/1.1/salt/
*/
define('AUTH_KEY', 'put your unique phrase here');
define('SECURE_AUTH_KEY', 'put your unique phrase here');
define('LOGGED_IN_KEY', 'put your unique phrase here');
define('NONCE_KEY', 'put your unique phrase here');
define('AUTH_SALT', 'put your unique phrase here');
define('SECURE_AUTH_SALT', 'put your unique phrase here');
define('LOGGED_IN_SALT', 'put your unique phrase here');
define('NONCE_SALT', 'put your unique phrase here');
/**
* WordPress Database Table prefix
* Change from default wp_ to something unique
*/
$table_prefix = 'xyz_'; // Change this!
/**
* Security Enhancements
*/
// Disable file editing in dashboard
define('DISALLOW_FILE_EDIT', true);
// Disable plugin/theme installation
define('DISALLOW_FILE_MODS', true);
// Limit post revisions
define('WP_POST_REVISIONS', 3);
// Enable automatic updates
define('WP_AUTO_UPDATE_CORE', true);
// Force SSL for admin
define('FORCE_SSL_ADMIN', true);
// Hide WordPress version
define('WP_HIDE_VERSION', true);
/**
* Debugging (DISABLE on production!)
*/
define('WP_DEBUG', false);
define('WP_DEBUG_LOG', false);
define('WP_DEBUG_DISPLAY', false);
/* That's all, stop editing! Happy publishing. */
if ( !defined('ABSPATH') )
define('ABSPATH', dirname(__FILE__) . '/');
require_once(ABSPATH . 'wp-settings.php');
Change these immediately:
- Generate new security keys: https://api.wordpress.org/secret-key/1.1/salt/
- Change database table prefix (requires database changes too)
- Update database password
Set correct file permissions:
bash
# wp-config.php should be 640 or 600
chmod 600 wp-config.php
Update .htaccess File
Replace with clean WordPress .htaccess:
apache
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
# Additional Security Rules
# Protect wp-config.php
<files wp-config.php>
order allow,deny
deny from all
</files>
# Disable directory browsing
Options -Indexes
# Protect .htaccess
<files ~ "^\.htaccess">
order allow,deny
deny from all
</files>
# Block access to wp-includes folder
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^wp-admin/includes/ - [F,L]
RewriteRule !^wp-includes/ - [S=3]
RewriteRule ^wp-includes/[^/]+\.php$ - [F,L]
RewriteRule ^wp-includes/js/tinymce/langs/.+\.php - [F,L]
RewriteRule ^wp-includes/theme-compat/ - [F,L]
</IfModule>
# Block PHP execution in uploads
<Directory "/path/to/wp-content/uploads/">
<Files "*.php">
Order Deny,Allow
Deny from All
</Files>
</Directory>
# Protect against script injections
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{QUERY_STRING} (<|%3C).*script.*(>|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} GLOBALS(=|[|%[0-9A-Z]{0,2}) [OR]
RewriteCond %{QUERY_STRING} _REQUEST(=|[|%[0-9A-Z]{0,2})
RewriteRule ^(.*)$ index.php [F,L]
Hardening Phase
Set Correct File Permissions
Recommended permissions:
bash
# Directories: 755
find /path/to/wordpress/ -type d -exec chmod 755 {} \;
# Files: 644
find /path/to/wordpress/ -type f -exec chmod 644 {} \;
# wp-config.php: 600 (most secure)
chmod 600 wp-config.php
# .htaccess: 644
chmod 644 .htaccess
Via FTP (FileZilla):
1. Right-click on folder/file
2. File permissions
3. Set numeric value (755 for folders, 644 for files)
4. Check "Recurse into subdirectories" for folders
Enable Two-Factor Authentication
For WordPress Admin:
Method 1: Wordfence 2FA
1. Wordfence → Login Security
2. Two-Factor Authentication → Enable
3. Scan QR code with app (Google Authenticator, Authy)
4. Enter code to verify
5. Save recovery codes
Method 2: Two Factor Authentication Plugin
1. Install "Two Factor Authentication" plugin
2. Users → Your Profile
3. Two-Factor Options → Enable
4. Choose method (TOTP recommended)
5. Scan QR code with authenticator app
6. Test and save
Recommended 2FA apps:
- Google Authenticator (iOS/Android)
- Authy (iOS/Android/Desktop)
- Microsoft Authenticator
- 1Password (has built-in TOTP)
Limit Login Attempts
Install Limit Login Attempts Reloaded:
1. Plugins → Add New
2. Search "Limit Login Attempts Reloaded"
3. Install and Activate
4. Settings → Limit Login Attempts
5. Configure:
- Allowed retries: 3
- Minutes lockout: 20
- Hours until retries reset: 12
- Lockout: Increase to 24 hours after 4 lockouts
Change WordPress Login URL
Why? Bots constantly attack /wp-admin/
and /wp-login.php
Install WPS Hide Login:
1. Plugins → Add New
2. Search "WPS Hide Login"
3. Install and Activate
4. Settings → WPS Hide Login
5. Change login URL to something unique:
- Example: yoursite.com/my-secret-login-page
- Avoid: admin, login, wp-login
6. Save changes
7. IMPORTANT: Bookmark new login URL!
⚠️ WARNING: Save your new login URL or you’ll be locked out!
Disable XML-RPC (Common Attack Vector)
XML-RPC is used for:
- Pingbacks
- Trackbacks
- Remote publishing
- Mobile apps
If you don’t need it, disable it:
Method 1: Via Plugin
Install "Disable XML-RPC" plugin
Activate (no configuration needed)
Method 2: Via .htaccess
apache
# Block XML-RPC
<Files xmlrpc.php>
Order Deny,Allow
Deny from all
</Files>
Method 3: Via functions.php
php
// Disable XML-RPC
add_filter('xmlrpc_enabled', '__return_false');
Test if disabled:
- Visit: yoursite.com/xmlrpc.php
- Should show error or blank page
Disable File Editing in Dashboard
Already added to wp-config.php, but verify:
php
// In wp-config.php
define('DISALLOW_FILE_EDIT', true);
This prevents:
- Editing theme files from dashboard
- Editing plugin files from dashboard
- Hackers from modifying files if they breach admin
To edit files, you’ll need:
- FTP access
- File Manager in cPanel
- SSH access
Update Everything
Update in this order:
- WordPress Core
Dashboard → Updates
Update Now
- Plugins
Dashboard → Plugins
Check for updates
Update all plugins
- Themes
Dashboard → Appearance → Themes
Update available themes
- PHP Version
cPanel → MultiPHP Manager
Select PHP 8.0+ (check theme/plugin compatibility first)
- MySQL/MariaDB
Contact hosting for database version upgrade
Recommended: MySQL 8.0+ or MariaDB 10.5+
Enable automatic updates:
php
// In wp-config.php
// Core auto-updates
define('WP_AUTO_UPDATE_CORE', true);
// Plugin auto-updates (enable in Dashboard → Plugins)
// Theme auto-updates (enable in Dashboard → Themes)
Check Search Engine Status
Google Search Console:
1. Login to Google Search Console
2. Security & Manual Actions → Security Issues
3. Check for warnings
4. If warnings exist: Request Review
If your site was de-indexed:
1. Search Console → URL Inspection
2. Test live URL
3. Request Indexing
4. Submit updated sitemap
Bing Webmaster Tools:
Similar process for Bing
Check for security warnings
Request recrawl