This article is going to explain what user enumeration is, and how it can make your WordPress site vulnerable to intrusion. Then, I’m going to explain how to prevent it from happening.

At the company I work for, one of the plugins we require our WordPress clients to have is WordFence. This plugin does a lot of things, one of which is keep a running report of login attempts. If you have this plugin installed on your site, I suggest you take a look at this report on occasion.

My guess is you will see at some point, repeated and bizarre login attempts have been made. This kind of pattern is indicative of brute force attacks. These attacks occur when a hacker tries to log in using a username many times until a password works.

If you haven’t guessed already, this is why many sites enforce strong password rules. It’s easy to brute force an account when the password is “password” or “1234.” Preventing user enumeration is a good preemptive step to heading off brute force attacks.

 

What is User Enumeration?

User Enumeration is a type of scan that hackers run on a site to find potential usernames of site administrators or contributors. These scans tend to be conducted using malicious scripts that search for numerical user data, in particular, user IDs.

Let’s lay down some fundamental assumptions about WordPress:

  • Most WordPress websites use pretty permalinks (i.e. mysite.com/page-title/ rather than mysite.com/?p=123).
  • The WordPress MySQL database is full of tables holding valuable content and information all with numerical identifiers.
  • Therefore, all pages, posts, users, etc. have a static ID number.

In its most simple form, an enumeration scan tries to validate user IDs, and then convert the user ID to a username. This is an easy task on a website with pretty permalinks enabled. All one has to do, is enter the URL mysite.com/?author=x. X can be substituted for any integer. Much of the time, a redirect to the permalink version of that page will take place and could, by default, expose a username.

Now lets imagine this on a grander scale. A script that performs that process in repetition, replacing X with any integer in a defined range, could be dangerous. If a site has many users, a hacker could work up a username list very fast. If any of those users have “password” as their password, a brute force is peas and carrots.

 

Blocking User Enumeration Scans

There are two ways to do this. The first is by modifying the .htaccess file, and the second is by modifying functions.php. The .htaccess file tells Apache servers how to process configuration changes in a directory (for example: handling of pretty permalinks). The functions.php file is a layer between your theme and the WordPress core. It acts like a plugin, telling your theme how to communicate with WordPress and holds additional functionality like custom hooks, actions, and filters.

Either of these files can  be used by hackers to find holes and areas where they can dig further for user information. So lets modify these to prevent that.

 

Blocking With .htaccess

Open your .htaccess file which is found in your WordPress root directory. If you don’t have pretty permalinks enabled you probably don’t have this file and should go to the next section. Once you have the file open, add these directives:

# Block User ID Phishing Requests
<IfModule mod_rewrite.c>
  RewriteCond %{QUERY_STRING} ^author=([0-9]*)
  RewriteRule .* http://mysite.com/? [L,R=302]
</IfModule>

Note: be sure to replace mysite.com/ with your own website’s domain name.

In plain English, this code gives the following directives: if a query string begins with the word “author” and includes an integer between 0-9, then redirect to mysite.com.

 

Blocking With Functions.php

In order to prevent user enumeration scans from being carried out, we can also modify the functions.php file. Open the file and add the following code:

// block WP enum scans
// http://m0n.co/enum
if (!is_admin()) {
  // default URL format
  if (preg_match('/author=([0-9]*)/i', $_SERVER['QUERY_STRING'])) die();
  add_filter('redirect_canonical', 'shapeSpace_check_enum', 10, 2);
}
function shapeSpace_check_enum($redirect, $request) {
  // permalink URL format
  if (preg_match('/\?author=([0-9]*)(\/*)/i', $request)) die();
  else return $redirect;
}

In plain English, here is what is happening in that code: if the script is requesting a page within the WordPress admin area, block it from running a query string for the author archive.

All Set

By doing these two simple things, you can help secure your WordPress website from user enumeration scans. This certainly won’t prevent hackers from trying to break in, but it will definitely make it harder for them to acquire necessary information used in common hack attempts.