Security Research & Defense

Information from Microsoft about vulnerabilities, mitigations and workarounds, active attacks, security research, tools and guidance

August, 2008

  • IE 8 XSS Filter Architecture / Implementation

    Recently we announced the Internet Explorer 8 XSS Filter and talked a bit about its design philosophy. This post will describe the filter’s architecture and implementation in more detail.

    Design Goals

    The Internet Explorer 8 XSS Filter is intended to mitigate reflected / “Type-1” XSS vulnerabilities in a way that does not “break the web.” Our baseline approach needs to satisfy the following three conditions:

    • The XSS Filter must be compatible.
      • There should be minimal, ideally zero, disruption to benign content/data. We might be able to achieve effective filtering if we were to drop all non-alphanumeric characters from input, however this would be an unrealistic and overbearing solution. Any solution that involves directly modifying request URLs is likely to persist corrupted data on the server-side. Similarly, approaches that would ask the user questions they can’t answer or block entire pages are not acceptable.
    • The XSS Filter must be secure.
      • In general it must not be possible to subvert the filter by modifying attacks that are otherwise intentionally blocked. Although the XSS Filter cannot mitigate all possible XSS attacks, it can win some critical battles decisively. We can push as far as possible to maximize the XSS Filter’s effectiveness as long as we are also careful not to compromise compatibility or performance.
    • The XSS Filter must be performant.
      • Users prefer a fast browser to a slow one, even if the slower one is “more secure.” So some approaches are simply not acceptable for performance reasons. For example, creating an extra instance of the browser rendering engine for each navigation would be too impactful to consider.

    In implementing the filter, we made decisions to best meet the above goals.

    Practical Considerations

    The XSS Filter must be in a position to observe and intercept requests and responses from the browser to the web server. In Internet Explorer, this is possible via a MIME Filter. The prototype implementation of the XSS Filter was in fact implemented as a MIME Filter, but for performance it was moved into MSHTML (the browser rendering engine) when we built Internet Explorer 8.

    Architecture / Implementation

    Figure A: XSS Filter Hosted in Internet Explorer 8

    Figure B: XSS Filter Logic Flow

    Figures A and B depict a high level view of the XSS Filter. Let’s dig into the details.

    For performance, the XSS Filter only takes effect for navigations within the browser which can result in the execution of script. There’s no need for the XSS Filter to operate on resources such as images (as long as they are truly images when rendered by Internet Explorer).

    The filter also checks the source and destination URLs of navigations within the browser. If the navigation is cross-site, or the source cannot be determined (ex: the user clicked on a Favorite) then the navigation is filtered.

    The XSS Filter can be enabled/disabled per-zone. For the Beta 2 release the XSS Filter will be enabled for the Internet and Restricted Sites zones, but not the Local Intranet zone. Administrators can choose to enable or disable the XSS Filter for any zone via group policy.

    The core XSS Filter engine operates in two stages:

    1. HTTP GET / POST data is scanned to match a set of heuristics that identify XSS attack vectors. Matches are used to build signatures to identify markup/script as replayed in the HTTP response.

    2. Generated signatures are used to scan the HTTP response. Markup/script which has been identified by a signature is neutered to block execution.

    Validating that an XSS attack has actually been replayed into the response maximizes XSS detection reliability – “reflected XSS” requires reflection. Having the capability to identify and neuter the replayed markup/script allows the filter to avoid overbearing mitigations such as querying the user, modifying outgoing requests, or blocking entire pages.

    Our approach is performant in that the only notable “heavy lifting” is the scan of the HTTP response body, which will only occur in cases where signatures are generated. Signature generation is highly indicative of an actual XSS attack and it is rare during everyday browsing.

    Fun with Regular Expressions – Part 1: Heuristics

    If a navigation has met the criteria for filtering, the filter takes the URL as well as any POST data associated with the request, decodes it as necessary, and uses regular expressions to identify XSS attack vectors. These case-insensitive patterns are the filtering heuristics. Here is an example:

    {<sc{r}ipt.*src[whitespace or forward-slash]*=}

    This heuristic will identify SCRIPT tags with SRC attributes. While SCRIPT tags may be common in HTML, their presence in a URL or POST data is one indication of an XSS attack.

    In the example heuristic above, note that the character within the inner braces is what we will refer to here as the neuter character. Each heuristic can have one or more neuter characters. Each neuter character, in this case ‘r’, indicates a character that will eventually be modified by the filter in the HTTP response body in order to block the XSS attack. The ‘#’ character is used as the neuter replacement character – it is effective in breaking HTML elements as well as script blocks into which it is injected.

    The selection of neuter characters in any heuristic is very important. The wrong neuter characters chosen for a heuristic can subvert the filter. As an example, picking a quote symbol as a neuter character would cause the filter to neuter quotes. A smart attacker could use this behavior to force a match and neuter a quote on a page, intending to enable an XSS attack that wouldn’t otherwise be possible.

    A match on a heuristic does not in and of itself trigger the filter to detect XSS. Rather, it indicates to the filter that the HTTP response body must be examined to validate that the script in the input URL or POST data was in fact replayed to the output page.

    The decoding process briefly mentioned above is flexible and can also account for artifacts of various web platforms. As necessary, the filter generates additional signatures (see below) based on alternate interpretations of the same input data. So for example, because malformed URLEncoded characters may be handled differently for different web platforms, the filter must be capable of building proper signatures regardless.

    Fun with Regular Expressions – Part 2: Signatures

    As heuristics are matched, the filter generates one signature for each match. A signature is a new regular expression that will be used to scan the HTTP response body for the replayed suspect input. The neuter replacement character is temporarily put into place in the input after a signature is matched. Matching then continues for a heuristic until no more matches can be found in the input. Signatures are generated for URLs without neuter replacement characters in place. Otherwise the signatures would themselves contain neuter replacement characters and they would not correctly match attacks present in the HTTP response.

    With each heuristic, a list of safe characters is provided. For the heuristic that detects script tags, the safe characters are the greater-than and less-than characters and also alpha-numerics. The safe characters effectively form the essence of the XSS attack the filter is attempting to identify.

    Why signatures?

    If the filter were to simply search for a match verbatim it would not necessarily find one. The web server may incidentally remove or translate particular characters from the request as it is replayed. It is in fact common and attackers can use this behavior to their advantage.

    Safe characters are restricted to the “low-ASCII” range (0x00 – 0x7F) so that we can essentially remain character-set agnostic. Character sets that are capable of alternate “low-ASCII” encodings (eg: UTF-7) are not currently special-cased, however some new restrictions are being placed on the general usage of these character sets moving forward. (These changes are outside the scope of this blog post but stay tuned to my blog for more details).

    Here is an example match for the heuristic that detects script tags:

    <SCRIPT src=””

    The signature generated for this match would be:


    Each ¤ in the signature indicates a non-safe character from the original match. A sequence of zero to N unspecified characters will match any ¤. (Currently N is 10)

    If no signatures have been generated for a particular page then the filter permits the page to load without modification – no XSS was detected.

    However, if signatures do exist, the filter scans the HTTP response body for each signature. Once identified, the filter records exactly which character(s) must be neutered, as indicated in the signature by the characters within the braces. Once the signature list is fully processed the neuter replacement characters are put into place and the HTTP response body is passed on to render in the browser.

    The page will render normally except the information bar will notify the user that the page was modified and the XSS attack will be disabled.

    XSS Filter Limitations

    Like all security mitigation and protection technologies, the XSS Filter’s approach does have limitations, being that it is a pragmatic balance between application compatibility, security, and performance. Some examples:

    • Injection into some contexts is not blocked. Ex: Scenarios where content can be injected directly into javascript without breaking out of a string.
    • Injections facilitated by some HTTP headers are not currently blocked. Ex: “Referer” based injection.

    • If a page contains multiple nearby injection points, attacks can be constructed that thwart the XSS Filter.
    • These are all issues that undoubtedly occur on real web sites. The XSS Filter design philosophy dictates that we make a distinction between issues that generally enable the XSS Filter to be bypassed vs. issues that apply only in certain situations. The issues above, while very notable, clearly fall into the latter category. As time goes on we will continue to enhance the XSS Filter to maximize its effectiveness, however we will not compromise web site compatibility in the process.


      It is challenging to mitigate XSS in a way that balances the needs of compatibility, security, and performance. The XSS Filter’s two-stage approach helps us achieve these goals by very specifically targeting reflected (“Type-1”) XSS attacks. This architecture allows us to mitigate the XSS most commonly found across the web today, by default, for users of Internet Explorer 8.

      - David Ross, SVRD Blogger

      *Postings are provided "AS IS" with no warranties, and confers no rights.*

      August 19, 2008, 4:15pm: Updated with correct date

  • MS08-049 : When kind of authentication is needed?

    MS08-049 is an update for the Windows Event System service to correct an authenticated elevation-of-privilege vulnerability. We received a question via email yesterday about the type of authentication needed to exploit CVE-2008-1456. Our security bulletin was a little ambiguous with one reference to "logon credentials" and another to "domain credentials". The email question was from an IT security manager who wondered whether his hardened servers could be compromised remotely. He had disallowed local logon rights to regular users.

    The Event System service runs in a shared svchost.exe process with the default svchost COM access permissions. That service ACL grants local or remote access to all Authenticated Users. The Authenticated Users group includes all domain users and all local workstation accounts on the targeted machine. However, the guest account, even if enabled, is not authenticated so COM will block the call, whether made locally or remote. The MSRC has updated the bulletin to be more precise.

    We hope this clarifies the risk of this vulnerability. It is only rated "Important" due to its effect of authenticated elevation-of-privilege. However, an authenticated attacker can remotely compromise any unpatched Windows machine in your network that is domain joined, including your domain controller or Exchange server. It's one of those "Importants" that is very important to address, so we highly recommend that you apply this update.

    - SVRD Bloggers

    *Postings are provided "AS IS" with no warranties, and confers no rights.*

  • MS08-050 : Locking an ActiveX control to specific applications.

    MS08-050 concerns an ActiveX control that can be maliciously scripted to leak out personal information such as email addresses.

    There appeared to be no need for the control to have this behaviour so giving it a Kill-Bit seemed the correct approach to take. During the extensive testing that each security update undergoes, however, it became apparent that the Kill-Bit wasn’t ideal as it partially broke the Remote Assistance application.

    So how do we kill off a control, keep the Remote Assistance functionality and still protect our customers?

    Firstly the original control must receive a Kill-Bit to prevent the control being foisted on to users.

    Secondly the control was modified so that when it initializes it first checks to see what process it’s running within. If the process attempting to invoke the control is Remote Assistance (1) or if the caller is in a white list of applications found in the registry (2), then the control is permitted to be loaded. Otherwise it will not load.

    Finally we issue a Phoenix-Bit (AlternateCLSID) so that Remote Assistance can continue to use the old ClassID.

    1 "%SystemRoot%\pchealth\helpctr\binaries\helpctr.exe"

    2 "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\App Paths\ImageName\” Where ImageName is the name of the executable that is to be added to the list (e.g. foo.exe), has the value "AllowMessengerExecHandleFailure" of type DWORD and the data set to 1

    - Security Vulnerability Research & Defense Bloggers
    *Postings are provided "AS IS" with no warranties, and confers no rights.*

  • MS08-043 : How to prevent this information disclosure vulnerability

    In this month’s update for Excel we addressed an interesting CVE (CVE-2008-3003) – the first vulnerability to affect the new Open XML file format (but it doesn’t result in code execution). This is an information disclosure vulnerability that can arise when a user makes a data connection from Excel to a remote data source and checks a checkbox to have Excel NOT save the password used in that connection to the file. The checkbox had no affect when saving the file in the new Open XML (.XLSX) file format and the password was thus errantly saved to the file – thus the vulnerability. So in case you haven’t heard – the new Open XML files (the Office files that end with an ‘x’ in the extension i.e. .docx, .xlsx., .pptx) are actually ZIP containers! In fact if you change the file extension to .ZIP you can open the new Office Open XML files in Winzip or the Windows shell to check out the contents for yourself without the need of fancy hex editor. If you do that – what you will see is mostly a bunch of XML files and image files (assuming you have images in your Office apps) inside. As it turns out – to verify / repro this bug report - all that was needed was the Windows shell (to open the renamed Office ‘.zip’ file) and Notepad (to edit one of the XML files inside). In fact the Windows shell and Notepad are all that’s needed to work around this bug (as detailed in the workarounds section of the bulletin for this vulnerability) and remove the accidentally leaked information from your .XLSX files!

    Here’s how you can inspect an .XLSX file to see if it has an improperly saved database connection password in it and how you can remove it and fix the file up yourself!

    • Make a backup copy of the XLSX file that you will be editing.
    • On a Windows XP or Windows Vista machine change the file extension of the affected .XLSX file to .ZIP
    • Using the Windows shell (i.e. Windows Explorer) open the ZIP file by double clicking on it and then double click on the 'XL' folder inside.
    • In the 'XL' folder click on 'connections.xml' and drag it out of the ZIP file to a local folder or your desktop.
    • Right-click on the 'connections.xml' file and select 'Open With' and then choose 'Notepad'
    • Locate the string "connection=" and then search for "PWD=" later in that string. Remove any characters after the "PWD=" and before the ";" characters as these are the improperly saved password for the connection. For example if you have an XLSX file with a saved connection password you might see a string like the following in connections.xmls:
    • <?xml version="1.0" encoding="UTF-8" standalone="yes"?><CONNECTIONS xmlns="">
      <CONNECTION id=1 saveData="1" background="1" refreshedVersion="3" type="1" name="Query from Test Machine">
      <DBPR command="SELECT * FROM FOO" connection="DRIVER=SQL Server;SERVER=SQLSERVER;UID=sa;PWD=sa;APP=2007 Microsoft Office system;WSID=CLIENT;DATABASE=master">
    • Save the connections.xml
    • Drag the connections.xml file back into the ZIP folder making sure to place it in the 'XL' folder inside the ZIP file.
        a. NOTE: Some applications such as Winzip will default to placing the file at the root of the ZIP archive and will not overwrite the file in the 'xl' folder by default.
    • Change the file extension of the ZIP file back to XLSX and then open the document in Excel 2007, click on the 'Data' menu and then click 'refresh all' in the connections part of the ribbon and verify that you are prompted for the password.

    - Security Vulnerability Research & Defense Bloggers
    *Postings are provided "AS IS" with no warranties, and confers no rights.*

  • MS08-042 : Understanding and detecting a specific Word vulnerability

    A few weeks ago we posted a blog entry titled "How to parse the .doc file format". Today's blog post will show you how to use that information to check whether a .doc file is specially crafted to exploit MS08-042, one of the vulnerabilities addressed by today's security updates. This particular vulnerability is being exploited out in the real world so we believe the benefits of releasing more information about it to help the defenders outweighs the risk of attackers learning more about the already-public vulnerability.  So today we are releasing information about this vulnerability and talking about a few tools that will help you analyze documents.

    Defragment the .doc file
    Wait – defragging is just for file systems, right? Well, if you remember our discussion of the compound binary format, it can be described as a file system within a file. One of the properties of the compound binary format is that the streams can be fragmented in the file. Last time we talked about using APIs to extract the streams of interest from the .doc file. This time we’ll talk about how to read the .doc file itself and detect attempts to exploit the vulnerability. Our technique will only work on a file that is not fragmented. You can learn about how fragmentation works in these files by reading the compound binary format specification.

    A quick note about hex editors
    While you can use any hex editor you like to do this analysis, for our examples we’re going to use the 010 Editor v3 from SweetScape Software. We chose this editor for its Binary Template functionality, which is well suited to detecting potential exploits of this vulnerability.

    Reading the WordDocument stream
    Once you’ve defragmented the .doc file you want to analyze, open up the WordDocument stream, look at the 16 bit value at offset 0xA, and examine bit number 10 (AND it with 0x200). If that bit is 0, then we will be working with the 0Table stream, and the 1Table stream otherwise.

    Next, look at the 2 DWORDs that start at WordDocument stream offset 0x42A. The first is an offset into the xTable stream, the second is a length. If the length is 0, then the structure we are interested in does not exist in this file, and so it is not crafted to exploit MS08-042. Otherwise, read on to find out we use the offset to determine if the file is malicious.

    To make things easier, I’ll use examples from our 010 binary template for this next section. You can find the entire template attached to this blog entry.  In our 010 binary template, after the portion that parses the compound binary format, we loop through the streams looking for one that is named WordDocument. Once we find it, we make note of which xTable stream to use, as well as the offset and length we just discussed:

    // Loop through all of the streams looking for the ones we are interested in
    for( dwCtr = 0; exists( stDir[dwCtr] ); ++dwCtr )
       // Memcmp doesn't compare arbitrary memory, just strings...
       if(    stDir[dwCtr].wCbEleName     ==  14
           && stDir[dwCtr].strEleName[ 0] ==  48   // 0
           && stDir[dwCtr].strEleName[ 1] ==  84   // T
           && stDir[dwCtr].strEleName[ 2] ==  97   // a
           && stDir[dwCtr].strEleName[ 3] ==  98   // b
           && stDir[dwCtr].strEleName[ 4] == 108   // l
           && stDir[dwCtr].strEleName[ 5] == 101   // e
           && stDir[dwCtr].strEleName[ 6] ==   0 )
          dwTableStream[0] = dwCtr;
          dwTableStrLen[0] = stDir[dwCtr].dwSizeLow;
          if( dwTableStrLen[0] < OleHeader.dwMiniStrMax )
             qwTableStrOffset[0] = MiniSectOffset( stDir[dwTableStream[0]].dwStartSect );
             qwTableStrOffset[0] = SectOffset( stDir[dwTableStream[0]].dwStartSect );
    // Determine which table stream to use
    FSeek( qwWordStrOffset + 0xA );
    WORD Flags;
    local uint iWhichTableStream = (Flags & 0x200) >> 9;
    // Get the offset into the Table Stream and structure length from the WordDocument stream 
    FSeek( qwWordStrOffset + 0x42A );
    DWORD fcSttbfBkmkFactoid;
    DWORD lcbSttbfBkmkFactoid;
    if( lcbSttbfBkmkFactoid == 0 )
       Printf( "Clean document.\n" );
       Printf( "This document doesn't contain any smart tags.\n" );
       Warning( "Clean document." );
       Exit( 0 );

    And finally, reading the xTable stream
    If we’ve gotten this far, we have a properly parsed .doc and we’ve determined that there is a smart tag structure in the xTable stream. Now we need to examine the structure in the table stream, so we’ll define the structure in our binary template. You can see which value we’re testing to detect potential exploits as well:

    typedef struct
       WORD wWordCount;
       byte bOtherData[12];
       if( wWordCount < 6 )
          Printf( "This document is malicious!\n" );
          Warning( "This document is malicious!" );
          Exit( 2 );
    } SMARTTAG ;
    typedef struct
       WORD wAlwaysFFFF;
       WORD wNumSmartTags;
       WORD wExtraData;

    Finally, we need to actually read in the SMARTTAGSECTION structure, and then all of the SMARTTAG structures it tells us about:

    FSeek( qwTableStrOffset[iWhichTableStream] + fcSttbfBkmkFactoid );
    SMARTTAGSECTION stSmartTagSection;
    for( dwCtr = 0; dwCtr < stSmartTagSection.wNumSmartTags; ++dwCtr )
       SMARTTAG stSmartTag;
       FSeek( startof( stSmartTag ) + ( stSmartTag.wWordCount + 1 ) * sizeof( WORD ) );

    Having a smart tag with WordCount < 6 sets up the condition for the vulnerability to occur, but it won’t actually be triggered unless there is some other corruption in the document which causes Word to abort the loading of the document. Since a benign .doc should never have a smart tag with WordCount < 6, we are done with our detection logic!  You'll find this logic encapsulated in the attached binary template.

    Of course, being able to detect attempts to exploit a vulnerability is no substitute for installing the security update! We strongly encourage you to install MS08-042 as soon as possible.

    - Security Vulnerability Research & Defense Bloggers
    *Postings are provided "AS IS" with no warranties, and confers no rights.*

  • MS08-041 : The Microsoft Access Snapshot Viewer ActiveX control

    MS08-041 fixes a vulnerability in the Microsoft Access Snapshot Viewer ActiveX control. It’s an interesting vulnerability so we wanted to go into more detail about platforms at reduced risk and also more about the servicing strategy for this vulnerability.

    Windows Vista at reduced risk?

    We first heard about this vulnerability from customers sending in reports of active attacks. We issued security advisory 955179 in response to those attacks. Attackers had found a race condition that tricked this legitimate ActiveX control into downloading a file from any internet URL and writing it to any path on the local disk. The first attacks placed a trojan malware executable in the user’s startup folder to be run on next reboot. Later, attackers figured out how to overwrite core system files and then immediately cause those files to be loaded. The most recent attacks we have seen will even prompt the potential victim to download the ActiveX control if they do not have it already installed.

    There is some good news, however. Windows Vista has a great defense-in-depth protection about these types of attacks. The IE7 “Protected Mode” feature of Windows Vista does not allow ActiveX controls (or anything running inside the browser) to write out to sensitive areas of the file system. So Vista users are at a substantially reduced risk from infection through the normal IE attack vectors that we have seen used in these attacks.

    MSRC ActiveX control servicing strategy

    There is one wrinkle in our servicing strategy for this vulnerability. You might recall from previous ActiveX control cases that the MSRC typically ships an updated binary along with a killbit for the old binary and phoenix bit pointing to the new binary. The new binary, the killbit, and the phoenix bit will all be installed by a single package ensuring that legitimate use of the ActiveX control will not be disrupted. One or two months later, the MSRC will ship a stand-alone killbit to block any instantiation of the old control. The idea is that any legitimate users of the control by then would have the phoenix bit pointing to the new binary so killing the old clsid entirely will not disrupt legitimate use of the binary.

    MS08-041 is the package that ships the updated Snapshot Viewer ActiveX control, the killbit for the old clsids, and the phoenix bit pointing the old clsids to their new clsid equivalents. So if you install MS08-041, you will be safe from attacks leveraging this vulnerability in snapview.ocx. However, keep in mind that if you don’t already have Microsoft Office installed, you likely won’t be offered MS08-041 by Microsoft Update. It makes sense because if you don’t have the control installed, you wouldn’t want Microsoft to push it down onto your computer. From the previous paragraph, recall that the MSRC will follow the initial package with a stand-alone killbit. That will ship with the next ActiveX killbit package after users who legitimately use and need the Snapshot Viewer ActiveX control have installed the new binary. In the meantime, if the computers you control do not have Office installed, you should consider setting the killbit on those computers to be sure you’re safe. You can find the steps to do so in the bulletin workaround section.

    - Security Vulnerability Research & Defense Bloggers
    *Postings are provided "AS IS" with no warranties, and confers no rights.*