How to prevent username enumeration vulnerability in Drupal

How to prevent username enumeration vulnerability in Drupal

These days everyone is trying to pay attention to website security. Great effort. But as you hopefully know, the real security is the security at every level. Let’s review the very generic and common security feature, such as the username and password pair to secure login forms in millions of web applications.

In the perfect scenario you would create a very unique and hard to guess username along with strong password (if your username is admin, bad luck!). In this case, whenever someone will be attempting a dictionary attack against your website, not only passwords needs to be discovered but usernames too. This makes the username/password security alone the strongest. In such scenario leaked username makes it only 50% success of a website breach (with password to be the remaining 50%) and gives your login form maximum protection possible.

 

What is Username Enumeration Vulnerability

Username enumeration is a type of vulnerability in web applications, where it is possible to find exact usernames or to confirm that a guessed (or leaked) username exists in the system based on system response. For example the password reset form may return different response based on the fact that the username exists in the system versus the opposite.

 

Username Enumeration Vulnerability in Drupal

The username enumeration vulnerability existed in Drupal likely forever. The Drupal community just did not pay enough attention to it until recently. Some modules (such as pathauto) made this vulnerability even worse (see below).

There is a lot of sceptical opinions about this vulnerability in Drupal. In particular, the Disclosure of usernames and user ids is not considered a weakness page on Drupal.org. However in certain cases disclosure of a username or existence of an email address in a website could be quite big deal (e.g. a dating website or websites for people with special interests).

Luckily there is movement in Drupal community, such as User enumeration vulnerability within Drupal Google group, also a patch effort hide usernames from users without the “access user profiles” permission

 

How to exploit the Username Enumeration Vulnerability in Drupal

In Drupal the username enumeration vulnerability could be exploited in a few scenarios:

  1. By submitting the password reset form (/user/password) with random usernames and capturing the response difference. If the username exists in the system, the response given by Drupal is different compared to the opposite.
  2. By enumerating user alias URLs such as /user/1, /user/2 and so on. Thanks to the great pathauto module, such request would redirect to an alias URL containing the username. For example, navigating to /user/1 might redirect you to /users/admin, where ‘admin’ is the username for user 1. This redirect was created and was functional by default until the Drupal 8 version of the module came out. Such redirect was making it super easy to get all usernames from a Drupal website.
  3. In the scenario above, Drupal permissions system was returning response code 403 if the user existed in the system or 404 if the one did not. Navigating to a URL like /users/admin would trigger a 403 response for an anonymous visitor, indicating that the username admin exists in the system. If 404 response code was given, this would indicate the absence of such user.

How to prevent username enumeration in Drupal

Scenario 1

To eliminate the vulnerability – download and install the Username Enumeration Prevention module https://www.drupal.org/project/username_enumeration_prevention

Scenario 2

First of all, identify if you have the pathauto module installed.

If you have the pathauto module enabled, then check if your website is vulnerable by following these 2 steps

  1. Go to /user/1 page as an anonymous user and check if your Drupal website redirects you to a URL similar to users/admin (or other, based on your pathauto alias for users and user 1 username). If the redirect happened, you would likely see your 403 Access Denied page.
  2. Pick the highest random number of a user ID that does not exist, say 9999999. Then go to /user/9999999 URL. This will likely show you the 404 Page Not Found page.

If both cases above worked as described for you, your website is vulnerable to the Username Enumeration vulnerability.

To resolve the vulnerability, your actions will depend on your Drupal version.

Drupal 7

  • Go to URL aliases page /admin/config/search/path/patterns
  • Check USER PATHS fieldset – pattern for user account page paths – it likely contains something like users/[user:name]. Remove this value and click Save the configuration.
  • Click the Delete Aliases tab or go to /admin/config/search/path/delete_bulk
  • Select Users checkbox and click Delete aliases now! button
  • Cleare Drupal cache
  • Log out or use an Incognito mode to repeat steps to identify if redirect from /user/1 to the alias URL happens. It should give you 403 Access Denied page, but at least the redirect to a URL that includes username does not happen.
    How to disable username enumeration via pathauto automated alias in Drupal 7

 

Drupal 8

  • Go to URL Aliases -> Patterns page (/admin/config/search/path/patterns)
  • Check if you have user redirect setup
  • Click Edit link
  • Uncheck Enabled checkbox
  • Save the configuration
  • Cleare caches
  • Use incognito mode in browser to access the /user/1 URL and confirm the URL does not change and you get Access denied
    Username Enumeration caused by Pathauto module alias

 

Scenario 3

There is a collaborative work on Drupal 8 patch aiming to give Drupal website administrator control over the exposure of usernames. Please help out to complete and test the patch.

I did not find any indications about a module or patch for Drupal 7, however, it is likely to be possible to use hook_page_alter() or hook_boot() to set a simple condition and return 404.

<?php

/**
 * Implements hook_page_alter().
 */
function custommodule_page_alter(&$page) {
  if (!user_access('access user profiles')) {
    if (arg(0) == 'user' && is_numeric(arg(1))) {
      // Return 404 unconditionally.
      drupal_not_found();
    }
  }
}

 

I will be testing this code against Drupal 7 installation (likely with pathauto module redirecting to user profile aliased profile – as described in the Scenario 2) to see if this works. Come back soon for the final code.

Drupal 8 and Drupal 7 403 to 404 response

Recently, there was a m4032404 module made available on Drupal.org which does 403 to 404 response code change, covering Drupal 7 and Drupal 8.

Posted in Drupal, Web Development and tagged , .

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.