views:

330

answers:

2

I have done some research on HttpOnly cookies and the problem that exist with the possibility to use an XHR request in combination with the TRACE method to get the cookie value echoed back from the server.

For a secure webapplication I currently have the following setup:

  • Session cookie is sent at login with secure and httpOnly properties set
  • The TRACE http method is disabled for the complete domain (returning "405 Method not allowed")

To avoid cross site request forgery I have added a random key in a hidden field to the forms. This key is must be returned in each POST request for the request to be accepted.

Apart from this all HTML is escaped by default using whitelisting to select tags and attributes that are allowed, but to illustrate why this is not enough: We previously allowed the style-attribute on span to be used (to color text for example), which could be used to pass javascript in Internet Explorer in the following way:

<span style="width: expression(alert('Example'));"> </span>

And then to the final question: Could anybody point out any flaws or suggestions to possible flaws in this setup? Or are you using the same or completely different approaches?

Known problems:

  • Not all browsers support httpOnly
  • Filtering css JS-expressions is not enough, @import(external-style-sheet) could also work
+1  A: 
mar
Nice list! Most of it is what we've already implemented, charset issues are high on our general testing-list. Are you aware of any sort of whitelist of attribute values considered safe? Because as explained we considered "style" to be safe for a short time which actually isn't safe at all. An overview of properties and validation regexps would be a great source for a lot of webdevelopers.
Tomas Salfischberger
We have allowed tags and CSS selectors, allowed attributes for *each* tag and allowed values for *each* of these attributes/selectors based on spec (e.g., color and font-size have different whitelist regex) and our *comfort* level (may allow href only to certain domains). The regex is applied after we walk through each character of input with a library such as icu or iconv and a custom html parser - certain characters are transformed to escaped/htmlentity encoded values. Finally we output only input we understand. Unfortunately the source is not in open source land yet.
mar
+1  A: 

HttpOnly Cookies is a good secuirty measure, but it is not designed to stop XSS, just make it more difficult for attackers to exploit xss vulnerabilities. Let me elaborate.

A token based xsrf secuirty system can be bypassed using XSS, thus the attacker doesn't need to know the cookie to exploit the xss vulnerability.

To avoid cross site request forgery I have added a random key in a hidden field to the forms. This key is must be returned in each POST request for the request to be accepted.

For instance, using XSS an attacker can execute JavaScript which can read any page on the domain using xmlhttprequest. Thus by using xmlhttprequest an attacker can read the XSRF token and then use it to forge the POST request. This is because one property of XSS is that it allows for a break in the Same Origin Policy. As an example, Here is a real world exploit that I wrote which does what i just explained.

The best way to prevent XSS is to convert nastily characters like <> into their corresponding html entities. In PHP I recommend:

$var=htmlspeicalchars($var,ENT_QUOTES);

This will fix single quotes and double quotes so it can stop most xss. Even if the resulting sting is in a html tag. For instance an attacker can't use this exploit if you replace quote marks. This is because the attacker has to break out of quotes in order to execute an "onload=".

$var="' onload='alert(document.cookie)'";

into this html:

print("<img src='http://HOST/img.php?=".$var."'&gt;");

HOWEVER, the specific case that you listed using a <span> tag is still potentially a problem because the attacker doesn't need quote marks! Your also going to have a xss vulnerability if you put inside a <script> tag. Just be safe about where user input is being placed, there isn't a "catch all" or "silver bullet" for all vulnerabilities.

The "XST" attack which leverages the HTTP "TRACE" method is not a realistic attack in practice. The reason why is that it is impossible for an attacker to force a web browser into making a "TRACE" http request. Attackers can force the "GET" and "POST" methods using javascript or an <img> tag in the case of "GET", but the rest of the HTTP header is off limits. Keep in mind that TRACE is enabled by default in nearly all Apache systems, if it was really hazardous it would be removed all together. Many security testing tools like Nessus will throw an error if Apache supports TRACE, it can also be disabled easily.

Rook
I assume OP wants to allow user authored html and css input to render. Application such yahoo mail or gmail that allow html email fall in this category. If not, then then ignore my answer and the rest of this comment (essentially agree with Michael).If you want to allow user authored html and css html, encoding all input is not appropriate. E.g., an a href in input will be transformed to <a. Whitelist tags and attribute names. Sanitize attribute values (e.g., href should not allow javascript). Same for CSS (sandbox).
mar
Mar: You are right, we want to display html formatted userinput (some from e-mail, so we cant force users to use something like BB-code).
Tomas Salfischberger
Michael: TRACE can indeed be disabled easily, that's already done. Your claim that TRACE using XHR is impossible is not right, try: xhr.open('trace', '/', false);But converting html characters to entities and escaping quotes is not a viable solution because of the necessity to display userinput containing basic HTML.
Tomas Salfischberger
@Tom, right but in order to use XHR you must be executing JavaScript in the same context as the domain. Other wise this would be a violation of the Same Origin Policy. http://code.google.com/p/browsersec/wiki/Part2#Same-origin_policy_for_XMLHttpRequest Its a moot point and thats why its still enabled on 99% of servers. You **CAN** send GET and POST requests from any domain to any domain using JS and HTML, and thats why XSRF is a still a serious problem.
Rook
@Tom, Further more html entries is the most common method of xss protection because unlike striptags(), the message is still human readable while also preventing more edge cases of xss. In order to make an omelet you gotta break some eggs, security is all about making software less useful. On a side note, TRACE is disabled on my servers because it is unnecessary.
Rook