WordPress powers 43% of the web and is the most targeted CMS by attackers. This practical guide covers the essential steps to harden your WordPress site against the most common attack vectors.
WordPress's popularity is both its strength and its weakness. With over 60,000 plugins in the official repository and millions of themes, the attack surface is enormous. The most common entry points are:
This is the single most impactful thing you can do.
# Check for updates via WP-CLI
wp core check-update
wp plugin list --update=available
wp theme list --update=available
# Check for updates via WP-CLI
wp core check-update
wp plugin list --update=available
wp theme list --update=available
The login page receives thousands of brute-force attempts per day on any public WordPress site.
Option A: IP restriction (Apache .htaccess)
<Files wp-login.php>
Order Deny,Allow
Deny from all
Allow from YOUR.IP.ADDRESS
</Files>
<Files wp-login.php>
Order Deny,Allow
Deny from all
Allow from YOUR.IP.ADDRESS
</Files>
Option B: Two-factor authentication Install WP 2FA or Wordfence and enable 2FA for all admin accounts.
Option C: Rename the login URL Use a plugin like WPS Hide Login to move the login page to a non-standard URL.
XML-RPC is a legacy remote publishing protocol that is almost never needed on modern sites. It is frequently abused for:
Disable via .htaccess:
<Files xmlrpc.php>
Order Deny,Allow
Deny from all
</Files>
<Files xmlrpc.php>
Order Deny,Allow
Deny from all
</Files>
Or via wp-config.php:
add_filter('xmlrpc_enabled', '__return_false');
add_filter('xmlrpc_enabled', '__return_false');
WordPress adds its version number to the HTML source and RSS feeds by default. Attackers use this to target known vulnerabilities.
Add to your theme's functions.php:
// Remove version from head
remove_action('wp_head', 'wp_generator');
// Remove version from scripts and styles
function remove_version_from_scripts($src) {
if (strpos($src, 'ver=') !== false) {
$src = remove_query_arg('ver', $src);
}
return $src;
}
add_filter('style_loader_src', 'remove_version_from_scripts');
add_filter('script_loader_src', 'remove_version_from_scripts');
// Remove version from head
remove_action('wp_head', 'wp_generator');
// Remove version from scripts and styles
function remove_version_from_scripts($src) {
if (strpos($src, 'ver=') !== false) {
$src = remove_query_arg('ver', $src);
}
return $src;
}
add_filter('style_loader_src', 'remove_version_from_scripts');
add_filter('script_loader_src', 'remove_version_from_scripts');
Also delete readme.html from your WordPress root — it explicitly states the version number.
# WordPress root
find /var/www/html -type d -exec chmod 755 {} ;
find /var/www/html -type f -exec chmod 644 {} ;
# wp-config.php should be more restrictive
chmod 600 /var/www/html/wp-config.php
# WordPress root
find /var/www/html -type d -exec chmod 755 {} ;
find /var/www/html -type f -exec chmod 644 {} ;
# wp-config.php should be more restrictive
chmod 600 /var/www/html/wp-config.php
Never set directories to 777 — this allows any process on the server to write files.
Add these to your .htaccess or Nginx config:
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()"
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()"
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
For most WordPress sites, a security plugin provides the best balance of protection and ease of use:
WebGuard's scanner includes dedicated WordPress checks — it will detect exposed wp-login.php, active XML-RPC, version disclosure, readme.html, and more.
Scan your WordPress site free [blocked] and get a prioritised fix list in under a minute.
Free scan, no account required. See exactly which issues affect your site.
Start Free ScanFrom missing security headers to exposed configuration files, these are the vulnerabilities WebGuard finds most frequently — and they're all fixable in under an hour.
UK online retailers face GDPR fines, PCI DSS obligations, and increasingly sophisticated skimming attacks. Here's how to protect your customers and your business.
Passwords alone are no longer sufficient protection. 2FA blocks over 99% of automated account takeover attacks. Here's how to implement it across your website and admin tools.