How can I securely check if a username exists?

This source says that it is almost impossible to avoid user enumeration in this situation and delaying an attacker is the best you can do:

If you are a developer you might be wondering how you can protect your site against this kind of attack. Well, although it's virtually impossible to make an account signup facility immune to username enumeration, it is however possible to avoid automated username enumeration attacks against it by implementing a CAPTCHA mechanism.

However, I might have missed something - I'm also curious if anybody else has a better solution.


The alternative to allowing multiple users to have the same user name is far worse!

Really what happens with that system

  • User requests a new password
  • You now have to check passwords to make sure no collisions happen
  • The user can use this to brute force other accounts

That's bad. So you need to prevent multiple users from having the same username. You do this by checking.


What happens if a user can find out another users username

This is the scenario you're presented with, and how do you prevent someone from maliciously using it. What risk do you open yourself up to here?

  • A user can find out a username
  • Still doesn't give access, as they now have to guess the password

Okay good, this offers a little more security and still keeps users from having emails and other sensitive information leaked. But now you want to try and mitigate attacks. How do you do that?

Mitigating registration attacks

There are a couple of techniques that exist here to prevent it, but the best by far is rate limiting and maximum attempts that you log by IP.

Rate Limiting, Maximum Attempts, and IP Logging

When a user tries to register, they can only check for available usernames so fast. In all reality it will take a real person a second or two to type in a new username. This lets you do a few simple checks and balances. However this only really happens when they try to register. When a user attacks you and uses a username that isn't registered, all that happens is they have registered that username. Oh well. Now they have to start the registration process all over again, and here is where you can check.

  • User tries to register a lot of accounts really fast: a bot, stop them and kick them out(rate limiting)
  • User tries a LOT: Attacking by hand, kick them out(maximum attempts)
  • User comes back: Same IP address shows a really determined attacker. BAN THEIR IP(maximum repeated attempts)

Now that attacker has exposed themselves and gotten banned at an IP level. You know there is something bad going on here, have a log of usernames that might have been gleamed, and best yet there was no personal information leakage. Great job!

However now you need to go back and deregister all those accounts that were created in an attempt to find other accounts. Good thing you have those logs!


The Downfalls Of Usernames Without Emails

Here's a big flaw that you need to be aware of when you don't tie an account to an email: The username can be preregistered and held for ransom. It is then extremely hard to prove ownership of the username. This let's someone do a different type of attack against your system where they just attempt to pre register a lot of accounts of people and hold them at ransom. Hopefully you have a log from the above checks so you can try and catch them in the act.


Alternatives

You mentioned they have already gone through the email confirmation process, so another way to handle it at this point is to link it to the email instead. After registration, if they want to change their email they'll have to log in, and send a request with a link to their email to change it. This can be done with a time sensitive token. Now they can have a username too to display on the site. The pitfalls are also mitigated here since the display name can overlap and there is no way to try and gain access to another account with that information, but the email provides a check of truth(and possibly some sort of physical identifier like a profile picture)


When a user tries to log in, he or she enters their username. When registering, you are told if a username is taken or not. If you find a taken username, you can try to log in with it and possibly hack it.

Solution which is also another problem:
If they had to log in with an email, the knowledge if a username is taken won't help - you log in with an email not username so you can't know what to enter in the email text form when you know that there is the helloman username. But now the problem is telling the user if the email is taken.

Solution - when registering don't tell them if the email is taken but tell them that a confirmation email was sent. Send them an email, if the email was registered before send an email saying that someone tried to register their email. If the one who tried to register [email protected] is not the real helloman than he probably wont see helloman's email inbox. And if the real helloman tried to create a new account with his already registered email then only he will receive an email saying that he already registered. Unless there is a hacker who managed to hack helloman, but many people like helloman aren't stupid and wont use password as the password, also the most common email systems nowadays are very secure, so it's not to worry (and if he hacked them than it's not our problem(If you setup your own email server for you and your staff)).