Welcome to MSDN Blogs Sign in | Join | Help

IE8 XSS Filter design philosophy in-depth

It's great to see some positive reaction to the potential of our XSS Filter.  Now we just need to deliver!

In this blog post I’ll try to shed some light on our design philosophy.

To understand how we have arrived at our current filtering approach, it is useful to look back to the XSS Filter’s very beginnings.  Version 1.0 of the XSS Filter prototype, originally released within Microsoft back in 2002, provided users with the following (ugly!) prompt:

XSSFilter v1.0 UI

Clearly this is not something that everyday users would understand or find acceptable!  We needed to find a way to make the filtering automatic and painless and thus provide maximum benefit to users.

The approach we are taking today in Internet Explorer 8 doesn’t simply examine URL / POST data for evidence of XSS – it is capable of validating that an XSS attack has been replayed into the response.  Having identified the replayed XSS, we then have the capability to neuter the XSS on the page in a highly targeted fashion.  Thus, the XSS Filter can be effective without modifying an initial request to the server or blocking an entire response.

The detection of reflections hones our targeting as well – you can’t have “reflected XSS” without the reflection!

Our XSS Filter design goals do not equate success with blocking every conceivable attack technique.  Consider that a reported bug might fall into one of the following categories:

  1. Straightforward implementation flaws.

    Example:  A buffer overrun when a specially crafted URL is passed to the XSS Filter code.

    Any feature, the XSS Filter included, must consider this to be a severe vulnerability.

  2. Mechanisms to bypass the XSS Filter in the general sense.

    Example:  As the XSS Filter was being developed, we identified that URLs that including a %00 were processed by the XSS Filter in such a way that the %00 would decode to a null byte.  This would result in termination of the string we were using to process the URL.  A real attack could then pass through unfiltered after the null byte.

    To be successful, the XSS Filter must address any issue like this that thwarts its overall effectiveness.

  3. Mechanisms to bypass the XSS Filter’s protection for certain specific XSS attack scenarios.

    Example #1: Internet Explorer 7 will effectively ignore the high-bit of each character on a page in the US-ASCII character set.  So when a web page outputs a page in US-ASCII, or can be forced to do so, it was possible to bypass the XSS Filter by setting the high-bit on bytes in the querystring.  (This is resolved in Internet Explorer 8.)

    If we had not addressed this issue, the XSS Filter would be ineffective when the victim page used the US-ASCII character set (either by default or because it was forced).  This would be a serious limitation of the XSS Filter but ultimately it wouldn’t be a deal-breaker – for the growing majority of sites using Unicode the XSS Filter’s effectiveness would remain unchallenged.

    Example #2:  The XSS Filter would not be effective if a web app were to ROT13 decode data from the querystring before replaying it back to the client.  For attacks that depend on application-specific transformations, we will only attempt to make the XSS Filter effective where these transformations are identified to be pervasive.

    We choose not to ROT13 decode URLs.  :-)

  4. Specific new XSS attack vectors.

    Example:  The following use of data binding will result in the execution of script within IE:

    <xml id=cdcat><note><to>%26lt;span style=x:exp<![CDATA[r]]>ession(alert(3))%26gt;hello%26lt;/span%26gt;</to></note></xml><table border=%221%22 datasrc=%22%23cdcat%22><tr><td><span datafld=%22to%22 DATAFORMATAS=html></span></td></tr></table>

    Note there is no SCRIPT tag present.  There are many similar obscure script execution techniques present in all browsers.  These are often called “XSS attack vectors” and many such techniques are archived on RSnake’s cheat sheet.  The XSS Filter does handle this particular XSS attack vector.

    In the general case, we recognize the need to address additional new reflected (Type-1) XSS attack vectors as they are identified.

Observe the distinctions between the different bug categories listed above.  The most important takeaway is our level of pragmatism especially in category #3 above.  We will not be lead to compromise the XSS Filter’s web site compatibility by attempting to address every conceivable XSS attack scenario.

In summary, the XSS Filter will prove its worth by raising the bar and mitigating the types of XSS most commonly found across the web today, by default, for users of Internet Explorer 8.

IE8 goes on the offensive against XSS!

IE has announced the new XSS Filter feature which will debut in IE8 Beta 2!  Stay tuned to my blog in the coming weeks for more details on how the filter works, its history, its limitations, and some lessons learned during the development process.

