Checking for Bad Passwords in Drupal to Avoid Site Compromise

Easy-to-guess passwords are all too often the means by which intruders gain unauthorised access. It's useful to be able to audit the passwords in use on your site - especially for user accounts with administrative privileges.

Ideally your Drupal site should have a robust (but user friendly) password policy (see my previous post: Password Policies and Drupal). However, this is not always possible.

The problem with checking your users' passwords is that Drupal doesn't actually know what they are; rather than storing the plaintext password, a cryptographic (salted) hash is stored in the database. When a user logs in, Drupal runs the supplied password through its hashing algorithm and compares the result with the hash stored in the database. If they match, the user has successfully authenticated themselves.

The idea is that even if the hashes stored in the database are compromised somehow, it should be very difficult (if not infeasible) to derive the original passwords from them.

So how can a site check whether users have chosen bad passwords?

One method is to check the password against a repository of known-compromised passwords while we (briefly) have it in plaintext; that is, when the user has just submitted it. That's how the Password Have I Been Pwned? module works.

However, if you wish to conduct an audit of many passwords in your system, it's not very convenient to have to wait for users to type those passwords in. It would be better to be able to check the hashes.

Tools such as John the Ripper (John), take a list of possible passwords (usually referred to as the wordlist) and compare each against stored hashes. John supports Drupal hashes, but to use it you need to take the hashes from the database and put them in a text file. That's not convenient, and may introduce unwanted risks; a text file containing password hashes should itself be treated as very sensitive information.

Drop the Ripper

Another option is the drush module Drop the Ripper, which is inspired by John. Drop the Ripper (DtR, which I created and maintain) comes with a default wordlist (curated by John the Ripper's maintainers) and uses Drupal's own code to check the hashes stored in the database.

It's fairly safe to use on production sites (the drush 8 version does not need to be installed as module), but it will use some resources if you are running a lot of checks.

The default options have DtR check the passwords for all users on the site against the top 25 "bad passwords" in the wordlist (along with a few basic guesses based on the user's details). Here's an example of that:

$ drush dtr
Match: uid=2 name=fred password=qwerty                       [success]
Match: uid=4 name=marvin password=123456                     [success]
Ran 65 password checks for 4 users in 2.68 seconds.          [success]


In that case, two of the users had pretty bad passwords!

You can narrow the check down by role, but roles are arbitrary in Drupal; how do you know which ones grant "administrative" privileges? There's an option to check all users with a role that includes any "restricted" permissions (those which show "Give to trusted roles only; this permission has security implications" in the admin interface). This is a good way of checking the accounts that could do serious damage if they were compromised:

$ drush dtr --restricted
Match: uid=1 name=admin password=computer                    [success]  
Match: uid=3 name=sally password=password1                   [success]  
Match: uid=4 name=marvin password=abc123                     [success]  
Ran 24 password checks for 3 users in 1.04 seconds.          [success]


You can target one or more specific users by their uid:

$ drush dtr --uid=11 --top=100
Match: uid=11 name=tom password=changeme                     [success]
Ran 47 password checks for 1 users in 3.85 seconds.          [success]


This can be useful if - for example - you notice something in your logs which suggests a particular account may have been subject to a brute force login attack.

Check the command's built-in help for details of more options, and several examples.

So isn't this dangerous? Can hackers use it?

Well, you can only run DtR if you can run drush commands on a site, in which case you can already log in as any user you want (drush uli) and/or change any user's password (drush upwd). However, it should be used carefully and responsibly; you should treat the output of the command as sensitive data in itself. There is an option to hide actual passwords, but consider that if a user came up as a "Match" with the default options, we can infer that their password is very obvious or high up on the wordlist.

Keep in mind also that people have a bad habit of using the same password everywhere. If DtR reveals that the username [email protected] has the password "abc123", we'd hope that's not also their gmail password. But it could be.

This tool should typically be used by site admins to check that their users - especially those with administrative super powers - have chosen passwords that are not trivial for bad actors to guess. If it turns out that there are bad passwords in place, one option is to use drush to set a hard-to-guess password for the account(s) in question, and then politely suggest that they reset their password to something better.

Drop the Ripper supports both Drupal 7 and 8, via both Drush 8 and 9.