WordPress Security Hardening: Auditing Plugins, REST API, and XML-RPC Vectors
A production-grade hardening guide for WordPress sites. How to disable XML-RPC, prevent user enumeration via REST API, lock down wp-config.php and debug logs, and eliminate top attack vectors in Nginx.
Powering over 40% of the world's websites, WordPress remains the most heavily targeted CMS platform on the internet. Automated botnets continuously scan millions of WordPress instances daily, hunting for vulnerable third-party plugins, unauthenticated user enumeration endpoints, and left-behind configuration files that yield administrative access or remote code execution.
While many administrators attempt to solve security by installing monolithic, performance-degrading security plugins, the most robust WordPress hardening is achieved at the server and architectural levels—locking down sensitive endpoints in Nginx, hardening PHP execution parameters, and disabling legacy vectors like XML-RPC.
1. Neutralizing XML-RPC (xmlrpc.php) to Prevent Brute-Force & DDoS
WordPress originally introduced XML-RPC to facilitate remote publishing from mobile apps. Today, it represents a primary vector for credential brute-forcing via system.multicall (which allows thousands of password attempts within a single HTTP request) and pingback amplification DDoS attacks. Modern WordPress setups utilizing the REST API have no need for XML-RPC.
# Nginx block to immediately drop all requests to xmlrpc.php
location = /xmlrpc.php {
deny all;
access_log off;
log_not_found off;
return 403;
}
2. Preventing User Enumeration via the WordPress REST API
By default, accessing /wp-json/wp/v2/users on any standard WordPress installation returns a complete JSON list of all registered author and administrator usernames. Attackers use this enumeration endpoint to gather valid usernames, reducing their subsequent attack to simple password guessing.
// Add to theme's functions.php or custom security mu-plugin:
add_filter('rest_endpoints', function($endpoints) {
if (isset($endpoints['/wp/v2/users'])) {
if (!current_user_can('list_users')) {
unset($endpoints['/wp/v2/users']);
}
}
if (isset($endpoints['/wp/v2/users/(?P<id>[\\d]+)'])) {
if (!current_user_can('list_users')) {
unset($endpoints['/wp/v2/users/(?P<id>[\\d]+)']);
}
}
return $endpoints;
});
3. Locking Down Sensitive Core Files (wp-config.php & debug.log)
When debugging WordPress issues, developers frequently set WP_DEBUG_LOG to true in wp-config.php. If the resulting /wp-content/debug.log file is publicly accessible, attackers download complete PHP stack traces revealing database credentials, API integration tokens, and file system paths.
# Block access to sensitive WordPress configuration and debug logs
location ~* /(wp-config\.php|readme\.html|license\.txt|debug\.log) {
deny all;
return 404;
}
# Block access to the install script after site initialization
location = /wp-admin/install.php {
deny all;
return 404;
}
4. Disabling Script Execution in the /wp-content/uploads/ Directory
The media uploads directory is writable by design. If a vulnerable plugin allows arbitrary file upload, an attacker will upload a PHP web shell into /wp-content/uploads/. Configure your web server to strictly refuse script execution inside this directory.
# Disallow executing PHP scripts inside upload directories
location ~* /wp-content/uploads/.*\.php$ {
deny all;
return 404;
}
5. Plugin Supply Chain Governance & File Editing Restrictions
Over 90% of WordPress vulnerabilities originate in third-party plugins and themes rather than core code. Audit plugins quarterly, eliminate abandoned extensions, and disable the in-dashboard theme editor by placing define('DISALLOW_FILE_EDIT', true); in wp-config.php to prevent attackers from editing code even if admin credentials are compromised.
Developer Security Checklist
- ✓ Block public HTTP access to /xmlrpc.php via Nginx or .htaccess
- ✓ Restrict /wp-json/wp/v2/users to authenticated administrator sessions
- ✓ Disable PHP execution within /wp-content/uploads/ directory
- ✓ Prevent public access to debug.log, wp-config.php, and install.php
- ✓ Disable file editing in wp-config.php (DISALLOW_FILE_EDIT = true)
- ✓ Run regular perimeter scans with Site Check to verify endpoint closure
Security Auditor Synthesis & Key Takeaways
When shipping production web applications and vibe-coded projects built on modern stacks (Next.js, Astro, React, Supabase), perimeter security cannot be an afterthought. Over 85% of customer data leaks and database compromises do not stem from sophisticated zero-day exploits, but rather from trivial misconfigurations: orphaned staging endpoints, exposed environment files, overly permissive CORS policies, and disabled Row Level Security (RLS) rules.
Automated perimeter scanning with Site Check proactively catches these signatures across 36 critical attack vectors, equipping engineering teams and vibe-coders with immediate actionable remediation guides before automated scanning botnets discover the exposed endpoints.