Lead my team!

My team (SWI React) is hiring for a lead position.  Details:

Job Title: Lead Software Development Engineer
Job Category: Software Development
Product: Trustworthy Computing
Date Posted: 02/16/2008
Job Code: 223577
Location: WA - Redmond
Travel Required: 
 
Do you consider yourself a hacker? Is breaking code a passion? And more importantly, can you teach others how to leverage your thinking? Microsoft’s SWI React team is looking for a someone to lead an elite group of hackers on a mission to protect 440 million people from software vulnerabilities. As the Lead Security Software engineer, you will utilize both your world-class code hacking skills and passion for leading teams as you help deliver a superior, trustworthy set of products to our customers. You will be responsible for analyzing and performing penetration testing on all externally reported vulnerabilities across Microsoft’s diverse product base. To be considered for this position you must have:
     Passion for trustworthy computing & software security
     Ability to stay up to date and adapt to the ever evolving security ecosystem
     Proven people management skills with initiative around growing others
     Experience with organizational goal setting & KPI measurement
     Strong cross group collaboration capabilities - up, down and across.
     Deep customer and partner focus with the willingness to improve offerings and workflow
     Knowledge of common hacking/network tools, exploit writing, networking, cryptography, penetration testing, assembler is a plus.

 

Posted by dross | 0 Comments

XSS-Focused Attack Surface Reduction

All web browsers expose what have been referred to as XSS “attack vectors” – various techniques that XSS attacks can leverage to achieve script execution.  The best and most well regarded list of these behaviors is RSnake’s XSS Cheat Sheet.

The existence of these attack vectors can at minimum present a challenge to filters and other technologies which attempt to block XSS.  But more fundamentally, XSS attack vectors enable XSS bugs that would not otherwise exist.  This is the essential argument for what I term XSS-Focused Attack Surface Reduction.

Let’s explore one example.

Finding a useful reflected XSS bug usually involves identifying a server that will replay data from a URL which is then interpreted by the browser as script.  Often constraints are placed on how the attack must be constructed.  This can result from ineffective filtering that has been put in place or simply due to incidental non-security related filtering at the server.

Here is a simple example attack URL:

http://[server]/[path]/[file].asp?id=70-305zzz<script>alert();</script>

The script element in the URL is injected into the server’s HTTP response as valid HTML.  This vulnerability was addressed with server-side validation.  However, the following variation was later identified, demonstrating the validation to be insufficient:

http://[server]/[path]/[file].asp?id=70-305zzz+"+style="background-position-x:expression\0028\0065\0076\0061\006C\0028\0061\006C\0065\0072\0074\0028\0027pwn3d\0027\0029\0029\0029

This variation makes use Internet Explorer's support for Dynamic Properties.  The character sequence at the end of the URL is an encoded block of Javascript.  While the validation put into place at the server prevents an element from being closed off with a greater-than symbol, it does not prevent the addition of a new STYLE attribute on the element which can contain a Dynamic Property that Internet Explorer will then execute.

The idea of XSS-Focused Attack Surface Reduction is that we can view each instance of XSS as having been enabled by one of a finite number of XSS attack vectors existing in the browser.  Then we can look at ways to regulate each of those vectors in order to reduce the browser's susceptibility to XSS.

In this example above, the vector is a behavior exposed by the Dynamic Properties feature.  The Dynamic Properties feature provides real value as a feature in the browser, so it’s difficult to perform XSS-Focused Attack Surface Reduction without serious compatibility impact.  It’s something we have been looking at closely though.

Fortunately, it turns out that in many cases XSS attack vectors are incidental behavior unlikely to be put to use by legitimate web content.  In these cases, XSS-Focused Attack Surface Reduction becomes much more feasible. 

In Internet Explorer 7, an effort was made to reduce vulnerabilities involving the use of the special “javascript:” and “vbscript:” URL syntax.  Specifically, these URLs were disabled in some contexts.  This actually wasn’t intended to mitigate XSS per-se, but it was in fact an effective instance of XSS-Focused Attack Surface Reduction.  This is because the use of javascript:/vbscript: URLs in unusual places such as IMG or EMBED tags often enabled XSS where it wouldn’t otherwise be possible.  It was great to see that after we released IE7, RSnake noticed the change and updated his cheat sheet.

