//update 1: please look at the end for edit #1
This applies to pretty much any credential system, even include 2FA: When and How do I tell the user that the login had failed - and If at all?
On a Tech-News site I read about a recent data leak on which the attacker used what they called "credential stuff" or something - it's pretty much a brute force combined with a dictionary - but the dictionary in this case is a big table full of cracked credentials from earlier leaks. This resulted in a new list providing plain-text passwords. According to the site every login can be attacked with it even if all other security is Fort Knox. The way this works is that instead of brute force with random input the input is taken from an earlier list leaked and only credentials that work are copied over into the new list.
So, this made me think about: if, when and how do I tell the user that the login failed? Google does it like this:
- login name is checked
- only if 1. is passed the password is checked, otherwise the reply is just "username does not exist"
- only if 2. is passed then maybe 2FA if in place is checked, otherwise "wrong password" is replied
- finally, if 2FA is used, it's checked and when it passes you login - otherwise the reply is "2FA failed"
So, by this an attacker can first check if a list of possible usernames is valid and can filter out those not valid. Then, to filter the list further just check the known passwords. If no 2FA is active then login is granted. Otherwise when 2FA is in place one has to auth it. So, if an attacker focus on breaking the 2FA the list can be filtered to only those with valid usernames + password with the side-effect that one also gets the list where no 2FA is active.
If I design a login myself, I would request all 3 information at once so there's no way to filter which of them was wrong - although this might only work with a time-based 2FA instead of one-time on demand.
TLDR: Are there ways to mitigate against such "stuffing" attack?
//edit 1: As pointed out by the replies of r0x0t and user18471 it seems there're some tradeoffs to consider I didn't thought about. So let me update my initial post by them:
"Will the user ever have a chance of noting what was wrong when username, password and maybe 2FA is entered all at once and no matter what was wrong only a 'login failed' is replied?"
I didn't thought about that. Sure, a username is usually entered in plain without hiding, but what if you only visited a site once long time ago and you don't remember what username or e-mail-address you used? Will you ever get a hint that the username/e-mail-address you already tried for the last few hours isn't even the correct one you used the first time? The way I used to think about this very issue there would be no way to hint this to the user. So, I guess the way other sites do it at least has this trapdoor needed for human interaction.
On the other side: When relaying the information that the "user-identification" is wrong, wich hints the user s/he tries the wrong username/e-mail-address, it also gives an attacker the information that the tried identification was wrong. I guess the same goes for the order when to give info about wrong passphrase and/or 2FA.
"How about counting wrong login attempts? Only counting wrong passwords/2FAs when the username/e-mail was correct - or for all tries of the session no matter what went wrong?"
Another valid point I just didn't gave any second of thinking about - mainly because I mostly use public key stuff instead of "oldschool username + password". So, from as far as I understand this point it's about like Fail2Ban for auto-blocking remote attacks to SSH, SMTP and other open services a normal server has to has open for normal operation wich are often points of interest for attackers to gain system access or knowledge of secrets. As I only use my server for my very own purposes without any user stuff I only have services running I know about and only allow access in a very restricted way (SSH only with public-key auth, SMTP only with strong passwords with a filter in place to block ip packets from known attacker sources, etc). But what if I host a forum? Do I only have a counter in the database which counts up when a username was right and the password wrong? Or do I use a session ID and count ANY input? For a normal user maybe mis-hitting a key on entering the password there won't be any issue - but for an attack it does make a difference if one could spam false usernames without any restriction but gets blocked of after 3 wrong passwords on a correct username.
It's a bit like me try to implement a simple GUI application following MVC pattern: It can be implemented in many different ways all valid, but all have their very own pros and cons. But instead of learning a design pattern in which I can make mistakes a login done wrong can lead to a major security hole someone could use to break in my server backend. I guess I either need a lot more to learn about this topic - or ask someone who already has good skills at this.