On Fri, Jul 8, 2011 at 5:32 PM, Cal Leeming [Simplicity Media Ltd] < [email protected]> wrote:
> > > On Fri, Jul 8, 2011 at 5:03 PM, Shawn Milochik <[email protected]> wrote: > >> This topic came up on the list a few months back, and I just wanted to >> share the solution I've put into place. >> >> Short version: >> >> 1. Ensure that my Web server (nginx) passes the user's real IP address in >> the request. >> >> 2. For POST requests to the login URL only (to avoid any performance >> side-effects), keep a rolling count of number of requests by the IP in the >> past five minutes and use that to limit the number of attempts. Return >> HttpResponseForbidden with a message about too many log in attempts. >> >> Justification: >> >> I'm using IP instead of user because this prevents an attacker from >> inconveniencing a legit user or getting a "fresh start" just by guessing a >> different username. >> >> I'm throttling instead of locking the account (temporarily or >> permanently) to prevent attackers from locking out legitimate users. >> >> Details (implemented in middleware): >> >> Middleware file creates an in-memory sqlite3 database. >> > > Have you considered using an atomic caching server for storing the state of > an IPs 'throttle' count? > > It has the added benefit of giving you future support for distributed use, > wouldn't be as performance heavy as writing to a database, and deals with > any race condition problems quite nicely. > - "wouldn't be as performance heavy as writing to a database" Sorry, I shouldn't have included that, as I don't know how resource hungry the sqlite3 libs are when writing directly to memory, in comparison to the overhead of using django cache backend. > >> >> All requests that aren't POSTs or to the login URL are ignored. >> >> POST requests to the login URL cause these actions, in this order: >> Get count of requests in last five minutes. >> Return HttpResponseForbidden message if count is excessive. >> Delete database entries greater than five minutes old. >> Log this attempt. >> >> That's it. Pretty simple and effective. I hope others find it useful, and >> point out any flaws I may have missed. >> >> >> -- >> You received this message because you are subscribed to the Google Groups >> "Django users" group. >> To post to this group, send email to [email protected]. >> To unsubscribe from this group, send email to django-users+unsubscribe@** >> googlegroups.com <django-users%[email protected]>. >> For more options, visit this group at http://groups.google.com/** >> group/django-users?hl=en<http://groups.google.com/group/django-users?hl=en> >> . >> >> > -- You received this message because you are subscribed to the Google Groups "Django users" 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-users?hl=en.

