Hi all,
I'm trying to work on adding rate-limiting to core as part of this year's 
GSoC, and I'd like to work on this 
ticket as a part of the project. I'm aiming to write an API for 
rate-limiting (which is a lot like django-ratelimit merged into core),
which we could use to add some default rate-limiting to the 
AuthenticationForm.

It seems like it's hard to add rate limiting to the form without 
introducing a DoS vector. The ideal solution would be a soft block
like a captcha, but that is not currently possible to do in the core. For 
now, I propose that we allow a small amount of login attempts
per minute - maybe 10 or so attempts per minute for each username and IP 
considered together, and then rate-limit using a fixed window.
The IP would come from a user-specified header configured by a setting.

I think this would work better for good actors by allowing them to try 
again immediately after a few incorrect passwords, and limit bad actors 
significantly.
We will make the rate, the key, etc. for the enforced rate-limit 
customizable, as you can read in my proposal for the implementation here 
<https://docs.google.com/document/d/1cg3Afu3QzLztgSxYjXAC3esaYYPes5lOYoL5ksphjHo/edit>
.

Thanks,
Hrushikesh

On Monday, 27 July 2020 at 20:25:35 UTC+5:30 Adam Johnson wrote:

> 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. 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.
>
> Thanks,
>
> Adam
>
> On Mon, 27 Jul 2020 at 12:13, Claude Paroz <[email protected]> wrote:
>
>> Hi all,
>>
>> I thought a bit about login rate limiting again in recent times.
>> 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
>>
>> 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
>>
>> Kind regards,
>>
>> Claude
>> -- 
>> 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 [email protected].
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/django-developers/49b80757-9117-fa11-3f53-731af1f0c206%402xlibre.net
>> .
>>
>
>
> -- 
> Adam
>

-- 
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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/0b3bfc35-972e-4012-b43e-1ecc4d643cc8n%40googlegroups.com.

Reply via email to