News‎ > ‎

The Conundrum of the Clobbered Cookies

posted Jan 19, 2012, 7:05 PM by Nickosaurus Hax   [ updated Jan 23, 2012, 2:52 AM ]
Recently I have been investigating how cookies are treated by various browsers - specifically cookies set with the 'HTTPOnly' attribute. I've found a couple of cases where the browser's behaviour leads to interesting conditions, such as locking users out of an application - both of these issues have been identified in WebKit browsers Safari and Chrome.

This has been covered in the past by Michal Zalewski as part of the Browser Security Handbook, however some of the conditions appear to have changed, which potentially open new areas of attack. The particular areas I'm talking about are 'Overwriting cookies', 'Problems with conflict resolution' and mainly, 'Problems with "protected" cookie clobbering' on this page.

I have raised both of these issues as bugs / 'unusual behaviour' with Apple and Google, both of which have decided that it's not a security issue - so I'm documenting it here in case anyone else comes across or is interested in this behaviour. This behaviour eases the exploitation of session fixation vulnerabilities in web applications. While every webapp that doesn't set a new cookie upon authentication/privilege change is vulnerable to session fixation, the exploitability of the vulnerability depends on whether the attacker can control the cookie value that the web application will use as the session token - and this cookie-juggling behaviour allows the attacker to control said value.
Preconditions for this issue to be exploited are: 
  • that the target application is vulnerable to session fixation, and 
  • that the same application (or one in a subdomain) is vulnerable to Cross Site Scripting, allowing for the injection of JavaScript or <meta http-equiv> tags.

Google Chrome

The following methods can be used to create a new cookie in the Chrome cookie-store, with the same name as an existing cookie - even if the existing cookie was set with the HTTPOnly tag:
  • <meta http-equiv=set-cookie> (via XSS)
  • <script>document.cookie='mycook=setbyhtml;path=/;domain=.testvhost.com';</script> (via XSS)
  • Set-Cookie:%20cookie=value%0d%0aLocation:%20logout.php (via a HTTP header injection vulnerability - must have a different domain)
In the last instance, if the cookie has a different domain (e.g. .testvhost.com instead of testvhost.com), then the same behaviour with the juggling of cookie priority will occur. Of course if you control the Set-Cookie statement you have control of the cookie anyhow, I just thought it would be helpful to note that it can still be a contributor to Chrome's behaviour.

By using one of the above methods, it is possible to create a new cookie with a higher preference than the server-set cookie. This is possible by prepending a period (.) to the 'domain' flag of the <meta>/JavaScript cookie. When a further cookie is set by the target application, the <meta> cookie becomes the primary cookie - the next time the target application receives a request from the victim browser, it will be the cookie controlled by the attacker.

This is a quirk with how WebKit treats multiple cookies with the same name. My expected behaviour is that Chrome would:
- only ever send one cookie, or
- always send all cookies in the same order/priority, and
- not to choose which cookie to send based on which cookie was most recently set, regardless of the method it was set in.

In MSIE8/Firefox/Opera, the use of HTTPOnly will prevent JavaScript/HTML from changing the session token sent to the web application - either by not accepting the new cookie, or by adding the new cookie but keeping it at a lower priority so as not to disrupt the user's session. Even though we are not modifying the server-set cookie, we can insert a new cookie that takes priority over the server-set cookie - giving us control of the cookie sent to the web application, and allowing session fixation via the Cookie: header.

Safari
JavaScript / <meta http-equiv=set-cookie> can be used to set a new cookie that will take preference over an existing HTTPOnly cookie. This is due to how Safari treats 'domain' cookie flags. 
For example, if the original (server-set) cookie does not have a domain specified by the server, then the JavaScript-set cookie will always take preference over the server-set cookie - even if the server provides the browser with a new cookie using the 'Set-Cookie' HTTP Response header. This allows for persistent cookie tainting. 
If the server-set (valid) cookie has a domain specified, the attack will only work until the browser receives a new cookie from the server. This is because the cookie is overwritten, rather than shuffled further down the Cookie: header.
While this behaviour does not allow a malicious actor to access an existing Cookie, it does allow the actor to more easily exploit a session fixation vulnerability or prevent a user from accessing a web application. 
I have included a couple of scenarios below: 

Scenario A - Cookie Overwrite: 
1. Server sets a cookie with a domain flag and HTTPOnly, e.g.: "sessionid=12345; path=/; domain=.apple.com; httponly" 
2. XSS vulnerability in apple.com (or any of its subdomains) allows a user to inject JavaScript in order to set a new cookie for the same
FQDN or subdomain e.g.: "sessionid=54321; path=/; domain=.apple.com" - overwriting the existing cookie. 
3. Next request sent by the browser will send the sessionid of 54321. If the server sets a new cookie after this, the sessionid will then
take that value. 
Scenario B - Cookie Added With Higher Preference: 
1. Server sets a cookie without a domain specified, with HTTPOnly, e.g.: "mycook=setbyserver; path=/; httponly"
 
2. XSS vulnerability in reda.cked.me (or any of its subdomains) allows a user to inject JavaScript in order to set a new cookie for either
reda.cked.me or the .cked.me subdomain e.g.: "mycook=setbyhtml; path=/;
domain=.cked.me" - this creates a new cookie with a greater preference than the server-set cookie. 

3. All further requests sent by the browser will send the sessionid of setbyhtml. If the server sets a new cookie after this, the sessionid will
not be changed from setbyhtml. Users could be locked out of an application (until cookies are cleared/browser is restarted) by using this technique.


In conclusion.. I can understand the browser vendors' choices not to treat this behaviour as a security vulnerability, but believe that this behaviour eases exploitation of issues in vulnerable web applications. Of specific concern is that if targetsite.com has a cookie-based session fixation vulnerability, then if subdomain.targetsite.com has an XSS issue, targetsite.com's "protected" HTTPOnly cookie can be overwritten. An interesting condition, anyway.
Comments