> --
> You received this message because you are subscribed to the Google Groups
> "Django developers" group.
> To post to this group, send email to django-d...@googlegroups.com.
> To unsubscribe from this group, send email to
> django-develop...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/django-developers?hl=en.
>
>
--
Sent from my mobile device
If you search the archives of this list you'll find a fairly recent
discussion on this. Please read that first. We will need, at the very
least, a pluggable solution with a well-defined interface, because we
will not find a one-size-fits-all solution. As such, it is not a small
feature by any means. It will require significant effort just in terms
of proposing the feature. Create a ticket by all means, but I would
suggest that a solid proposal should be thoroughly discussed here before
you start coding.
Regards,
Luke
--
I teleported home one night
With Ron and Sid and Meg,
Ron stole Meggie's heart away
And I got Sidney's leg
(THHGTTG)
Luke Plant || http://lukeplant.me.uk/
https://code.djangoproject.com/ticket/16860
We probably should include a more general rate limiting framework (or
at the very least, better instructions for configuring this in common
webservers). Unfortunately, how to do this well is a REALLY hard
problem. There's django-axes as well as Simon Willison's
ratelimitcache. Neither of them are perfectly ideal. The bigger
problem is that ANY rate-limiting framework is going to need
At the moment, if your login field is not rate-limited, that is a
configuration mistake which is between you and your webserver, and is
not within the realm of what Django tries to do. We need to be careful
not to re-implement functionality that is better left to other parts
of the stack.
-Paul
The bigger problem is that ANY rate-limiting framework is going to
need heavy customization to work for all of the different ways Django
is deployed. One size will definitely not fit all in this case.
Prior to more specific work on this matter (and before anything can be
included in core), we need to address the issues in 16860. The generic
groundwork must be done first. It would be helpful to examine this
proposal in light of those concerns. What hooks does Django need to
provide to allow this to be implemented cleanly as a third-party
installable?
This needs to be pluggable because (no matter what we include), it
won't meet the requirements for a sizable subset of Django's users
(many of whom have very explicit requirements).
> Points 1-3
Our protection should be on by default if we include it in Django at
all. This means that the default configuration will be universal
enough that it doesn't get in the way for most installations.
> 4. After x failed login attempts, protection kicks in. x is a
> configurable amount of times, which by default is 3?
3 is too few for a default on a general user-facing site. Brute force
attempts try hundreds of passwords. If normal users see this
protection with any regularity, people will turn it off.
> 5. Failed logins are either stored in a database (which works well for
> small systems and protects against slow distributed attacks), or in
> memory (for large systems). Default: use the database? Because most
> users operate on small systems?
Probably the database. An extra column on users would be the most
obvious place, but it's a no-go because we don't have migrations and
this functionality should be separately pluggable anyway. We would
need to ship with a default set to off in the base settings file, and
explicitly set it on for new projects. If it adds database columns,
that might be an argument for shipping with it disabled.
> 6. We protect against the following scenarios:
> a. Login attempts coming from many IP-addresses and targeting a
> single user account;
> b. From a single IP-address, targeting a single user;
> c. Single IP-address, more than one user.
> Case 6a and - in a lesser extent - 6b are strong indicators for a
> brute force attack. Case 6c might be brute force, but might also be
> triggered by many users behind a proxy.
These are all attack vectors. There's also multiple IP multiple
account slow brute force, and many other variations. Any of these
options is going to need to be quite configurable to work for most
Django users.
> 7. Protection may consist of:
> a. denying access for x minutes for a given user or IP-address. x
> is configurable, and by default: 5 minutes?
Rate limiting is more user friendly than a hard cutoff like this. The
hard cutoff is easier to explain to a user, though. This allows a DoS
attack against specific users.
> b. adding a sleeptime to login requests (mentioned several times,
> but sounds very weak to me, because it can be easily passed by opening
> a new connection?).
Absolutely no. Adding sleep() anywhere in Django opens nasty DoS
avenues. Sleep ties up workers for no reason.
> c. logging it, and/or notifying the admin
> d. adding a captcha to login form
Which captcha do you propose? Is there a good one which does not add
external dependencies? We can't require compiled dependencies like PIL
out of the box.
> 8. Protection should be configurable as well. By default: use a
> captcha? Using a captcha prevents an attacker from using the denial
> trigger for a DoS-attack.
Captchas do that. They also introduce usability issues. Do you have a
pure-python captcha which is also ADA compliant? How do you recommend
we balance the difficulty (for both humans and robots) of the captcha?
> 9. Rate limitors should be generably applicable, to all views.
Yes. This is why they are probably best viewed as a separate feature.
> 10. Final question:
> Should this be in Django contrib? I argue in favor, in order to
> protect the innocent and keep everyone safe.
I agree that Django should ship some form of login protection.
> django.contrib.security
> seems a proper place to me.
For rate limiting or captcha? The former might belong in
core.ratelimit. The captcha is probably a pluggable related to
contrib.auth.
> There are several rate-limiting
> implementations in the wild, but unfortunately they are not often
> used. For example, compare the numbers on django-packages for django-
> axes, brutebuster and ratelimitcache against a commonly used
> application like south or django-debug-toolbar.
Yep. This is why we do need to ship something with Django. But we need
to be sure that we ship a careful, complete implementation, because
once we make a decision about the interface, we have to support it for
a long time. This is why many parts of contrib started as external
projects and stayed that way until there were clear winners.
If we can build the hooks that make it easy to build this kind of
functionality, we can get the community testing necessary to figure
out which code belongs in Django itself.
Also, we don't get to add more settings. Most of the things proposed
would require the addition of dozens of settings.
It's great to have excitement about adding this feature. It's
something Django needs, and with appropriate effort, I believe we can
build a solid foundation that will be useful to many Django users.
-Paul
Yeah... it's really a tricky problem. That solution is probably best
as an external app. Some users deploy Django apps with no net access
at all.
> About ticket 16860, I believe that to be over my head for now. In your
> opinion, is that ticket tied to the User discussion, about a more
> flexible/abstract User model (ticket 3011)?
It's tied to it, but 3011 is really hairy, and I believe we can do
good work in 16860 with or without the changes under discussion in
3011. I don't know when we will sort out 3011, but the stuff in 16860
can happen on a different timeframe.
> And/Or do you believe we have to deal with database migration first?
That would be nice, but I think we can work with what we currently have.
-Paul