Protecting Django Application Against Brute Force Password Guessing

lockWhen you bring  your web application live, you can expected various types of attacks –   one could be a brute force scanning of possible logins.   As a standard mean of prevention against such types of attacks login should be temporarily disabled after some number of unsuccessful attempts.  For Django nice package called django-lockout exists.

Main advantage of this package is that it keeps history of unsuccessful login attempts in memory (using Django cache system),  so checks are very quick.   django-lockout is fairly easy to implement, however I’ve found one issue, when it is used together with django admin site.

django-lockout is  monkey-patching django.contrib.auth.authenticate function (this function is wrapped in custom decorator, that handles checking and blocking of unsuccessful login attempts).  This patching is done in  middle-ware class of django-lockout , as part of  its instantiation.   However as many things in Django,  instantiation of middle-ware classes    is done in latest possible moment –  in this case when first request comes.   And this was source of my issues with django-lockout –   if  we get reference to  django.contrib.auth.authenticate function before middle-ware instantiation,  we get unpatched version of the function.

And exactly this happens if we include admin site  into

Import of admin causes also import of  django.contrib.auth.forms.AuthenticationForm , which imports:

so we end up with AuthenticationForm, which uses unpatched  authenticate function.   To fix this we  create subclass of  AuthenticationForm :

Method clean is overridden with two important changes –   first –  we refer auth.authenticate  (via package reference) so we get now patched version of the function,  second – we handle LockedOut exception to provide appropriate message.

This modified form has to be used for our application login page (in

and we also have to patch admin site to use this form (also in





Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">