Statistical Validation of the IE8 XSS Filter


Greetings, I’m Russ McRee of Microsoft’s Online Services Security & Compliance Incident Management team. My team serves as incident handlers for the various types of attacks our online services face. High on the list of incidents we handle are cross-site scripting attacks. 

There’s an unfortunate misconception surrounding cross-site scripting (XSS) attacks that result in them being perceived as less impactful than other types of attacks, and often more theoretical than practical. I believe this mindset increases inherent risk for Internet users. I wanted to share some statistics that show why I think the addition of the XSS Filter to Internet Explorer is so significant.

The Web Application Security Consortium (WASC) recently released its findings from the Web Application Security Statistics Project 2007. The data in this report adds to the statistics I cited in The Anatomy of an XSS Attack, for the June 2008 ISSA Journal.

Some highlights from the WASC study:

  • Of the most prevalent vulnerabilities, including SQL injections, information leakage, predictable resource location, and cross-site scripting, XSS was the most prevalent at 41%.

  • Of 10,297 sites analyzed for the WASC study, 28,796 XSS vulnerabilities were discovered, accounting for 31% of all sites surveyed.

Additional statistics:

  • According to the Internet Security Threat Report from Symantec, during the last six months of 2007, 11,253 site-specific, cross-site scripting vulnerabilities were documented, compared to 6,961 between February and June in the first half of the year, for a 62% increase in six months.

  • According to a WhiteHat Security Statistics Report, 90% of all websites have at least one vulnerability, and 70% of all vulnerabilities are XSS.

While statistics can always be used to prove a point, more important are the actions taken to alleviate a problem. Since XSS vulnerabilities are of epidemic proportions, the XSS Filter in IE8 (intended to protect consumers from this massive attack vector) is a great thing.

David Ross, Security Software Engineer on the SWI team has driven the effort that discovers likely XSS in a cross-site request, and identifies & neuters the attack if it is replayed in the server’s response. Users are not presented with questions they are unable to answer – IE simply blocks the malicious script from executing.

Simply put, IE 8’s XSS Filter seeks to provide defense in depth via automatic detection and prevention of common XSS attacks, a pervasive security threat facing Internet users, without deterring performance or compatibility.

Referring back the statistics above, this translates into 70% of possible threats faced by IE 8 users deterred by the XSS Filter.  I’m really excited about the work that the Internet Explorer and SWI teams have been doing  here to provide new levels of protection for users.

Russ McRee

