User enumeration is when a malicious actor can use brute-force techniques to either guess or confirm valid users in a system. User enumeration is often a web application vulnerability, though it can also be found in any system that requires user authentication. Two of the most common areas where user enumeration occurs are in a site's login page and its ‘Forgot Password' functionality.
The malicious actor is looking for differences in the server's response based on the validity of submitted credentials. The Login form is a common location for this type of behavior. When the user enters an invalid username and password, the server returns a response saying that user ‘rapid7' does not exist. A malicious actor would know that the problem is not with the password, but that this username does not exist in the system, as shown in Figure 1:
On the other hand, if the user enters a valid username with an invalid password, and the server returns a different response that indicates that the password is incorrect, the malicious actor can then infer that the username is valid, as shown in Figure 2:
At this point, the malicious actor knows how the server will respond to ‘known good' and ‘known bad' input. So, the malicious actor can then perform a brute-force attack with common usernames, or may use census data of common last names and append each letter of the alphabet to generate valid username lists.
Once a list of validated usernames is created, the malicious actor can then perform another round of brute-force testing, but this time against the passwords until access is finally gained.
An effective remediation would be to have the server respond with a generic message that does not indicate which field is incorrect. When the response does not indicate whether the username or the password is incorrect, the malicious actor cannot infer whether usernames are valid. Figure 3 shows an example of a generic error response:
The application's Forgot Password page can also be vulnerable to this kind of attack. Normally, when a user forgets their password, they enter a username in the field and the system sends an email with instructions to reset their password. A vulnerable system will also reveal that the username does not exist, as shown in Figure 4:
Again, the response from the server should be generic and simply tell the user that, if the username is valid, the system will send an instructional email to the address on record. Figure 5 shows an example of a message that a server could use in its response:
Sometimes, user enumeration is not as simple as a server responding with text on the screen. It can also be based on how long it takes a server to respond. A server may take one amount of time to respond for a valid username and a very different (usually longer) amount of time for an invalid username. For example, Outlook Web Access (OWA) often displays this type of behavior. Figure 6 shows this type of attack, using a Metasploit login module.
In this example, the ‘FAILED LOGIN' for the user 'RAPID7LAB\admin' took more than 30 seconds to respond and it resulted in a redirect. However, the user 'RAPID7LAB\administrator' got the response ‘FAILED LOGIN, BUT USERNAME IS VALID' in a fraction of a second. When the response includes ‘BUT USERNAME IS VALID', this indicates that the username does exist, but the password was incorrect. Due to the explicit notification about the username, we know that the other response, ‘FAILED LOGIN', is for a username that is not known to the system.
How would you remediate this? One way could be to have the application pad the responses with a random amount of time, throwing off the noticeable difference. This might require some additional coding into an application, or may not be possible on a proprietary application.
Alternately, you could require two-factor authentication (2FA). While the application may still be vulnerable to user enumeration, the malicious actor would have more trouble reaching their end goal of getting valid sets of credentials. Even if a malicious actor can generate user lists and correctly guess credentials, the SMS token may become an unbeatable obstacle that forces the malicious actor to seek easier targets.
One other way to block user enumeration is with a web application firewall (WAF). To perform user enumeration, the malicious actor needs to submit lots of different usernames. A legitimate user should probably never not need to send hundreds or thousands of usernames. A good WAF will detect and block single IP address making many of these requests. Some WAFs will drop these requests entirely, others will issue a negative response, regardless of whether the request is valid.
We recommend testing any part of the web application where user accounts are checked by a server for validity and look for some different types of responses from the server. A different response can be as obvious as an error message or the amount of time a server takes to respond, or a more subtle difference, like an extra line of code in a response or a different file being included. Adding 2FA or padding the response time can prevent these types of attacks, as any of these topics discussed could tip off a malicious actor as to whether a username is valid.
Read about Rapid7's web application security testing solutions.