WordPress sites get hacked primarily through three vectors: outdated plugins with known vulnerabilities, weak or reused admin passwords targeted by brute-force bots, and exposed default URLs (wp-login.php, xmlrpc.php) that automated scanners hit millions of times per day. The good news is that 80 percent of WordPress compromises are preventable with basic hardening steps that require no advanced technical knowledge and can be completed in a single afternoon.
Why WordPress Gets Hacked
WordPress's market share is its biggest security liability. At 43 percent of all websites, it is the single largest target for automated exploit tools. Attackers do not manually hack WordPress sites – they run bots that continuously scan millions of sites for known vulnerable plugin versions, weak passwords, and misconfigured files. The economics are simple: find one vulnerability in a popular plugin, automate its exploitation, and run it against every WordPress site on the internet.
Plugin vulnerabilities are the most common entry point. The WordPress plugin directory hosts over 60,000 plugins, and plugin code quality varies from enterprise-grade to abandoned personal projects with obvious security flaws. A single popular plugin with a SQL injection or file upload vulnerability affects every site that has not updated within days of the patch release. According to Wordfence's 2025 threat report, plugin vulnerabilities accounted for 71 percent of WordPress compromises tracked.
The predictable default configuration is the second major factor. Every WordPress installation has wp-login.php at the same URL, wp-admin at the same path, and xmlrpc.php enabled by default. Bots know exactly where to look. The xmlrpc.php endpoint alone receives thousands of brute-force authentication attempts per day on most public WordPress sites – it exists for legitimate XML-RPC applications but is exploited far more often than it is used legitimately.
Login Hardening (Steps 1 to 3)
Step 1: Enable two-factor authentication on all administrator accounts.
2FA is the single highest-impact security step you can take. Even if an attacker obtains your password through a data breach or brute force, they cannot log in without the second factor. Install the "Two Factor Authentication" plugin by Plugin Contributors or use Wordfence Login Security (free). Configure it to require a time-based one-time password (TOTP) from Google Authenticator, Authy, or a hardware key for all accounts with administrator, editor, or author roles. 2FA alone would have prevented the majority of the credential-based compromises in WordPress breach data.
Step 2: Limit login attempts.
WordPress allows unlimited login attempts by default, which makes brute-force attacks trivial. Install "Limit Login Attempts Reloaded" (free, 2+ million active installations) and configure it to lock out an IP after 3 failed attempts for 20 minutes, with permanent lockout after 4 lockouts. Review the lockout log weekly for the first month – if you see hundreds of lockouts from different IPs, you have an active brute-force campaign against your site and should implement Step 3 immediately.
Step 3: Change the wp-admin URL.
Install WPS Hide Login and change your login URL from the default /wp-login.php to something unpredictable (/manage-2026 or /site-access or any string not in a wordlist). This does not stop a determined attacker but eliminates the automated bot traffic entirely – bots scan for the default URL and move on when they do not find it. Combined with login attempt limiting, this reduces brute-force traffic to near zero. Do not forget the new URL or you will lock yourself out (save it in a password manager).
File Permissions and Configuration (Steps 4 to 5)
Step 4: Set correct file permissions.
Incorrect file permissions are one of the most common security misconfigurations on shared hosting. The correct permissions for a WordPress installation are: directories set to 755 (owner can read/write/execute, group and world can read/execute), files set to 644 (owner can read/write, group and world can read only), and wp-config.php set to 600 (owner can read/write only, no one else can read it). Run these commands via SSH or ask your host to apply them:
find /var/www/yoursite -type d -exec chmod 755 {} ;
find /var/www/yoursite -type f -exec chmod 644 {} ;
chmod 600 /var/www/yoursite/wp-config.php
Never set any file or directory to 777 (world-writable). Hosts that require 777 for plugins to write files are running an insecure configuration – the underlying issue is that the web server is not running as the file owner.
Step 5: Disable XML-RPC if you do not need it.
XML-RPC is a legacy protocol that allows remote publishing to WordPress. Most sites do not need it. Add this rule to your .htaccess file to block all XML-RPC access:
# Block XML-RPC
<Files xmlrpc.php>
Order Deny,Allow
Deny from all
</Files>
If you use the WordPress mobile app, Jetpack, or any tool that requires XML-RPC, skip this step or whitelist only the specific IPs that need access.
Plugin Hygiene (Steps 6 to 7)
Step 6: Remove unused plugins and themes immediately – do not just deactivate.
Deactivated plugins are still on your file system and can contain vulnerabilities. Go to Plugins > Installed Plugins and delete every plugin that is deactivated and not needed. Do the same for themes in Appearance > Themes – keep your active theme and one default theme (Twenty Twenty-Four) as a troubleshooting fallback, delete everything else. The same applies to inactive themes: their files exist on disk and can be exploited even if not activated. This reduces your attack surface by eliminating code that is not providing any value.
Step 7: Keep everything updated – WordPress core, plugins, and themes.
Updates are the primary defense against known vulnerabilities. The gap between a vulnerability being disclosed and automated exploitation being widespread is often less than 48 hours. Enable automatic background updates for WordPress core minor versions (security patches) and configure a weekly schedule for reviewing plugin and theme updates. Tools like ManageWP or MainWP let you manage updates across multiple sites from a single dashboard. The WP Activity Log plugin provides an audit trail if an update causes issues and you need to identify what changed.
WAF and Monitoring Setup (Steps 8 to 10)
Step 8: Install a Web Application Firewall.
A WAF intercepts malicious requests before they reach WordPress. The two primary options for WordPress are Wordfence (plugin-level WAF, free tier available) and Cloudflare (network-level WAF, free tier available). Wordfence's free tier blocks the most common exploit patterns and includes malware scanning. Cloudflare's free WAF provides network-level protection before traffic even reaches your server, which reduces server load from attack traffic and blocks volumetric attacks.
For most sites, Cloudflare (free tier) as the first line of defense plus Wordfence (free tier) as the application-layer defense is the recommended combination. Cloudflare requires pointing your domain's nameservers to Cloudflare – a 5-minute change in your domain registrar. Wordfence installs like any other plugin.
Step 9: Move wp-config.php above the web root.
By default, wp-config.php lives in the same directory as your WordPress files, which are web-accessible. If your server is misconfigured and PHP is not processing .php files (which can happen during server migrations), the raw contents of wp-config.php – including your database credentials – are served as plain text. Moving wp-config.php one directory above your web root makes it inaccessible via HTTP even if PHP stops working. WordPress automatically looks for wp-config.php one directory above wp-settings.php, so no configuration change is needed after moving it.
Step 10: Disable PHP execution in the uploads directory.
The uploads directory (/wp-content/uploads) should contain only media files – images, PDFs, videos. It should never execute PHP. Attackers who gain file upload capabilities (via a vulnerable plugin) will often upload a PHP web shell to this directory and execute it to gain full server access. Block PHP execution in uploads by adding a .htaccess file in /wp-content/uploads/ with this content:
<Files *.php>
deny from all
</Files>
For nginx servers, add this to your site configuration: location ~* /wp-content/uploads/.*.php$ { deny all; }
For professional implementation of all these measures, the WordPress security service covers all 12 steps plus ongoing monitoring configuration.
Backups and Advanced Hardening (Steps 11 to 12)
Step 11: Set up automated daily backups to off-site storage.
Backups are not a security measure against getting hacked – they are your recovery mechanism when everything else fails. Without a clean off-site backup, a successful compromise can mean hours of downtime and permanent data loss. Install UpdraftPlus (free) and configure it to run daily backups of both your files and your database, stored automatically to an off-site location: Google Drive, Dropbox, Amazon S3, or similar. Critical: the backup destination must be different from your server. A backup stored on the same server as the compromised site is useless if the server is wiped.
Test your backups quarterly by doing an actual restore to a staging environment. A backup that cannot be restored is not a backup. Most people discover their backup restore process does not work when they are in the middle of a crisis – test it before you need it.
Step 12: Monitor for file integrity changes with Wordfence or Sucuri.
WordPress malware infections often involve modifying legitimate WordPress core files to inject malicious code. File integrity monitoring compares your current files against a known-clean baseline and alerts you when changes are detected. Wordfence (free) includes file integrity scanning – run a manual scan monthly and configure email alerts for high-severity detections. Sucuri SiteCheck (free, web-based) provides an external scan of your site for malware signatures, blacklist status, and obvious injections without installing a plugin.
For sites handling e-commerce or sensitive user data, consider a professional monitoring service: Sucuri's platform ($199/year) provides continuous monitoring, CDN, and guaranteed malware removal with a response SLA. The cost is typically recovered in the first month by preventing a single compromise that would cost more in downtime, cleanup, and lost customer trust. The malware removal service is also available for existing infections that need professional remediation.
If Your Site Gets Hacked: Step-by-Step Cleanup
If your site has already been compromised, take these steps in order. Speed matters – the longer an infected site runs, the more data it exfiltrates and the further it spreads to your other hosting accounts if the server is shared.
Step 1: Put the site in maintenance mode. Visitors should not see defaced content or be exposed to malware delivered from your site. Most hosts provide a "suspend site" option in cPanel. Alternatively, add a .maintenance file to the WordPress root directory, which triggers WordPress's built-in maintenance mode.
Step 2: Change all passwords immediately. WordPress admin account, hosting panel (cPanel/Plesk), FTP/SFTP credentials, and the MySQL database password. If you use the same password elsewhere, change it there too. The attack may have originated from a credential stuffing attack using a password reused from a breached service.
Step 3: Run a Wordfence scan. Wordfence's scanner identifies infected files, suspicious code patterns, and recently modified files. Review the high-severity results first. Note the list of files flagged as modified or infected – you will need this for the cleanup.
Step 4: Restore from a clean backup if available. If you have a verified clean backup from before the infection date, restoring from backup is faster and more reliable than manual file cleanup. After restoring, immediately update everything (core, plugins, themes) and apply all the hardening steps above. The vulnerability that allowed the initial compromise is still present in the restored files – patch it before going live again.
Step 5: Manual cleanup if no clean backup. Replace all WordPress core files with a fresh download from wordpress.org (do not touch wp-content). Review each file in wp-content/plugins and wp-content/themes – compare against original plugin files from the WordPress.org repository. Remove any unrecognized files. Look for base64-encoded strings (a common malware obfuscation technique) in PHP files: grep -r "base64_decode" /var/www/yoursite/wp-content/ and review each result.
Step 6: Harden before going live. Apply all 12 steps above before bringing the site back online. If you restored a clean backup, verify the vulnerability that was exploited has been patched (usually a plugin update). If you are unsure how the site was compromised, review your server access logs for the dates around the infection with your host's security team.
Step 7: Request a Google review if blacklisted. Check Google's Transparency Report and use the URL Inspection tool in Google Search Console to see if your site has been flagged for malware. If it has, clean the site completely, then submit a reconsideration request via Search Console. Review times are typically 1 to 3 business days.