Thursday, December 11, 2008

Never trust a cookie

Let's say you're testing a web app, and you notice that in addition to a standard JSESSIONID, it sets 3 additional cookies:

If you're like me, you get a little excited when you notice that the last two contain the username and employee number of the logged in user. Any time an application is storing identifiable information in a cookie, there's a good chance it's a disaster waiting to happen. The fact is that if it's being stored there, it's being used somewhere, and chances are it's not being revalidated before being used.

So, like a good little security gnome, I change the username and ID number to "not mine", and sure enough, I am now somebody else. Authorization problems like this are unfortunately incredibly common. Many apps are very strict about making sure you authenticate, but once you've done so, forget to check that you are authorized to the resources you access.

But wait! Do I even need to authenticate in the first place to exploit this? Let's see... *type type type* No luck. As it should be, the app is checking the session ID to make sure I'm at least logged in as SOMEBODY. I guess that's good.

Oh, wait...turns out it just checks for the existence of the session ID cookie. As long as I put any bogus value in the XXSessionID cookie, I can specify any user's username and employee ID in the XXSessionUser and XXSessionEmpno cookies without having to log in.

Lessons learned:
1. Use your built-in session management tools.
2. Store session state information server-side.
3. Never trust a cookie.