Internet Explorer 8 has a new security feature, an XSS filter that tries to intercept cross-site scripting attempts. It's described this way:

The XSS Filter, a feature new to Internet Explorer 8, detects JavaScript in URL and HTTP POST requests. If JavaScript is detected, the XSS Filter searches evidence of reflection, information that would be returned to the attacking Web site if the attacking request were submitted unchanged. If reflection is detected, the XSS Filter sanitizes the original request so that the additional JavaScript cannot be executed.

I'm finding that the XSS filter kicks in even when there's no "evidence of reflection", and am starting to think that the filter simply notices when a request is made to another site and the response contains JavaScript.

But even that is hard to verify because the effect seems to come and go. IE has different zones, and just when I think I've reproduced the problem, the filter doesn't kick in anymore, and I don't know why.

Anyone have any tips on how to combat this? What is the filter really looking for? Is there any way for a good-guy to POST data to a 3rd-party site which can return HTML to be displayed in an iframe and not trigger the filter?

Background: I'm loading a JavaScript library from a 3rd-party site. That JavaScript harvests some data from the current HTML page, and posts it to the 3rd-party site, which responds with some HTML to be displayed in an iframe. To see it in action, visit an AOL Food page and click the "Print" icon just above the story.

link|edit|flag

5 Answers

up vote 18 down vote accepted

What does it really do? It allows third parties to link to a messed-up version of your site.

It kicks in when [a few conditions are met and] it sees a string in the query submission that also exists verbatim in the page, and which it thinks might be dangerous.

It assumes that if <script>something()</script> exists in both the query string and the page code, then it must be because your server-side script is insecure and reflected that string straight back out as markup without escaping.

But of course apart from the fact that's it's a perfectly valid query someone might have typed that matches by coincidence, it's also just as possible that they match because someone looked at the page and deliberately copied part of it out. For example:

http://www.bing.com/search?q=%3Cscript+type%3D%22text%2Fjavascript%22%3E

Follow that in IE8 and I've successfully sabotaged your Bing page so it'll give script errors, and the pop-out result bits won't work. Essentially it gives an attacker whose link is being followed license to pick out and disable parts of the page he doesn't like — and that might even include other security-related measures like framebuster scripts.

What does IE8 consider ‘potentially dangerous’? A lot more and a lot stranger things than just this script tag. eg. What's more, it appears to match against a set of ‘dangerous’ templates using a text pattern system (presumably regex), instead of any kind of HTML parser like the one that will eventually parse the page itself. Yes, use IE8 and your browser is pařṣinͅg HT̈́͜ML w̧̼̜it̏̔h ͙r̿e̴̬g̉̆e͎x͍͔̑̃̽̚.

‘XSS protection’ by looking at the strings in the query is utterly bogus. It can't be ‘fixed’; the very concept is intrinsically flawed. Apart from the problem of stepping in when it's not wanted, it can't ever really protect you from anything but the most basic attacks — and the attackers will surely workaround such blocks as IE8 becomes more widely used. If you've been forgetting to escape your HTML output correctly you'll still be vulnerable; all XSS “protection” has to offer you is a false sense of security. Unfortunately Microsoft seem to like this false sense of security; there is similar XSS “protection” in ASP.NET too, on the server side.

So if you've got a clue about webapp authoring and you've been properly escaping output to HTML like a good boy, it's definitely a good idea to disable this unwanted, unworkable, wrong-headed intrusion by outputting the header:

X-XSS-Protection: 0

in your HTTP responses. (And using ValidateRequest="false" in your pages if you're using ASP.NET.)

For everyone else, who still slings strings together in PHP without taking care to encode properly... well you might as well leave it on. Don't expect it to actually protect your users, but your site is already broken, so who cares if it breaks a little more, right?

To see it in action, visit an AOL Food page and click the "Print" icon just above the story.

Ah yes, I can see this breaking in IE8. Not immediately obvious where IE has made the hack to the content that's stopped it executing though... the only cross-domain request I can see that's a candidate for the XSS filter is this one to http://h30405.www3.hp.com/print/start:

POST /print/start HTTP/1.1
Host: h30405.www3.hp.com
Referer: http://recipe.aol.com/recipe/oatmeal-butter-cookies/142275?

csrfmiddlewaretoken=undefined&characterset=utf-8&location=http%253A%2F%2Frecipe.aol.com%2Frecipe%2Foatmeal-butter-cookies%2F142275&template=recipe&blocks=Dd%3Do%7Efsp%7E%7B%3D%25%3F%3D%3C%28%2B.%2F%2C%28%3D3%3F%3D%7Dsp%7Ct@kfoz%3D%25%3F%3D%7E%7C%7Czqk%7Cpspm%3Db3%3Fd%3Do%7Efsp%7E%7B%3D%25%3F%3D%3C%7D%2F%27%2B%2C.%3D3%3F%3D%7Dsp%7Ct@kfoz%3D%25%3F%3D%7E%7C%7Czqk...

that blocks parameter continues with pages more gibberish. Presumably there is something there that (by coincidence?) is reflected in the returned HTML and triggers one of IE8's messed up ideas of what an XSS exploit looks like.

To fix this, HP need to make the server at h30405.www3.hp.com include the X-XSS-Protection: 0 header.

link|edit|flag
++ Thanks for providing the Bing example :) – Roland Bouman Jan 12 '10 at 21:19
5  
You are right, hp.com needs to return the X-XSS-Protection header. I had assumed that it needed to come from AOL.com, since in this scenario, I thought hp.com was the presumed bad guy, and it didn't make sense for the bad guy to be able to disable the protection. But this is a way for hp.com to assert that the endpoint isn't vulnerable, which it isn't. – Ned Batchelder Jan 13 '10 at 14:40
1  
Well, it might also be vulnerable, but that's another issue ;-) – bobince Jan 13 '10 at 20:41

