What is User Enumeration?
WordPress websites may reveal whether a username exists on system through the author
query variable. When a web app leaks information about whether a username exists or doesn’t exist, this is called user enumeration. A common example is when you see a validation notice telling you that the username is already in use, or that the provided password is wrong (instead of the username OR password). More information can be found at OWASP.
How to Stop User Enumeration in WordPress
There are a few ways to do this, basically we want to remove the ability for bots, or users, to visit our block and request an author archive page. If you’ve noticed a large number of requests to /?author=X
in your logs, then you’re being hit by bots trying to do this. Here are a few approaches I’ve used, or would suggest, to combat this.
Option #1: In your Theme’s functions.php
The universal approach involves adding a small bit of code to your WordPress theme or plugin in order to re-direct malicious requests that attempt to enumerate users. Here’s a function I commonly use to do this:
/**
* Block User Enumeration
*/
function kl_block_user_enumeration_attempts() {
if ( is_admin() ) return;
$author_by_id = ( isset( $_REQUEST['author'] ) && is_numeric( $_REQUEST['author'] ) );
if ( $author_by_id )
wp_die( 'Author archives have been disabled.' );
}
add_action( 'template_redirect', 'kl_block_user_enumeration_attempts' );
Option #2: .htaccess Rules for Apache Servers
If your WordPress site is run on a server with Apache, then you can add the following rule to the .htaccess
file in your installations root folder.
# Block Attempts to Enumerate WordPress Users
RewriteCond %{REQUEST_URI} !^/wp-admin [NC]
RewriteCond %{QUERY_STRING} author=\d
RewriteRule .* - [R=403,L]
MOST of the other htaccess approaches our there use a 301 redirect, but I suggest sending them to a 403 Forbidden response as suggested by WASP standards.
Option #3: Config Rules for nginx Servers
If your WordPress website is powered by nginx, then the following rule can be added to the location / { ... }
block of your WordPress sites’ *.conf
file to send these requests to a 403 Forbidden
error page, which seems appropriate.
# Block user enumeration
if ( $query_string ~ "author=([0-9]*)" ) { return 403; }
The full location
block would then look something like this:
location / {
index index.php;
try_files $uri $uri/ /index.php?$args;
# Block user enumeration
if ( $query_string ~ "author=([0-9]*)" ) { return 403; }
}
That should do it, using any of the above method you should stop those nasty user enumeration bots in their tracks. As always, if you have any questions let me know!