Hello, Having some basic throttling built-in would be an improvement for the vast majority of websites. Also it would plug one of the big holes in django.contrib.auth (another big one being 2FA).
Some DoS concerns were expressed on the pull request. I believe the options are: 1. use a global form validation error — this is my preference; 2. return a HTTP 429 — this requires making the protection very conservative (i.e. users should never see it in normal circumstances, like CSRF errors) or adding a new error page (which every website then has to style). Furthermore, I think: - We should consult with the authors of existing libraries in this space to check if the simple mechanism we're considering don't have downsides we missed and they know; - We should focus this on usernames and ignore IP addresses, as most sites are behind a reverse proxy of some kind and no one handles X-Forwarded-For headers right (even Heroku doesn't care — when I reported they were vulnerable to XFF injection, their security team [or, more accurately, their subcontractors] didn't understand the report, even after several rounds of explanation and a working proof of concept) - We must make sure this doesn't get in the way of users with more advanced needs. Currently the feature can be disabled with DELAY_AFTER_FAILED_LOGIN = 0, which seems fine. Best regards, -- Aymeric. > On 27 Jul 2020, at 20:21, Claude Paroz <cla...@2xlibre.net> wrote: > > Hi Adam, > > Le lundi 27 juillet 2020 16:55:35 UTC+2, Adam Johnson a écrit : > Hi Claude, > > A delay of 5 seconds seems quite long. Often I fail to log into a site due to > mis-selection of credentials from my password manager, so I can resubmit a > login form within 1-2 seconds. > > That 5-secs choice is debatable, we can agree on a shorter delay. We may also > wait for the second or third failure before throttling (suggested on the PR). > > A real rate-limiting solution has the advantage of buckets of requests per > time period, allowing users a few rapid attempts before being locked. > > Additionally, the default PBKDF2 hasher already enforces a (smaller) > arbitrary delay via its algorithm iterations. I can't find a source but I > think I remember reading it should be tuned to take about 100ms. This is > about 1.5 orders of magnitude less than a 5 second delay, which is perhaps > not so significant in terms of password brute-forcing (less difference than > one extra password character). Not sure if 100ms is where Django's current > default ends up on a modern CPU, but we probably aren't far off given we > increase the iterations according to a formula that roughly tracks Moore's > law. > > I'd rather see something like django-ratelimit merged to core. It's more > general purpose so users can reuse and customize it, and we could potentially > use it for other features in Django too. > > Sure, that might be the better long-term solution. However, I'm afraid this > will be delayed forever... (note the ticket is already 7 years old). In my > opinion, a "battery-included" framework like Django should include at least a > basic brute force protection. That's why I'd like to push some minimal > mitigation for Django 3.2, then we can always add a more elaborate tooling > set later. > > Claude > > On Mon, 27 Jul 2020 at 12:13, Claude Paroz <cla...@2xlibre.net <>> wrote: > Hi all, > > I thought a bit about login rate limiting again in recent times. > https://code.djangoproject.com/ticket/21289 > <https://code.djangoproject.com/ticket/21289> > > We know that there are some packages (django-ratelimit, django-defender, > etc.) that can do the job, but the main issue here is to provide a > *default* behavior for any fresh new Django project. > > A must-read on this subject is: > https://owasp.org/www-community/controls/Blocking_Brute_Force_Attacks > <https://owasp.org/www-community/controls/Blocking_Brute_Force_Attacks> > > I would like to suggest one mitigation measure for default Django, which > seems to me the least controversial, considering that hard-locking by > username and/or ip address can open Denial of Service vectors which may > or may not be acceptable for some sites. > > My suggestion is to add a time delay of 5 seconds in the > contrib.auth.forms.AuthenticationForm after the first failure on any > username. This choice of 5 seconds is a compromise between not too much > annoying users after a failed login attempt, and still set a significant > throttling limit for some brute force attacks. You can consider that > after a failed login, a real user will spend at least 2-3 seconds just > to re-enter a new password and re-submit the form, so the real wait > penalty should not be more than 2-3 seconds. > > This is of course NOT the panacea against all type of brute force > attacks, as you can read on the OWASP article above. But it appears to > me as a reasonable measure that can be widely accepted by most Django > projects that use the default authentication form. > > The WIP PR is available here: > https://github.com/django/django/pull/13242 > <https://github.com/django/django/pull/13242> > > Kind regards, > > Claude > -- > www.2xlibre.net <http://www.2xlibre.net/> > > -- > You received this message because you are subscribed to the Google Groups > "Django developers (Contributions to Django itself)" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to django-developers+unsubscr...@googlegroups.com > <mailto:django-developers+unsubscr...@googlegroups.com>. > To view this discussion on the web visit > https://groups.google.com/d/msgid/django-developers/7720e6a7-b214-4602-b576-c0277b60e749o%40googlegroups.com > > <https://groups.google.com/d/msgid/django-developers/7720e6a7-b214-4602-b576-c0277b60e749o%40googlegroups.com?utm_medium=email&utm_source=footer>. -- You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/5E4AFB46-0ADB-42D4-ADB4-59F3976D157B%40polytechnique.org.