Web application session handling is one of the most difficult things to do right. As we move more and more towards standard web frameworks (django,rails, etc.) to handle the basic functionality of a custom web application, this becomes a smaller issue. Unfortunately, there are engineers and developers that insist on going it alone in this realm. There are also legacy applications that require backward compatiblility and then there are just plain old out of date applications that still serve publicly.
Note: The following terms all describe the session ID and may be used internchangably: Session ID, session value, cookie value, session cookie, cookie.
In the course of my penetration testing, almost every time there is at least one failure in the session managment category. I would (and so would OWASP classify these categories as follows:
- Exposed session ID's: http://example.com?sessionid=12345 (seems silly, but it happens)
- Smetimes these are also exposed in plain text as a cookie value, although they are quite often a hash value
- Session fixation attack: The session ID value is re-used or recycled on next login
- Session destruction/creation: The session ID value is not destroyed on logout, timeout or browser close
- Session IDs are not rotated: The logged out (non-authenticated) session ID is re-used for the logged in session value
This does not represent an exhaustive list, just a few items that I see come up regularly during the course of my testing.
A few words on general web application testing. By far, the single best tool for testing web applications is BurpSuite. At $299 (as of this post) it is the best bang for buck I've seen. I would call this a semi-automatic testing tool. It works as a web proxy to essentially setup a man-in-the-middle by design and as such has access to all traffic and interesting goodies between you and your target site. If you are serious about web application auditing, this is the tool to learn. They do have a free version that is great for learning. I am in no way affiliated with Burp or its authors, but I would not step into a web application pentest without it.
Another tool with the right price is Edit This Cookie. It is a Chrome browser extension that allows user manipulation of any cookie on the current site. It is an absolute must-have for this excercise. Firefox has similar add-ons as well.
Now, lets get to the actual auditing of these issues. I may turn this into more of a three part series on sessions, but for now, this is it.
One of the best things you can do is take time to understand how the authentication system works on your target site. How is the session stored? In a cookie? In the URL? What happens when you fuzz or substitute random values for the session ID value? How does the application react in different scenarios? That's what we're going to talk about in-depth with some actual steps on how to find out.
A few notes on getting to know your target:
- Spend some time analyzing the URLs that are involved in the authentication process. Note any redirects that occur and if there are any interesting GET and POST parameters being passed. The goal is to understand what is taking place server-side to authenticate the user.
- Identify all cookies, deleting them one by one (you can delete and flag if you are using the chrome plugin "edit this cookie"), until you know which contains the session key. Also analyze the URLs for authenticated users and be able to identify what exactly is identifying the user.
- Note all cookies and their values--you may need them later.
- Validate that the "secure flag" is set on all session cookies. I.e Any cookie with the "session" flag must also have the "secure flag".
- Check for the persistence of cookies. If you have visited the target, delete all cookies for the site and then close the browser. Proceed with the following steps, noting the session cookie value at each step
And now let's dig a little deeper: After each of the steps below, note the session value and label it accordingly so you can see how it is handled.
- open browser and visit the target
- login again
- log out again
- close browser
- open browser and visit site
- login again
- logout again
Compare cookie values from the above steps. Note any issues with the following best practices:
- 'logged out' cookie values should not persist and become 'logged in' cookie values after authentication.
- 'logged in' cookies should be destroyed when the browser is closed so that re-opening the browser does not give you a logged-in session.
- The same 'logged in' cookie value should not be given every time you authenticate.
- The 'logged out' cookie value should not determine what 'logged in' cookie value you will be issued after authentication. The 'logged in' cookie received should be random.
- The 'logged in' cookie value should not become the 'logged out' cookie value after logout.
A few questions to answer as a result of your testing:
- Are session cookies protected? Session cookies should be treated like all other user input and be validated. Best practice is to hash the session cookie so that session manipulation and hijacking attempts are much more difficult.
- Is the session cookie encoded? Sometimes decoding a session cookie can reveal additional items that are bundled with the session ID that may be interesting. One will need to figure out how to decode encoded cookies so that session ID values from different cookeis and users can be compared to look for vulnerabilities.
- Is the session ID bound to any other attributes? With a logged in account, change your IP address and then check if you are still authenticated. Do the same with the user-agent (and client certificates if you received one). If altering these attribtues does not affect your authentication status, the session ID is not bound to any additional user property. While best practice is to bind the session to another property, the absense of this does not indicate a vulnerability.
- How are logins from different browsers instances for the same un/pw treated? Do they receive the same session ID? If one logs out, is the other logged out?
- Does logging out really log you out? Record the cookie for a logged in user and log out. Update the session cookie to the previous 'logged in' cookie value and attempt to visit a restricted/authenticated web page.
- Attempt to understand any single sign-on (SSO) systems and look for weaknesses. Oauth has some implementation difficulties.
Here is a list of items to check for regarding authentication procedures:
- Figure out how session management and authentication work
- Reset or create your password multiple times, each time introducing more complexity. Find the following:
- Minimum password length
- Complexity requirements (requires numbers, letter, capital letters, symbols, etc.?)
- Review the password reset procedures.
- Are the links used in emails to reset your password able to be clicked a second time?
- Do links in emails to reset your password have an expiration?
- Is your plaintext password emailed to you (i.e. you password is not stored encrypted)
- Is a new password emailed to you after starting the reset process? This means someone can deny you access to your account by starting a password reset for you.
- Are accounts locked after a number of invalid login attempts? If not, may be susceptible to brute force. (use the authbrute script)
- Does the account sign-up page allow you to validate user account names?
- Does the 'failed login' page give information about whether the username or the password was incorrect?
This should get you a good step in the right direction when auditing the session handling for a web application. If nothing else, it presents some of the correct questions to obtain answers for.
Now, what would offense be without a good defense? Look for a future blog post about the defensive solutions to these potential vulnerabilities.
Credit to JBStiles for some testing procedures.