WordPress hardening checklist with copy-paste fixes
Updates matter most. After that, these small changes close the doors attackers try first.
1. Keep everything updated
Turn on auto-updates for plugins and themes (Plugins → Enable auto-updates). Remove anything you don’t use: deactivated plugins can still be exploited.
2. Disable the built-in file editor
Add to wp-config.php, above “That’s all, stop editing!”:
define( 'DISALLOW_FILE_EDIT', true );3. Block XML-RPC (if you don’t use it)
Jetpack and some mobile apps use XML-RPC. If you don’t, block it at the server:
<Files "xmlrpc.php">
Require all denied
</Files>location = /xmlrpc.php { deny all; }4. Stop listing usernames
Hide the REST API user list from visitors who aren’t logged in (as a must-use plugin in wp-content/mu-plugins/):
<?php
add_filter( 'rest_endpoints', function ( $endpoints ) {
if ( ! is_user_logged_in() ) {
unset( $endpoints['/wp/v2/users'], $endpoints['/wp/v2/users/(?P<id>[\d]+)'] );
}
return $endpoints;
} );Also check that author archives (/?author=1) don’t reveal login names. Set each user’s “Display name publicly as” to something other than the login.
5. No PHP in uploads
Uploads should only ever hold media. Put this in wp-content/uploads/.htaccess:
<FilesMatch "\.(php|phtml|phar)$">
Require all denied
</FilesMatch>location ~* ^/wp-content/uploads/.*\.(php|phtml|phar)$ { deny all; }6. Protect wp-config.php and logins
- Make
wp-config.phpreadable only by its owner (permissions600or640, depending on your host). - Never leave
wp-config.php.bak,.oldor.zipcopies in the web root. - Use two-factor authentication and limit login attempts for admin accounts.
- Keep
WP_DEBUG_DISPLAYoff in production, so errors never show on screen.