Comments (10)

  1. Ben Voigt [C++ MVP] says:

    A more important statistic, perhaps, would be the fraction of hackers with the knowledge to execute an XSS attack today who will be unable to do so with the IE8 XSS filter.  This is surely far less than 70% neutralized and likely near zero.

    An arms race may work against spam, where the volume of malicious content is the problem, but in the XSS domain where individual attacks can be serious, bolt-on solutions won’t work.  Sites have to be re-architected to protect against the attack and not rely on a browser that statistically identifies and blocks even 99% of attack vectors.

    It would be worthwhile to close some fraction of vulnerabilities, so some fraction of affected websites become safe against all attack, but I doubt this filter will do so.  The hackers just have to obfuscate their scripts to the point that the filter can’t recognize them.

  2. Ted says:

    That’s where you’re wrong, Ben. This isn’t a bolt-on protection; they built it into the core engine of the browser.  Remember, bad guys can obfuscate their attacks all they want, but at the end of the day, the browser has to actually deobfuscate the script enough to run it.  

    So an attacker needs to be able to create a script which the filter/browser doesn’t recognize, but which the scriptengine/browser will run.  That’s a lot harder than you imply.

  3. Mitch 74 says:

    @Ted: I think Ben wasn’t using ‘bolt-on’ to say it’s a quick hack, only that this solution isn’t perfect: however smart it is, it’s still only a workaround for badly secured sites, and may not work in all cases. If such is the case (and that seems to be Ben’s concern), the solution may bring in a false sense of security, letting users become pray to attacks that bypass the workaround.

    Not to say that this is a bad thing for users (overall, it’s very good), but more like something that developers should be aware of.

    Note to IE developers: would it be possible to add an environment variable somewhere that would allow IE to switch to ‘developer mode’ where all such automatic systems provide a UI notification, with the ‘user unfriendly’ messages still being active? It would probably help devs to know when the website they are working on would potentially get screwed up, and advanced user (the ones who may understand cryptic messages) would probably appreciate it too.

  4. steve says:

    IE7 bug (might be in IE8 too)

    If a link is opened in a new tab (from a middle-click), and that link had a target="someFrameName" attribute, the new tab’s window, INHERITS this name.

    This breaks frames that nest in any complex way, and does not behave like any of the dozens of browsers that implemented Tabs before IE.

    Scenario:

    Page

    +- iframe "a"

    +- iframe "b"

    Normal usage:

    If user clicks on a link to load in frame "b". but document loading in frame "b", contains its own iframe "c".

    Links in frame "c" load within itself, but check if their parent.window.name is "b"… if so, they reload "expand" into "b".

    Now in IE7, if you load a link "destined" for frame "b", in a new tab… IE names that new window "b", and SETS the parent.window.name to "b" too (which is wrong, because there isn’t even a parent window!!!), thus ends up in a never-ending loop, constantly reloading into itself (since there is no parent window)

    There is a hack workaround – whereby the content loaded in "c", *ALSO* checks to see if (self == top) and if so, does not do the reload in the parent because it has just encountered the above IE7 bug.

    Does anyone have a better (less hacky fix?) and does anyone that has access to IE8 know if this bug is still in IE?

    many thanks

  5. David R. says:

    @steve I can CONFIRM that this bug is in IE8 BETA 2 also.

    I think I might be able to live with the name being passed to the new tab but "non-existent" parent frame bug is VERY cumbersome.

    in IE4,IE5,IE6 this worked fine:

    —————————————

    if(window.parent && window.parent.name == ‘content’){

     //load in parent window

     window.parent.location.href = self.location.href;

    }

    now in IE7/IE8 we need to modify all of our code to handle this bug.

    in IE7,IE8 this extra garbage logic is needed:

    —————————————

    if(window.parent && window.parent.name == ‘content’){

     var loadInParent = true;

     if(isIE7() || isIE8() ){

       if(top == self){

         loadInParent = false;

       }

     }

     if(loadInParent){

       //load in parent window

       window.parent.location.href = self.location.href;

     }

    }

    /*

     Note: isIE7(), and isIE8() are external functions defined to work around specific IE bugs.

    */

    Can someone at [MSFT] indicate if this bug has been fixed internally or if it will be fixed in IE8 Beta 3?

    Regards,

    David R.

  6. Anonymous says:

    Ben, the filter could be updated, like antivirus;with your logic, both would be worthless.

  7. Hi All, There’s an unfortunate misconception surrounding cross-site scripting (XSS) attacks that result

  8. Ben Voigt [C++ MVP] says:

    Ted,

    Pardon me for my scepticism, but classifying self-modifying executable code (whether source code or machine code for either a VM or physical CPU) is hard.  Javascript is dynamic, with self-modification capabilities.  If they had a perfect solution we’d not be hearing "Microsoft develops XSS Filter", we’d be hearing "Microsoft Researcher solves Halting Problem".

    Yes, you can improve the filter over time, like antivirus.  And yes, if its performance is reasonable, I’ll be glad to use it.  But no, I won’t rely on it for online security just as I don’t rely on antivirus for online security.  It is, as stated, simply defense-in-depth.  I’m not questioning its utility, I just want people to consider whether this article as an exercise in how to lie with statistics.

    From the post "identifies & neuters the attack if it is replayed in the server’s response".  How many blog comments are actually replayed in the server’s response?  Not very many, most say something about the comment will appear in a few minutes.  Ditto for wiki edits.  And you can’t block such posts outright without impacting all blogs that discuss programming and might have Javascript snippets, all bug tracking systems that might include code snippets, all online HTML editor/validator systems, and so on.

    The responsibility of preventing the server from placing tainted user-controlled content in a page it serves subsequently lies with the server.  I don’t want to hear banks disclaiming responsibility for XSS vulnerabilities because "We clearly recommended that you use IE8 which stops XSS attacks".

  9. 이 글은 Internet Explorer 개발 팀 블로그 (영어)의 번역 문서입니다. 이 글에 포함된 정보는 Internet Explorer 개발 팀 블로그 (영어)가 생성된 시점의