Testing for DoS Locking Customer Accounts (OWASP-DS-002)

Brief Summary
In this test, we check whether an attacker can lock valid user accounts by repeatedly attempting to log in with a wrong password.

Description of the Issue
The first DoS case to consider involves the authentication system of the target application. A common defence to prevent brute-force discovery of user passwords is to lock an account from use after between three to five failed attempts to login. This means that even if a legitimate user were to provide their valid password, they would be unable to login to the system until their account has been unlocked. This defence mechanism can be turned into a DoS attack against an application if there is a way to predict valid login accounts.

Note, there is a business vs. security balance that must be reached, based on the specific circumstances surrounding a given application. There are pros and cons to locking accounts, to customers being able to choose their own account names, to using systems such as CAPTCHA, and the like. Each enterprise will need to balance these risks and benefits, but not all of the details of those decisions are covered here. This section only focuses on testing for the DoS that becomes possible if lockouts and harvesting of accounts is possible.

Black Box Testing and Examples
The first test to perform consists of verifying that an account does indeed lock after a certain number of failed login attempts. If you have already determined a valid account name, use it to verify that accounts do indeed lock by deliberately sending at least 15 bad passwords to the system. If the account does not lock after 15 attempts, it is unlikely that it will ever do so. Keep in mind that applications often warn users when they are approaching the lockout threshold. This should help the tester, especially if actually locking accounts is not desirable because of the rules of engagement.

If no account name has been determined at this point in the testing, the tester should use the methods below to attempt to discover a valid account name.

To determine valid account names, a tester should look to find places where the application discloses the difference between valid and invalid logins. Common places this would occur are:
 * 1) The login page – Using a known login with a bad password, look at the error message returned to the browser.  Send another request with a completely improbable login that should not exist along with the same bad password, and observe the error message returned.  If the messages are different, this can be used to discover valid accounts.  Sometimes the difference between responses is so minor that it is not immediately visible. For instance, the message returned might be perfectly the same, but a slightly different average response time might be observed. Another way to check for this difference is to compare hashes of the HTTP response body from the server for both messages.  Unless the server puts data that changes on each request into the response, this will be the best test to see if there is any change at all between the responses.
 * 2) New account creation page – If the application allows people to create a new account that includes the ability to choose their account name, it may be possible to discover other accounts in this manner.  What happens if you try to create a new account using an account name that is already known to exist?  If this attempt generates an error saying that you must choose a different name, this process may also be automated to determine valid account names.
 * 3) Password reset page – If the login page also has a function for recovering or resetting a password for a user, look at this function as well.  Does this function give different messages if you attempt to reset or recover an account that does not exist in the system?

Once the tester has the ability to harvest valid user accounts, or if the user accounts are based on a well-defined, predictable format, it is an easy exercise to automate the process of sending three to five bad passwords to each account. If the attackers have determined a large number of user accounts, they can deny access to a large portion of the legitimate user base.

Gray Box Testing and Examples
If information about the implementation of the application is available, look at the logic related to the functions mentioned in the Black Box testing section. Things to focus upon:
 * 1) If account names are generated by the system, what is the logic used to do this?  Is the pattern something that could be predicted by a malicious user?
 * 2) Determine if any of the functions that handle initial authentication, any re-authentication (if for some reason it is different logic than the initial authentication), password resets, password recovery, etc. differentiate between an account that exists and an account that does not exist in the errors it returns to the user.