I used to think that checking for username enumeration vulnerabilities was important to do. Based on what I’ve observed, now I’m not so sure.
When I’m conducting a broad test of a software system, I tend to check for basic security holes like username enumeration. “Username enumeration” vulnerabilities happen when software that has login accounts for its users gives you a way to build a list of valid login accounts, for example, by giving you a way to query whether a guessed username is valid or not. Once you have this list, you can try to launch a brute force attack to guess the passwords.
Testing for username enumeration is one of the mitigations recommended in the 2013 OWASP Top 10. Cigital gives it even more prominence in their Top Web Application Security Vulnerabilities Compared to the OWASP Top 10, with username enumeration ranking as the 9th most commonly found, even when only considering the vulnerability via password reset features. My experience, though, is that companies aren’t very interested in fixing these vulnerabilities. It may be commonly found because it isn’t commonly fixed.
Once I did get a fix for an obvious vulnerability, but when I found I could still do enumeration by checking the response time from the server, that didn’t get fixed. I often see no fix at all when I report a username enumeration problem. For example, the main web login form for Instagram has this vulnerability, but Instagram considers your username to be public information, and they confirmed when I contacted them that they’re not going to close this hole. A significant fraction of the companies that participate in the HackerOne bug bounty program specifically state that they exclude username enumeration from the program.
I’ve found a few ways that companies have indirectly mitigated this issue, which may be contributing to some of the “ho-hum” response:
- Rate-limiting on the vulnerable feature based on IP address. In my testing, it wasn’t uncommon to see that a feature that allowed me to enumerate would temporarily lock me out after about several tries in rapid succession. This would only succeed in locking me out if it’s based on my network presence, not on the username, since I would be trying a different username each time.
- Similarly, a few vulnerable sites use CAPTCHA to defeat automated enumeration attempts. After trying several different usernames, I would get a CAPTCHA challenge that stopped a script from continuing.
In both of these cases, I can easily determine if a particular username is in use. But if I want to compile a large number of usernames, it may take a script months of running at the maximum allowed rate. There may be other ways to defeat these measures, such as frequently changing the public-facing IP address, using a botnet, or trying to use a database of known CAPTCHA responses.
None of this matters for Instagram, because the vulnerability on the web login is not rate-limited in any way. And that isn’t even the easiest vector – the issue with incremental userIDs mentioned here has not been fixed: InstaBrute: Two Ways to Brute-force Instagram Account Credentials.
One remaining mitigation comes to mind – the account lockout based on failed password attempts. Once we have a list of good accounts, we haven’t gained anything until we guess the password. I haven’t tried cracking that nut yet. My first thought is that if we have a large number of usernames, the time it takes to try one particular password for each of them may not trigger an account lockout at all by the time we roll back to the top of the list for the next password to try, as long as the lockout feature automatically resets itself after some fairly short period of time. But perhaps I’m being naïve about how quickly we would need to progress through a long list of possible passwords.
I would be curious to hear what your experience has been with reporting username enumeration problems, especially with companies that set a high priority on closing these holes.
Image credit: Christiaan Colen (CC BY-SA 2.0)