Essentially, the change described above translates to one less tool available in the XSS exploit author’s toolbox.  This is what XSS-Focused Attack Surface Reduction strives to achieve.

I’m happy to report that IE8 is delivering additional XSS-Focused Attack Surface Reduction goodness.  For Beta 1 you will notice a small but notable step forward – the US-ASCII XSS attack vector has now been closed.  RSnake, feel free to update your cheat sheet once again.  J

The Kill-Bit FAQ - Part 1 of 3 posted to SVRD blog

Check out my ActiveX Kill-Bit FAQ which is now being posted to the SVRD blog.  There are three parts, the first of which is now live.  Parts two and three should be up by the end of the week.

Security Vulnerability Research & Defense blog

My team now has a blog!

http://blogs.technet.com/swi/

I'll be contributing to the team blog in the future.  But don't worry -- my personal blog (this one) isn't going away!

Posted by dross | 0 Comments
Filed under:

MashupOS

The standard IFRAME-based isolation technique for web apps is starting to show its age.  We need something better!

Microsoft Research has posted a new paper scheduled to appear at SOSP '07:

Protection and Communication Abstractions for Web Browsers in MashupOS

RSnake also has an interesting post on this topic.

An innovative new defense against cross-domain vulnerabilities

Cross-domain (or “Universal XSS”) vulnerabilities have long plagued modern script-enabled web browsers.  Shuo Chen of Microsoft Research has developed a new type of defense against these vulnerabilities.  A paper on this new approach has been accepted to the 14th ACM Conference on Computer and Communications Security (CCS).

An Analysis of Browser Domain-Isolation Bugs and A Light-Weight Transparent Defense Mechanism

I contributed some time to Shuo’s project and assisted with providing technical background on historical cross-domain vulnerabilities in Internet Explorer.

Pinning / Rebinding / Quick-Swap DNS Links

A group at Stanford has been researching these issues and recently published Protecting Browsers from DNS Rebinding Attacks.

Also, Dan Kaminski has published his slides from Blackhat 2007, Black Ops 2007: Design Reviewing The Web.

Notes on DNS Pinning

Christian Matthies has an excellent writeup on DNS Pinning (with diagrams!)  If you're tuned into web app security you've probably noticed a lot of discussion around Anti DNS Pinning a.k.a. DNS Rebinding a.k.a. Quick-Swap DNS lately.  You're likely to see a lot more such discussion after this year's Blackhat/Defcon given that there are a number of related talks on the agenda.  If you're there, don't miss out on Dan Kaminsky's talk in particular -- it should include a very slick demo!
 
There are a couple of details I'd like to add with respect how these issues relate to Microsoft products:
 
1)  There's been an assumption that IE actively implements DNS Pinning, as described in the 2002 XWT Foundation Security Advisory.  IE has never implemented a specific DNS Pinning feature.  It just happens that the steps necessary to make a working demonstration require some smart manipulation of IE's session management and caching behavior.  The steps required also may vary between different versions of IE.  So basically, any DNS Pinning type behavior observed in IE is incidental.
 
2)  “Anti Anti Anti DNS Pinning” has been specifically addressed in the version of XMLHTTP that ships with Windows Vista and Windows Server 2003 SP2.  If a web server implements Host header validation, that should be enough to guarantee the server won't be the target of anti-DNS Pinning via XMLHTTP.  After implementing HOST headers for a web site you can validate that content requested without the appropriate Host header is not served.  The linked article mentions IIS 5 but the instructions also apply to IIS 6.  If there's a way for an Internet web page to send an HTTP request with an arbitrary Host header, I would say that's a bug in need of a fix.

Inspect Your Gadget

Michael Howard and I have written up some guidance on how to develop secure Vista Sidebar Gadgets:

Inspect Your Gadget

De-obfuscation using a standalone Javascript interpreter

Mark Wodrich forwarded me this Websense blog post describing how to use a standalone Javascript interpreter to de-obfuscate some script.  Thanks Mark!
Posted by dross | 0 Comments

eval() and document.write(), meet Execute and ExecuteGlobal

Be on the lookout for these two VBScript statements that can be used to achieve the same effect as eval() and document.write(): Execute and ExecuteGlobal.

Jonathan Ness pointed me to an exploit sample that was using Execute, presumably to trip up any eval() or document.write() dependent detection logic or automatic de-obfuscation.  Thanks JNess!

