WordPress Security Checklist 2026 — 11 Things Every Site Must Pass
WordPress runs about 43% of all websites on the internet. It's the most popular CMS — and consequently the most targeted. Almost every WP exploit chain we see starts with the same fingerprinting steps: identify the version, enumerate users, look for misconfigured backups, find vulnerable plugins. Most of these are trivial to fix — once you know they exist.
This checklist covers the 11 most exploited issues in WordPress security audits. We've seen sites running for years with all 11 problems active. Each item below explains what attackers do with it and how to fix it.
1. Update WordPress core (and turn on auto-updates)
Outdated WordPress is the single biggest entry point. Versions before 6.0 have multiple known CVEs. Attackers fingerprint your version from /readme.html, the <meta name="generator"> tag, asset URLs (?ver=X.Y.Z), or your RSS feed.
Fix:
- Enable auto-updates: Dashboard → Updates → enable "Automatic updates" for major releases
- Add to wp-config.php:
define('WP_AUTO_UPDATE_CORE', true); - Hide version: in functions.php →
remove_action('wp_head', 'wp_generator');
2. Block username enumeration (3 vectors)
WordPress leaks usernames through three independent vectors. Most sites only block one.
- ?author=N redirects — visiting
yoursite.com/?author=1redirects to/author/admin/revealing username "admin" - REST API —
/wp-json/wp/v2/usersreturns the full user list as JSON - Login error oracle — wp-login.php says "Unknown username" vs "Wrong password", letting attackers test if a username exists
Fix all three:
# .htaccess — block ?author=N
RewriteCond %{QUERY_STRING} author=\d+ [NC]
RewriteRule ^ /? [L,R=302]For REST API, install a plugin like Disable WP REST API or add a filter requiring authentication on user endpoints. For the login oracle, in functions.php:
add_filter('login_errors', function() { return 'Invalid login.'; });3. Disable XML-RPC (or whitelist)
xmlrpc.php is one of the worst-kept WordPress secrets. It's used for two attacks:
- Brute-force amplification — using
system.multicall, an attacker tests 1000+ password combinations in a single HTTP request, bypassing wp-login.php rate limits. - Pingback DDoS — your site becomes part of a DDoS attack against someone else, sending hundreds of HTTP requests on command.
Most modern WordPress sites don't need XML-RPC at all. The Block Editor uses the REST API instead. Disable it:
# functions.php
add_filter('xmlrpc_enabled', '__return_false');
# OR .htaccess (firmer)
<Files "xmlrpc.php">
Order Allow,Deny
Deny from all
</Files>4. Delete wp-config.php backup files
This is critical severity— if found, it's game over in 30 seconds. Common leftover files:
- wp-config.php.bak
- wp-config.php.old
- wp-config.php.swp (vim crash recovery)
- wp-config.php.save
- wp-config.php~ (some editors)
Apache serves these as text/plain — exposing your database password in clear text. Anyone who guesses the URL gets full DB access.
Fix:
# Delete them via SSH
find /var/www -name "wp-config.php.*" -delete
# Block them in .htaccess
<FilesMatch "\.(bak|backup|old|orig|original|tmp|swp|swo|save|swn|~)$">
Order Allow,Deny
Deny from all
</FilesMatch>5. Disable WP_DEBUG_LOG in production
/wp-content/debug.log is publicly accessible by default if WP_DEBUG_LOG is enabled. It contains PHP errors, stack traces, and sometimes database queries with user data.
In wp-config.php for production:
define('WP_DEBUG', false);
define('WP_DEBUG_LOG', false);
define('WP_DEBUG_DISPLAY', false);6. Disable directory listing
If Options +Indexes is enabled, attackers can browse your /wp-content/uploads/, /plugins/, and /includes/ directories — seeing every file you have. Disable it:
# .htaccess root
Options -Indexes
# OR add empty index.html to each sensitive directory7. Move admin path + add 2FA
/wp-admin and /wp-login.php are the universal entry points every WordPress bot tries first. With no rate-limit and no 2FA, brute-forcing passwords is trivial. Two minimum mitigations:
- WPS Hide Login plugin — change /wp-admin to /my-secret-path
- Two Factor Authentication plugin (or Wordfence) — require TOTP / email code
8. Update plugins (#1 attack vector)
Plugins cause about 90% of WordPress hacks. Old WPBakery, Contact Form 7, RevSlider, Elementor — all have CVEs in older versions. Some attackers maintain databases of vulnerable plugin URLs and just spray exploits at IP ranges.
- Enable plugin auto-updates: Plugins → check "Auto-updates" for each
- Remove inactive plugins (they're still vulnerable even when off)
- Audit which plugins you actually use; uninstall the rest
9. Hide plugin/theme paths
Even if plugins are up to date, exposing them in HTML helps attackers fingerprint your stack. Page source contains URLs like/wp-content/plugins/woocommerce/... revealing every plugin you use. Use Hide My WP or WP Hide to obfuscate paths.
10. Remove readme.html
The /readme.htmlfile is shipped with every WordPress install. It explicitly says "This is WordPress" and reveals the version. Delete it from production — it serves no purpose.
11. Restrict REST API
/wp-json/ exposes a wealth of metadata even without authentication: post types, taxonomies, plugin data, sometimes user lists. Lock it down to authenticated users only:
add_filter('rest_authentication_errors', function( $result ) {
if (true === $result || is_wp_error($result)) return $result;
if (!is_user_logged_in()) {
return new WP_Error('rest_not_logged_in', 'Logged-in users only.', array('status' => 401));
}
return $result;
});How to check all 11 in one click
Manually testing all 11 takes hours. AuditCore's WordPress scanner runs all of these in about 6 seconds — and crucially, tests them in the way attackers actually do (3 user enum vectors, multiple version detection methods, etc).
The free trial scans your homepage. The Starter plan ($29 one-time) covers up to 25 pages with full WP-specific checks plus generic security (headers, SSL, ports, sensitive files). Unlimited rescans of that site.
Run a free WordPress audit and see how many of the 11 checks you currently fail. Most sites we scan fail at least 5.