You should send me (ericlaw@microsoft) a network capture (www.fiddlercap.com) of the scenario you think is incorrect.

The XSS filter works as follows:

  1. Is XSSFILTER enabled for this process?
    If yes– proceed to next check If no – bypass XSS Filter and continue loading
  2. Is a "document" load (like a frame, not a subdownload)? If yes– proceed to next check If no – bypass XSS Filter and continue loading
  3. Is it a HTTP/HTTPS request? If yes– proceed to next check If no – bypass XSS Filter and continue loading
  4. Does RESPONSE contain x-xss-protection header? Yes: Value = 1: XSS Filter Enabled (no urlaction check) Value = 0: XSS Filter Disabled (no urlaction check) No: proceed to next check
  5. Is the site loading in a Zone where URLAction enables XSS filtering? (By default: Internet, Trusted, Restricted) If yes– proceed to next check If no – bypass XSS Filter and continue loading
  6. Is a cross site Request? (Referrer header: Does the final (post-redirect) fully-qualified domain name in the HTTP request referrer header match the fully-qualified domain name of the URL being retrieved?) If yes – bypass XSS Filter and continue loading If no – then the URL in the request should be neutered.
  7. Does the heuristic indicate of the RESPONSE data came from unsafe REQUEST DATA? If yes – modify the response.

Now, the exact details of #7 are quite complicated, but basically, you can imagine that IE does a match of request data (URL/Post Body) to response data (script bodies) and if they match, then the response data will be modified.

In your site's case, you'll want to look at the body of the POST to http://h30405.www3.hp.com/print/start and the corresponding response.

link|edit|flag
Eric, thanks for the offer and the information. Here's one of the things I find frustrating about all the information out there about the filter (including your answer): they talk about "the response". Which response? There are a number of requests and responses needed to create the scenarios we're talking about. – Ned Batchelder Jan 12 '10 at 19:51
The only requests/responses examined by the filter are those that are document loads-- either the top-level document or a document in a subframe. – EricLaw -MSFT- Jan 13 '10 at 4:27
Are you saying that I can add the X-XSS-Protection:0 header to the response from the HP site? That seems odd to me: I had assumed in this scenario that the HP site was the presumed bad guy. Why would a header provided by "the bad guy" turn off the check? – Ned Batchelder Jan 13 '10 at 12:48
3  
In this scenario, the HP site is the potential victim; they're getting a POST from your site that contains sequences that could indicate an XSS attack attempt. They can add the "X-XSS-Protection: 0" header to their response if they are not worried about XSS attacks and do not want any sanitization from an XSS Filter (IE's or WebKit's). – EricLaw -MSFT- Jan 13 '10 at 20:49

Actually, it's worse than might seem. The XSS filter can make safe sites unsafe. Read here: http://www.h-online.com/security/news/item/Security-feature-of-Internet-Explorer-8-unsafe-868837.html

From that article:

However, Google disables IE's XSS filter by sending the X-XSS-Protection: 0 header, which makes it immune.

I don't know enough about your site to judge if this may be a solution, but you can probably try. More in depth, technical discussion of the filter, and how to disable it is here: http://michael-coates.blogspot.com/2009/11/ie8-xss-filter-bug.html

link|edit|flag
6  
The article in question is quite misleading. You should read jeremiahgrossman.blogspot.com/2010/01/…. – EricLaw -MSFT- Jan 12 '10 at 19:38
1  
Thanks for that link. While I am sure the blogger has a much better judgement of the situation than I have, I was unable to extract a good reason from his article why not to disable it. The comments on the other hand provided a few IMO very good reasons to consider disabling the filter as long as it is not fixed. See comments #7 and #8: tinyurl.com/ydcwu77 – Roland Bouman Jan 12 '10 at 20:10

Here's a blog entry posted by Microsoft that gives some more details about how the XSS filter works:

link|edit|flag

Has this changed for IE9? I am using Google Contacts API, Javascript version and am getting errors

"Internet Explorer has modified this site to prevent cross site scripting"

This error happens even though I have turned OFF XSS Filtering by adding my site to the list of trusted sites and turning the XSS Filter OFF for the Trusted sites. Everything works perfectly on IE8 (and every other browser). But, on IE9, after about 30 AJAX calls to Google, I get that error.

Its like IE9 is seeing that I am making many calls to google API's and gets suspicious and shuts the site down. What I am doing is a 2-way sync between a web application and Google Contacts. Since there can be 10,000 contact records in Google, I could easily make hundreds (or even thousands) of individual calls to Google to fetch a contact, modify it etc.

I am somewhat confused where the x-xss-protection header should be applied. I have added it to my web site. However, I have no control over the Google API's web site site and can not add it over there. I have added the header on my side. What Google is doing is unknown to me.

I can understand the concern for safety, however this is a web application and my customers add this web site to their trusted sites list. What gives?!

link|edit|flag

Your Answer

 
or
required, but never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.