Recursive Obfuscation

Thanks to Jonathan Ness for pointing me to an example of a new obfuscation technique that attempts to thwart the eval() à alert() trick.

Take a look at the following obfuscation script:

 1  <script>
 2  function N(F,D)
 3  {
 4     if (!D) D = ' "#%()-./012348:;<=>@ACEGHILMOPRTVWY\\]_abcdefghijlmnopqrstuvwxyz';
 5  
 6     var f;
 7     var V='';
 8  
 9     for (var c=0;c<F.length;c+=arguments.callee.toString().length-380)
10     {
11           f = ( (D.indexOf(F.charAt(c))&255)<<18) |
12                     ((D.indexOf(F.charAt(c+1))&255)<<12) |
13           ((D.indexOf(F.charAt(c+2))&255)<<6) |
14                     (D.indexOf(F.charAt(c+3))&255);
15           V += String.fromCharCode((f&16711680)>>16,(f&65280)>>8,f&255);
16     }
17 
18     eval(V);
19  }
20  </script>
21  <script>
22  N('[obfuscated goo v1]')
23  </script>
 
The first thing you'll notice is code length dependent obfuscation – observe the use of arguments.callee.toString().  You can use the trick I described in my previous blog entry to deal with this.
 
But what you can’t really see from the script above is that when you alert() instead of eval(), the string you get is:
 
N('[obfuscated goo v2]')
 
So it would seem that eval() is necessary in order to execute N() again to continue the de-obfuscation.  However, when analyzing any exploit you want to stay away from eval() at all costs to avoid inadvertently executing exploit script that hasn’t been analyzed yet.
 
So to de-obfuscate this, carefully perform the steps below. 

Warning: Executing malicious script without properly neutering it is dangerous.  Proceed with caution!  Be sure to read the safety guidance here.

  1. Copy the malicious script to a standalone HTML document.
  2. Replace all instances of eval() with pval(), making sure that the obfuscated script block itself doesn’t implement pval().  There is one instance of eval() on line 18 of the example above.
  3. Make sure there are no other extraneous document.write() calls, eval() calls, or anything else that appears to run script or inject script into the DOM.
  4. Drop the definition of pval() at the top of the file:

    <script>
    function pval(e) { alert(e); }
    </script>


  5. Run through the HTML and copy the N('[obfuscated goo v2]') from the alert().  Press Ctrl-C to copy the contents of the alert dialog to the clipboard.
  6. Paste N('[obfuscated goo v2]') over N('[obfuscated goo v1]')  on line 22 above.
  7. Go back to step 5 and continue as necessary until the ultimate de-obfuscated script is shown in the alert().

So far I’ve only seen recursion one-level deep so I don’t yet have a need for a more sophisticated solution.  If things get out of hand and I start to see multi-pass obfuscation I’ll post a more elegant technique.

High-bit ASCII obfuscation

Here’s another new obfuscation technique I’ve seen in use on malicious web sites recently.  Check out the following HTML:

<html><meta http-equiv=content-type content='text/html; charset=us-ascii'></head><body>¼óãòéðô¾áìåòô¨¢Ôèéó éó óïíå ïâæõóãáôåä óãòéðô¡¢©»¼¯óãòéðô¾</body></html> 

Those funny characters are actually standard ASCII characters with the high-bit of each byte set.  If the high-bit ASCII managed to get posted properly to this blog without getting mangled, you should be able to drop the obfuscated HTML into a file on a web server and observe that browsing to the file results in execution of the following script:

<script>alert("This is some obfuscated script!");</script>

Here’s some quick and dirty C# code that will clear the high-bit of each input byte:

       int char1;
       Char c1;
       FileStream fs = new FileStream([file path], FileMode.Open);
       BinaryReader r = new BinaryReader(fs);
 
       r.BaseStream.Seek(0, SeekOrigin.Begin);
 
       while (r.BaseStream.Position < r.BaseStream.Length)
       {
           char1 = r.ReadByte();
           char1 = char1 - 0x80;
           c1 = (Char)char1;
           Console.Write(c1);
       }
 
Drop this code into a console app and you’ll have a nice de-obfuscator.
 
This interesting behavior of US-ASCII in IE was noted by Kurt Huwig on BugTraq a few months ago.

More Posts Next page »
 
Page view tracker