Categories
Python Software Development

Django Friday Tips: Deal with login brute-force attacks

In the final tips post of the year, lets address a solution to a problem that most websites face once they have been online for a while.

If you have a back-office or the concept of user accounts, soon you will face the security problem of attackers trying to hack into these private zones of the website.

These attackers can either be people trying to login as somebody else, or even bots trying to find accounts with common/leaked passwords.

Unfortunately we cannot rely on users to pick strong and unique passwords. We can help them, as I explained in a previous post, but it isn’t guaranteed that the user will make a good choice.

Using a slow key derivation function, to slowdown the process and increase the time required to test an high number of possibilities, helps but isn’t enough.

However we can go even further with this strategy, by controlling the number of attempts and only allowing a “given number of tries per time window”.

This is very easy to achieve on Django projects by relying on the django-axes package. Here’s an explanation of what it does:

Axes records login attempts to your Django powered site and prevents attackers from attempting further logins to your site when they exceed the configured attempt limit.

django-axes documentation

Basically you end up with record of attempts (that you can see in the admin) and allows you to define how the system will behave after multiple failed tries, by setting the maximum number of failures and cool-off periods.

You can check the package here, it is very easy to setup and it shouldn’t require many changes to your code. The documentation can be found here and it covers everything you will need so I won’t provide any examples this time.

I hope this tip ends up being useful and wish you a Merry Christmas. The tips will continue in 2022.

By Gonçalo Valério

Software developer and owner of this blog. More in the "about" page.

Leave a Reply

Your email address will not be published. Required fields are marked *