lionleaf / dwitter

Social network for short js demos
https://www.dwitter.net
Apache License 2.0
765 stars 69 forks source link

Login form is vulnerable to Password Guessing Attack #442

Open imscary opened 5 years ago

imscary commented 5 years ago

The login system will not take a pause or block you for few minutes even if you try 100 incorrect passwords. This can be exploited very easily with Hatch or bruteforcing the form action request password input data with a valid csrf token until the different response. This can be avoided with 5 minutes wait time on every 5 incorrect passwords for a specified acconut. I don't know how to implement that on Django.

dwitterer commented 5 years ago

I assume you'd need some sort of localstorage value that tracks the number of incorrect attempts and then implement some logic around that in the login form. I'll see if I can give it a go when I get home in about 3 hours, but of course you're free to implement this before then if you want to...

stianjensen commented 5 years ago

If you want this kind of security, I would implement it on the backend in django, and not in the frontend, where it's relatively easy to bypass.

dwitterer commented 5 years ago

Well I mean, that's a good point. Now that I think about it, we could just add an entry to the database with the count of incorrect logins for each user, then use that. Then it'd be entirely backend as well...

I'm not at all good with databases though 😂

stianjensen commented 5 years ago

Yep a counter could work in that case, and having it reset to zero when you correctly login. But then you would also need a mechanism to have it reset after a bit of time.

Packages like django-defender and django-axes do this for you.

imscary commented 5 years ago

Yes but what computer info must we register into the DB? The IP? Using an attack tool with dynamic proxies can change ip for every password in the wordlist.

dwitterer commented 5 years ago

I mean, we store a list of users in the database, so we'd just implement it into that. Like:

User: kipkat Blah: bleh Whatever: whatever Login_attempts: 2

Right? We don't need the IP... Just the number of login attempts for each user on the site.

imscary commented 5 years ago

Oh, good point.

imscary commented 5 years ago

If I think a little bit, an attacker can spam an incorrect password all the day and that will make the account impossible to access by anyone if it's blocked. (based on that last engine you said)

joeytwiddle commented 5 years ago

That's also an important point kipkat. Gotta be careful when throttling that we don't create a denial of service opportunity.

Attackers can change IP often, but I doubt they have the 1,000,000 proxies needed for brute-force.

In my APIs I use this approach:

The cooldown mechanism itself works like this:

Here is the cooldown monitor code. But the cache of IP->CooldownMonitor is not there.


Now I read Stian's comment about some existing solutions for django! :)

rep-movsd commented 2 years ago

I implemented something like this for the web portal for my employer

Basically, you have a login_attempts table which counts logins with latest timestamp for both IP and username, and won't allow more than one in 3 minutes after 5 failed logins. After 10 the account is locked.

There is another option - use fail2ban on the server - it generally blocks all kinds of DDos attempts by scanning web logs and changing the firewall rules.

I use this on my personal websites on digitalocean