5 Reasons HTTPOnly won't save you
In the fallout from the Apache.org hack, several people have suggested that HTTPOnly cookies would prevent this attack. This discussion seems to come up every time XSS is used for credential theft, and I'm getting tired of posting rebuttals, so I figured I'd write one post to point people to.
If you're not familiar with HTTPOnly cookies, there is a flag set on the server side when sending the cookie that instructs the browser to avoid giving client-side scripts access to that data. When the HTTPOnly flag is set, the cookie is only used for, and accessible through, HTTP requests- hence the name.
Don't get me wrong- I recommend you use the HTTPOnly flag on any applications you develop. It's easy to set the flag, and it can be a useful defense in depth measure. However, it does not solve any real problems. At the very most, it's a small hurdle for the attacker. Too often, people fixate on the specific exploit, and not on solving the problem. Assuming he is going to the trouble of writing custom exploits, it won't stop him. Here's why.
Inconsistent browser implementation
While the HTTPOnly flag is supported by all the modern browsers, it didn't used to be. Archaic browser support isn't really a huge concern, but it's not completely insigificant either.
Cookie Tampering
If we assume that I can't read your cookies, that doesn't mean I can't still write them. HTTPOnly cookies can still be overwritten in some browsers, and can be overridden (by setting a more-specific cookie (such as www.example.com where the HTTPOnly cookie is only restricted to example.com. The browser should send the www.example.com cookie when both exist. Some browsers will send both. It's complicated)). The attacker may not have access to your session ID, but if you're not regenerating it every time a privilege change happens (you should be), all the classic session fixation attacks apply. Even if you do regenerate the session ID, the attacker can still force you to take over his session. Depending on the situation, that may be enough.
Cross-Subdomain Information Leakage
Do you have any other applications on other subdomains? An HTTPOnly cookie that's set for example.com will also be sent with any request to ancient-app-that-you-forgot-about.example.com. See my paper from last fall for more details.
mod_userdir
Okay, those of you not on a mass-hosted webserver can tune out, but the millions of you that are, take notice. If your cookie domain is set to "example.com", path is set to "/" (as most are by default), and you're on a mass-hosted webserver (particularly cPanel, though this applies to others), nothing is preventing user "foo" from placing a script on http://example.com/~foo/cookie_logger.php- which he technically owns. Your browser will happily send it those HTTPOnly cookies.
Ignoring the Cookie
Here's the real elephant in the room. Why do attackers want your session cookies in the first place? Trust me, session IDs aren't really that exciting. The attacker's goal is really just to gain access to the application. If they have the ability to execute Javascript in your browser in the context of the targeted website, they've already won. Stealing the cookie happens to be the quickest route to that goal, but it is by no means the only route. What's preventing them from making AJAX calls directly to the application, setting you up as a proxy? Sure, it takes a little more bandwidth, and is slightly more visible, but honestly, how many users would notice a page taking half a second longer to load? How many analyze every request a web page makes?
HTTPOnly cookies are designed to prevent credential theft, but only in situations where the application is already compromised via XSS. Credential theft is a means to an end, and there are plenty of other means to that end. Attackers have options. Defenders don't.
If you're not familiar with HTTPOnly cookies, there is a flag set on the server side when sending the cookie that instructs the browser to avoid giving client-side scripts access to that data. When the HTTPOnly flag is set, the cookie is only used for, and accessible through, HTTP requests- hence the name.
Don't get me wrong- I recommend you use the HTTPOnly flag on any applications you develop. It's easy to set the flag, and it can be a useful defense in depth measure. However, it does not solve any real problems. At the very most, it's a small hurdle for the attacker. Too often, people fixate on the specific exploit, and not on solving the problem. Assuming he is going to the trouble of writing custom exploits, it won't stop him. Here's why.
Inconsistent browser implementation
While the HTTPOnly flag is supported by all the modern browsers, it didn't used to be. Archaic browser support isn't really a huge concern, but it's not completely insigificant either.
Cookie Tampering
If we assume that I can't read your cookies, that doesn't mean I can't still write them. HTTPOnly cookies can still be overwritten in some browsers, and can be overridden (by setting a more-specific cookie (such as www.example.com where the HTTPOnly cookie is only restricted to example.com. The browser should send the www.example.com cookie when both exist. Some browsers will send both. It's complicated)). The attacker may not have access to your session ID, but if you're not regenerating it every time a privilege change happens (you should be), all the classic session fixation attacks apply. Even if you do regenerate the session ID, the attacker can still force you to take over his session. Depending on the situation, that may be enough.
Cross-Subdomain Information Leakage
Do you have any other applications on other subdomains? An HTTPOnly cookie that's set for example.com will also be sent with any request to ancient-app-that-you-forgot-about.example.com. See my paper from last fall for more details.
mod_userdir
Okay, those of you not on a mass-hosted webserver can tune out, but the millions of you that are, take notice. If your cookie domain is set to "example.com", path is set to "/" (as most are by default), and you're on a mass-hosted webserver (particularly cPanel, though this applies to others), nothing is preventing user "foo" from placing a script on http://example.com/~foo/cookie_logger.php- which he technically owns. Your browser will happily send it those HTTPOnly cookies.
Ignoring the Cookie
Here's the real elephant in the room. Why do attackers want your session cookies in the first place? Trust me, session IDs aren't really that exciting. The attacker's goal is really just to gain access to the application. If they have the ability to execute Javascript in your browser in the context of the targeted website, they've already won. Stealing the cookie happens to be the quickest route to that goal, but it is by no means the only route. What's preventing them from making AJAX calls directly to the application, setting you up as a proxy? Sure, it takes a little more bandwidth, and is slightly more visible, but honestly, how many users would notice a page taking half a second longer to load? How many analyze every request a web page makes?
HTTPOnly cookies are designed to prevent credential theft, but only in situations where the application is already compromised via XSS. Credential theft is a means to an end, and there are plenty of other means to that end. Attackers have options. Defenders don't.


1 Comments:
I think you left behind a big one: XST. You can read the details here:
http://www.cgisecurity.com/whitehat-mirror/WH-WhitePaper_XST_ebook.pdf
In a nutshell, if TRACE (part of the HTTP protocol) is enabled in the server, you can use it to receive a raw copy of what you sent (including headers, thus, including cookies) and just parse the response to get the cookie (session id) value.
By
palako, At
May 13, 2010 6:26 AM
Post a Comment
Subscribe to Post Comments [Atom]
<< Home