Hi Tom,

> Hello Everyone,
> 
> I noticed that Django's contrib.auth doesn't provide a mechanism
>  for detecting a password brute force attack. This is necessary for
>  a couple projects I'm working so I have to implement some kind of
>  solution and would really like to do it in such a way that it
>  could get contributed back to the community. I'd like to propose
>  possible two variants to the way that system works and would
>  appreciate feedback.
> 
> The first option is the more user customizable one, I propose a new
> signal (possibly called LoginAttempt) which User.check_password()
> would fire before returning so that users could implement their own
> logging and lockout policies. This is likely what I will implement
> first so that our internal implementation doesn't interfere with
> future general implementations.

The problem with signals is that they don't return values, and so the 
mechanism can't interact with the actual login process.  It can only 
notice that something is going on and try to stop it by some external 
mechanism.

> The second option, which is much more thorough, would add a
> LoginAttemptLogEntry model which would look something like this:
> 
> class LoginAttemptLogEntry(models.Model):
>     user = models.ForeignKey(User, null=True)
>     datetime = models.DateTime(auto_now_add=True)
>     success = models.BooleanField()
> 
> Then either ModelBackend.authenticate() or User.check_password()
>  would log each login attempt using the LoginAttemptLogEntry. Any
>  user's account which had more than N (configurable in settings,
>  default to 5?) consecutive unsuccessful login attempts would get
>  locked. A successful password reset would then re-enable the
>  account.

Personally, I really dislike this kind of thing.  It makes it trivial 
to allow an attacker to lock out a user, just by knowing their 
username.  The password reset mechanism has two disadvantages:

 1) It won't work if the user's e-mail address is out of date.
    A user who has not forgotten their password should not be forced
    to keep their e-mail address up to date if they don't need it to
    be.
 2) It's really inconvenient. This kind of security policy pushes the
    cost of the attack onto the user, who hasn't done anything wrong.

So I would be against this as a default implementation, or as any 
implementation included in Django. (I understand that this is probably 
coming from customer requirements).

Simon's rate limiting sounds like a better idea, since it doesn't 
require a reset and limits on IP address, so that the user isn't 
affected by the attacker's antics.

As for integrating a solution, for either one of these it can already 
be done without a new signal, and a solution like Simon's cannot be 
done with signals).  You simply wrap the view function in question in 
some code that implements your policy (possibly using a decorator like 
Simon's does).  For protecting the admin, this can be done by using an 
AdminSite mixin that overrides the 'login' method.

So if you want to contribute your work to the community, I would do it 
as an external project. But as other people have mentioned, check out 
the existing projects.

Regards,

Luke

-- 
"I'm at peace with the world. I'm completely serene. I know why I 
was put here and why everything exists. I am here so everybody can 
do what I want. Once everybody accepts it, they'll be serene too." 
(Calvin and Hobbes)

Luke Plant || http://lukeplant.me.uk/

--

You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.


Reply via email to