Stronger Passwords for Django

One of our main concerns is data security. While we can do our best to protect our service against external threats, a weak account password posses the easiest attack vector. We are all human and sometimes we don’t even realize how vulnerable our (supposedly strong) password is to a dictionary-based attack.

We use Django internally. Let us share with you how we hard-ended our account registration process to automatically check for weak passwords and give our users improved protection.

Installing libraries

If you want to ensure that your password is not easily crackable, try to crack it by yourself first. We use a handy library CrackLib which matches the password against predefined patterns and dictionaries. CrackLib is a common library and very likely it will be available as a precompiled package for your system. As a Python wrapper we use python-crack library. Again it should be easily available as a package.

Assuming we a have a Debian system, installation is as easy as:

aptitude install python-cracklib

Aptitude will install all dependencies including libcrack.

Dictionaries

We try to provide as many word dictionaries to search for the password as possible. Debian helps us with a large set of word dictionaries already included. Just check for the wordlist virtual package. Even better, download a large dictionary provided by CrackLib.

CrackLib requires compilation of the word dictionaries beforehand to build indexes for optimal performance. On a Debian system the  index is  located  in  the files /var/cache/cracklib/cracklib_dict{hwm,pwd,pwi} and is generated daily via cron. We don’t want to wait that long however, so lets compile it manually…

Just run /usr/sbin/update-cracklib to update the index. The script looks into several standard directories, including /usr/share/dict where Debian dictionaries are stored. However, if you downloaded your own dictionary, don’t forget to either move it to some of standard directories like /usr/local/share/dict, or – preferably – outside of standard system’s files. The alternative path should be added to /etc/cracklib/cracklib.conf.

Account registration

We are ready to roll! The support in Django is a piece of cake. Simply extend the standard registration form from the handy django-registration application:

from django import forms
from registration.forms import RegistrationForm

class SafeRegistrationForm( RegistrationForm):
  def clean( self):
     """ Tests the password for dictionary attacks. """
    r = super( SafeRegistrationForm, self).clean()
    if r:
      import crack
      try:
        crack.VeryFascistCheck( self.cleaned_data[ 'password1'])
      except ValueError, message:
        raise forms.ValidationError,
          "Please use a stronger password to protect your account. The current one is too weak (%s)."%str( message)
    return r

The clean method is overriden to add a stronger password test.

Viliam is a co-founder and in a position that could be called CTO.

Posted in Feature, Logentries, Web

Leave a Reply