Many types of attack on websites are concerned with bypassing the
authentication system. Logging into a site usually requires that a user
supply a username and a password.
If an attacker can harvest the list of usernames for a site, they
have half the authentication information they need to access those
accounts.
Guessing passwords is harder, but possible. An attacker will use tools
to brute-force common passwords, or if your usernames
are email addresses, they might use social engineering
to trick users into revealing their password.
Your site will be more secure if an attacker cannot probe it for
usernames. Let's look at some common ways that sites leak
information about what is and isn't a valid username.
Those are the most common ways users can be enumerated.
Let's recap.
If your login page has different error messages for unrecognized usernames
and incorrect passwords, an attacker can write a script to submit usernames
and test the response.
A safer approach is to return a generic error message
when a login attempt fails.
If it takes longer to check a correct username and an
incorrect password, a clever attacker will be able to
spot the difference.
Make sure all login code-paths take about the same time on average.
For instance, perform time-consuming operations like password-hashing
even when you know the username is wrong.
Password reset pages are another avenue of attack.
If somebody tries to reset a password for an unknown username, some
sites will respond with a message indicating that the account does not exist.
Try to avoid this.
If your password reset process involves sending an email, have the user
enter their email address. Then send an email with a password
reset link if the account exists - and a sign-up email if it's a new
email address.
Same deal with registration pages. Try to avoid having your site tell
people that a supplied username is already taken. If your usernames are
email addresses, send a password reset email when a user absentmindedly
tries to sign-up a second time.
If usernames need to be unique, but are not email addresses,
protect your sign-up page with some sort of CAPTCHA. This will make it
very difficult for an attacker to mine username information with a script.
If you are very security-minded, consider adding an exponential backoff
after each failed login attempt, so subsequent retries take longer and longer.
Lastly, if each user is granted a unique URL (e.g. for user profile pages),
make sure an attacker cannot enumerate usernames. It might seem like a good
idea to differentiate responses with HTTP 404 (not found) and
HTTP 403 (forbidden), but this leaks information.