My sense is that you're conflating 2 kinds of protection here because you haven't made a decision. Do you want to propose rate limiting, or a captcha? Answers to your points depend on that.
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 -- 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.
