User Enumeration
Back to All Lessons
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.
Username
Password
Username
Password
Username
Password
Username
Email
Email
Prove you're not a robot
Pick the bird with the biggest guns!
login_failures = session[:login_failures] || 0

sleep(0.0001 * 2 ** login_failures)
URI Probing
example.com/user/batman 403
example.com/user/robin 404
example.com/user/aquaman 403
example.com/user/wolverine 404
example.com/user/cyclops 403
example.com/user/thor 403
example.com/user/hulk 404
example.com/user/thing 403
example.com/user/superman 403
No batman...
...I see you robin. You are going on my list.
Well, that doesn't help.
One Mississippi...
Oh, really?
Nrrrrrrgh.
One more for the list.
Is your website vulnerable to user enumeration?
Check today. Scan your website for User Enumeration and other vulnerabilities with