In 2013 over 34 million Americans reported some form of identity theft. Three quarters through 2014 there is already a reported 568 data breaches with over 75 million records compromised and hundreds of millions of users affected. This is up from the 439 breaches in 2013. Identity theft isn’t a possibility, it’s a reality that is happening all the time and identity theft is at the core of the 2nd of OWASP’s top 10 most critical web security risks of 2013; Broken Authentication and Session Management.
We covered who the Open Web Application Security Project (OWASP) is and their mission in our last post on OWASP’s #1 risk; Injection. OWASP has defined Broken Authentication and Session Management as the following:
Application functions related to authentication and session management are often not implemented correctly, allowing attackers to compromise passwords, keys, or session tokens, or to exploit other implementation flaws to assume other users’ identities.
In addition, they have also defined a rating scheme to help clarify the agents, attack vectors and business impact of each risk. Below is how they have defined Broken Authentication and Session Management.
As I described at the beginning, the underlying theme of this risk is the ability of malicious user gaining access through some other identity. The breadth of different cases that authentication and session management can cover is exhausting. But let’s cover some of the obvious common scenarios to get a feel for the attack vectors we need to protect.
To make it easier, we’ll break it into two main areas, credential management and session identification.
When we look at the numerous attack vectors that can account for broken authentication, we can summarize them down to how we manage credentials in our system. A better way to define it is to
ask, how responsible are we with users identification in our system? Ask yourself, what actions to do you take to protect your personal information and are you taking those same actions for your users?
To paint a mental picture of that last question, when you receive physical mail at your house that retains sensitive information, do you leave around for the cable guy to see or is it stored away, possibly with the sensitive information being obscured. When you no longer need to retain that information does it just get tossed out with the trash or do you take explicit steps to make it not accessible when it’s discarded?
Let’s face it, we’re not all using the same language and frameworks, nor does the framework you use probably handle all application user requirements. So, the chances that you need to implement a Change Password or Remember Me feature or augment the current framework is pretty high. Implementing a Forgot Password feature? Have you fully vetted the multiple steps involved? We’ll look at some of the more common credential management procedures and talk through the points you need to be aware.
Forgot & Reset Password
Let’s make this clear, there isn’t a one size security protocol that fits all. Depending on your requirements, there is an interacting point where security and user experience meet for your specific scenario. We’ll point out those user experience and security trade-offs as we look through the points of implementing a Forgot Password process.
We can start by looking at the proper way to handle Forgot Password procedures. There is more to think about than you might original imagine.
1. Initialize. To initialize the process of resetting their forgotten password, have users only enter the email address that they believe is associated with the account. Don’t provide any feedback on whether the specified email address is a valid address or not. Provide only an immediate notification to the end user that instructions for resetting the password was sent to the specified email address.
2. Notify. Immediately send out an email to the specified account despite whether the email is a legitimate address or not. In the case that the email was not a legitimate, the email would be a notification to the email holder specifying that no account was found associated with the email. In the case where the email was legit, specify the instructions for continuing the password reset process.
Out of the gate, this is going to be controversial for some, shouting a user-experience foul. There is a small inconvenience where the user must submit another email address due to a typo or incorrect remembrance of what email address was used to register is little when we think about. This small inconvenience affords us additional protection for our users. The larger issue here is allowing a malicious party to harvest information on what valid users exist in our system (including the one experiencing the small inconvenience). The ability to harvest legitimate accounts and information about those accounts is a serious error and will be talked about later at length.
3. Protect the current account. There should be no action taken against an account where a password reset process has been initialized. To be more precise, no lockout of the account or no re-generation of a new password. Nothing. A form of Denial of Service attack (DOS) can be direct or in mass if any action is taken against an account where only the process of resetting the password has been initialized.
4. Tokenize. Generate a secure token that can be used to identify the reset request. This is persisted with the associated account ID and time stamp of when the request was initialized. This might go without saying, but the token does not represent any sensitive data and is only an obfuscated reference to the request record that should not be able to be guessed.
5. URL. Legitimate email addresses (email addresses found in the system) should contain a URL link to continue the password reset process. The URL will contain the token: https://FluffyKittens.com/account/reset/5hy9285029ki48c862cb9e1893kfjc9 that will be used to look up the password reset request record for additional information. Most importantly, this must be a secured URL using HTTPS. I spoke about the man-in-the-middle vulnerabilities when not securing all aspects of sensitive transaction and this is no different. It might go without saying, but do not provide the user’s current password! in the email. I might go as far as not even providing the associated username in the email (if the account username isn’t the email address). Especially, if you will require further user validation before allowing the user to specify a new password (talked about later in the process).
6. Request Validation. Following the URL link in the email will land them on the HTTPS secured form. Before being able to take the next steps in the password reset process, we need to validate that the token provided by the URL is still valid. The time that the request was initialized was captured with the password request record earlier in the process. At this point, you need to apply your business rules for how long a password request is valid, whether that is 1 hr. or more. If the time has expired, notify the user that this process must be restarted and discard the reset request record.
7. User Verification. At this point in the process we have relied completely on the security of the email address. The user is either a legitimate user or someone has managed to compromise the associated email account. Here is where you need to determine what level of further validating the user is required. FluffyKittenWishList.com might not require the same level of validating you are who you claim to be, that your financial institute requires.
There are a number of different forms of validation such as Two-Factor Authentication and Secret Questions/Answers. Since 2FA is in itself a diverse and deep subject, we’ll talked shortly about Secret Questions/Answers. If you determined to further validate the user, they need to answer 1 or more questions that they had chosen and answered at some point in the lifetime of their account. The key however, is that we don’t display only the questions they chose to answer. Require the invalidated user to choose from the list of possible questions the correct selected question and provide the correct answer.
If you are using secret questions and answers, the answers need to be stored just as you would with passwords. Many have written long ago how secret answers to secret questions are just another form of a password, so they need to be cryptographically secured.
8. Reset Password. After the user has successfully validated their legitimacy (or in the case where they are not required), they would be presented with the ability to provide a new password (and complementing password confirmation). However, once this has been done, we don’t automatically log them in.
9. De-Tokenize. After a successful password reset, destroy the associated password request record that was retrieved using the URL provided token.
10. Notify, Again. Once the password reset is successful, send a second email to the same email address notifying that a successful password reset has occurred on the associated account. This might not seem so intuitive, but engineering the compromise of someone’s account by someone other than the legitimate owner happens all the time. So, notifying the user account of these types of activities can help mitigate further exploitation of someone’s account in the case of an illegitimate password reset.
11. Login. As it was mentioned earlier, when a password is successfully reset, we don’t automatically log them in but redirect them to the login page and require them to login.
The above is a topic that can be extensively written about (and has been) but I have distilled it down to a few bullet points. Therefore, there are quite a few very important considerations that need to be made that weren’t mentioned already, such as:
· Logging, lots of it. Logging every aspect of the reset process (note: never log the password).
· Means for legitimizing the password reset request with CAPTCHA’s or throttling requests, usually attempts by harvesters to validate the exists of accounts.
· How to handle cases where username and email are separate but the user has forgotten their associated username – when would be a valid opportunity to divulge this information?
When it comes to allowing password resets by users currently authenticated, the more important factor is ensuring that the currently authenticated users is who we believe them to be. This really can be seen by any computer or device that another user can access physically. Whether that is your computer you stepped away from momentarily or a public computer you forgot to log off that website you were logged in.
Therefore, a quick and simple way to protect a user’s account is to require they submit the current password along with the new password. Additionally, this can be further enforced by requiring further user validation of either in the form of Two-Factor Authentication or Secret Question/Answers.
Securing passwords at rest is probably the most popular subject that would also fall under broken authentication. However, one nice aspect of OWASP risks is how some areas of individual risks can actually overlap other identified risks. While the mechanism of how we handle password storage in our system relates to broken authentication, it has also been identified as one of the top ten OWASP risk at #6: Sensitive Data Exposure.
But, despite having talked about proper password storage before, we’ll look at some of the important points about password storage. The definition of proper password storage has mutated over the years and continues to do so. But with the continued advancements of computer hardware, finding that cryptographically silver bullet that can withstand being cracked is no longer the only angle the community is taking. It now has been coupled with the use of Time as a means of defense.
The truth of the matter is that using a good cryptography algorithm can make it hard for a malicious user to crack, but as we have seen too many times, its not impossible. Brute Force attacks ensure that with some period of time, eventually a password can be cracked. Therefore, the ability to slow down how long it takes a malicious user to crack a password plays a significant role in proper password storage.
For some time now, many popular frameworks have been implementing out-of-the-box solutions that incorporate Password Based Key Derivation functions such as PBKDF2 and Bcrypt. Password Based Key Derivation functions take advantage of a process called Key Stretching. Key stretching is the action of deliberately making the key derivation function slow in order to impede attacks such as brute force attacks. It does this by iterating through the hashing algorithm a specified number of times, defined by the iteration count. For example, if the iteration count is set to 12,000, the specified algorithm by the Password Based Key Derivation function will iterate the password through the algorithm 12,000.
ASP.NET’s SimpleMembershipProvider and Identity are two authenticated implementations that utilize the PBKDF2. However, some would argue that their implementation of only 1000 rounds of the hash algorithm is too little. Understanding how to implement the PBKDF2 function in .NET can help understand how password hashing works in ASP.NET.
To itemize some core important points to password storage:
· Do not store passwords in plain text
· Don’t attempt to implement your own hashing schemes – use strong and valid, time proven and tested cryptography algorithms such as ASP.NET’s Identity (be aware of the low 1000 iteration count).
· For scenario’s where implementation is required, use a unique salt with a high level of entropy with each password hash. Hash with a valid hashing algorithm such as PBKDF2 and Bcrypt with a high level of hashing rounds.
Despite not being directly linked to Passwords in rest, these are some absolute points of necessities in the grand schemes of password security worth being reminded of:
· Always operate under HTTPS with any resources that interact with passwords (including the initial authentication form)
· Use only “Secure” flagged cookies with all HTTPS accessed resources
· Require strong passwords (preferably minimum of 12 characters), a better option would be to use Pass-phrases.
You probably have heard the phrase “defensive driving” or “drive for other people”? The meaning implies that we can’t assume everyone will drive correctly and we must be on guard to protect ourselves from those less skilled drivers. What does that have to do with the topics we have been covering? We can’t think about our users and their information only in the realm of our application. The idea that a third party can garnish information from ‘our’ system about who has a valid account, is a direct security vulnerability. I can here you saying “but that is a confidential and privacy issue!”. Is it?
Let me explain. Remember the opening statistics? We all know the probability that a user will use the same email address and password on multiple sites. A user who’s account was compromised on one of those breached systems, has conveniently registered with our system using the same email address and password. Allowing the discovery of valid email address in our system can easily lead to an easy illegitimate access to our system through that account. Elevated privileged accounts anyone?
How sessions are created, transmitted and disposed is where we see the highest level of vulnerabilities for sessions. As with many frameworks, there is generally a plethora of options for managing Session State. This can be in the form of persistence to a database, in-memory cache and even various cloud distributed options. Therefore, the ability to cover for each and every scenario is beyond this article.
What we can look at is some important points to be aware of when utilizing session state. At the core of most vulnerabilities with session state, is what we identified at the beginning of this article; stolen identity. The ability for a malicious user to hijack a valid user’s session or impose their own session on a victim is the areas we need to protect against. We’ll start with probably one of the more popular examples and easiest forms of session hijacking.
Though, frameworks have taken the liberty to short circuit this vulnerability, the bottom-line is, don’t allow cookie-less sessions. It’s that simple. If this is too hard of a line and cookie-less sessions are a must, then the hardline has to be with not allowing any sensitive data to be transmitted in this scenario. But again, I go back to the first line which is simply don’t allow cookie-less sessions.
Session Origination & Disposure
Session ID’s need to ensure a high level of entropy to ensure uniqueness as well the inability to be engineered or guessed. In addition, it’s important that sessions are protected. Minimum protection should come in the form of the HTTPOnly flagged cookies to ensure browser and server only access to session information. However, if any sensitive data is being transmitted, the use of HTTPS is absolutely and uncompromisingly required for all session related data.
Disposing of sessions is as important as any other part of session security. At minimum there are three pertinent points to maintain when disposing of sessions which are:
1. Ensuring that sessions expire and within a reasonable period of time. Whether that is 1 day or 1 hr. ensuring that they do expire is pertinent.
2. When disposing of sessions it is absolutely necessary that they completely be invalidated.
3. A invalidated session ID should never be recycled for use.
These required security points to how we handle sessions don’t stop with our own managed applications. They also apply (to the extent that they can) with Single Sign-on tokens issued from other authentication providers.
As you might have gathered from OWASP’s definition of broken authentication and session management, is that the realm of possible areas this risk encompasses is overwhelming. Application security is a broad subject and authentication and session management is just a piece of the whole pie. However, the impact that these risks can have can be devastating.
What we have seen throughout each of the discussed vulnerable areas is the risk of a identity theft. This can be through exploiting weak authentication or session processes, or through an unsanctioned legit login. It is paramount that we be aware of the vulnerable areas and it is our responsibility to do due diligence when it comes to implementing secure authentication and sessions management.