OWASP Top 10 Risks #2: Broken Authentication and Session Management

Identity Theft Through Broken Authentication and Session Management

Breach-Apocalypse

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.

 

clip_image001

 

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.

 

Credential ManagementCable Guy who can garnish personal information due to exposure.

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.

Reset Password Form Example

 

Forgot Password

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?

Password Reset

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.

 

Password Storage

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.

 

Information Engineering

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?

 

Session Management

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.

Cookie-less Sessions

Not long ago, the chances of organizations or users not allowing the use of cookies are significantly less.  However, in the case where cookies are not enabled and sessions are in use, the ability to transmit session identification is still needed.  Therefore, most of the time, this transmission of the session identification occurs in the URL. This URL can then be used from any other browser from any other computer and assume the identity of that session.

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.

Conclusion

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.

References

OWASP Broken Authentication And Session Management

Identity Theft Resource Center report

2014 Breach Information

http://www.databreachtoday.com/infographic-2014s-top-breaches-so-far-a-7408

http://www.ftc.gov/system/files/documents/reports/consumer-sentinel-network-data-book-january-december-2013/sentinel-cy2013.pdf

About the author

Max McCarty

Max McCarty is a software developer with a passion for breathing life into big ideas. He is the founder and owner of LockMeDown.com and host of the popular Lock Me Down podcast.

  • Robbie kouwenberg

    Very interesting article.
    I know security is hard and doing security right is even harder.
    However as a developer it would be nice if there were for instance more out of the box solutions that are suited for common scenarios.
    For instance a asp.net mvc project template that has the basics of the owasp top 10 covered with good guidance on how to implement your functionality securely.
    Is there anything like that out there?

    • Robbie, I don’t know of “A” specific framework that goes to the Nth degree to put security first. Don’t get me wrong, ASP.NET just like other frameworks have taken significant steps to make security a “first” class citizen, but allot of people still take issue with some of the out-of-the-box implementation.

      What I will say is that ASP.NET has done a fairly good job of making components swap-able or able to be customized. Implementing these common features such as Forgotten password or user verification (just to name a couple) isn’t like trying to implement password storage and has a lower difficult rating. Therefore, attempting to implement one of these features correctly is allot easier and frameworks like ASP.NET (and others) make customizing allot easier when you doing it yourself.

      However, I will say that for the most part ASP.NET meets a significant number of the above “forgotten password” points, but not all of them.

      As far as password storage – due to the complexity of correctly securing password at rest and transit and because most BCL libraries don’t help with the complexities, sticking with tried and true implementations (i.e.ASP.NET’s Identity or SimpleMembership Provider) are generally going to be the best and safest option.

      • Robbie kouwenberg

        Hi Max. I agree wholeheartedly with you. Although not all bases are covered 100% Asp.Net still has very good capabilities. It is those capabilities we should use and their limitations we should be aware of.

      • As of ASP.NET MVC5 pretty much every single thing you talk about is included out of the box. They still require you to uncomment a few lines of code for password reset but it does the Token&Email song and dance for you already.

        It also includes built in hooks for 2F auth and external auth (Live, Facebook, Twitter etc).

        The only thing it doesn’t include is security questions out of box. (Or those stupid images banks make you pick, but i understand that’s to reduce phishing but I highly doubt the lack of the walrus you selected is going to prevent a user who would have otherwise entered their username & password into a malicious site)

  • I definitely have some counter points:

    Forgot Password

    #2 I completely disagree with, you tell the user if no account is found with that email. I don’t care this proves this email exists in the system. People have multiple emails, nothing more will confuse a user than entering [email protected] “we have sent the password reset request” and nothing ever arrives at [email protected]. If you’re deadset on this requirement atleast send an email to [email protected] stating “we received your request however we cannot locate an account with this email”.

    (Also you duplicated 1 twice instead of using 2 in this section)

    #7 “another form of a password, so they need to be cryptographically secured.” this is debatable. Do you use these questions to authenticate a person over the telephone? Then they need they need to be accessible to human eyes. I view the statement “cryptographically secured” when it relates to authentication as purely 1 way hashing that cannot presently be reasonably rainbow dictionary attacked.

    Session Disposure

    I also disagree with this. There is nothing more damaging to a user’s experience than a session timeout. So I just filled up my shopping cart with hundreds of dollars of items, I click check out. I go to lunch and return. Now I’m logged out of purchase process and even worse if my shopping cart is empty. What is the probability I will purchase my items a second time? Infinitesimal.

    Sessions should not expire unless it is some arbitrarily long time duration such as a week or month to clean up data a person used on a shared computer. If I ran an eCommerce site, my sessions would never expire ever. You put a book in your shopping cart 6 years ago? You come back to my site you damn well better expect “your shopping cart is ready for check out”.

    In a different angle. I use O365 for work email. I go lock my computer and go home for the weekend. On Monday I return and O365 is sitting on the sign page. It logged me out even though I checked remember me (this is a mortal sin right here). So i type my password and get an error “session has expired”.

    You just can’t do this to users. Security done right should be entirely oblivious to users. Sessions timing out is just a cop out. If you’re actually interested in security you need to do real work, such as monitoring session usage. A user who is in the US and suddenly is in China, did they travel or were their cookies stolen? Now is a good time to sign the user out and force authentication. Using O365 example, I understand what likely timed out was the AntiForgeryToken to prevent CSRF and not truly my session. Microsoft took the easy way out and let me see an error. In a better designed system the token would be validated, so it was issued 48 hours ago, was it ever used? Nope? Then this token is still good. So the token was issued 48 hours ago AND it was used? Yeah, reject that request as it might be CSRF.

    If you want security unplug the computer from the internet. Since that’s ridiculous; security is about preventing malicious users while allowing regular users to be as oblivious as possible to security. Usernames and passwords really need to go the way of the Dodo, sadly they keep living on.

    • Chris,

      Thanks for the typo catch. As well, thanks for chiming in and posting some valid points to your arguments.

      #2 – I tried to make it very clear that there is not a perfect fit security scenario and every situation requires an evaluation of what level of security is required.

      In addition, I also made clear that a notification “is” sent to whatever address submitted “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”.

      However, you’re not the only one that feels the same way about not providing immediate feedback. This has been debated rigorously https://news.ycombinator.com/item?id=4280440

      #7 – Again, I think that comes down to requirements. If you can see this as a scenario that will be required, than this would be an issue. However, it has been suggested that the operator (in our fictitious example) can submit what the end user states is the answer to their question without having to see the actual answer (due to a 1-way hash). This does also remove any human interpretation and introduces human error in the case of a user to “stating” the exact answer.

      As far as session management, if your intentions are to ensure the user can maintain state, then identifying this as a requirement and putting in necessary security checks that might “help” mitigate is a must (as you pointed out some ways of doing so). However, this wouldn’t be acceptable to applications that would require a higher level of security. In addition, I also mentioned that if there is a scenario where you can’t validate the user, a force authentication is required.

      Btw, great use for the word “infinitesimal”.

      • “the operator (in our fictitious example) can submit what the end user
        states is the answer to their question without having to see the actual
        answer”

        That’s true, but it doesn’t help the next situation. The user can’t login AND can’t reset their password because they can’t answer the security questions.

        Suppose my security question was “What college did you attend?” I could easily have answered: Behrend, Penn State, PSU, Pennsylvania State University, Penn State Behrend, PennState, and probably another dozen or so iterations. A human would be able to validate many of my answers but hashing would fail without the exact same input. (I would suspect you would atleast want to normalize secret answers and not treat them as case sensitive)

        The more hoops that exist the more times users will be calling “i can’t sign in”.

        Of course all of this is why I’m a huge fan of “enter your email to logon” “check your email to logon” Basically following the password reset token path for ALL logons. The only theoretical downside to this is that arguably it makes a user more susceptible to spear-phishing since they’re used to clicking on logon links.

        • This is true. However, I already pointed that out when I stated “This does also remove any human interpretation and introduces human error in the case of a user “stating” the exact answer.”