Security Research & Defense

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

October, 2013

  • MS13-080 addresses two vulnerabilities under limited, targeted attacks

    Today we released MS13-080 which addresses nine CVEs in Internet Explorer. This bulletin fixes multiple security issues, including two critical vulnerabilities that haven been actively exploited in limited targeted attacks, which we will discuss in details in this blog entry.

    CVE-2013-3893: the final patch after Fix it workaround

    Previously, Microsoft released Security Advisory 2887505 and made available the Fix it workaround 51001 to provide earlier protection to all customers for an actively exploited security issue that was reported to us. Fix it workarounds are examples of the reactive steps that MSRC can take in order to provide earlier protection solutions for customers during active attacks in combination with technologies such as EMET that help make exploitation more complicated for attackers. We have noticed some appreciation of Fix it workarounds across users given the download numbers and we are glad that users are proactively using this type of protection when possible while waiting for the comprehensive update. Today’s bulletin for Internet Explorer addresses this CVE, so we recommend to all customers (with or without Fix it workaround applied) to prioritize the installation of this security update. Customers who decided to install Fix it workaround 51001 can install MS13-080 bulletin at any moment and then remove the Fix it at any time using the uninstaller 51002 (as usual, we remind users that the presence of Fix it does not interfere with security updates and upcoming bulletins).

    We are aware that a Metasploit module has been released recently for this CVE, however from the telemetry received from our partners and sensor feeds, the exploitation activity detected at this moment is still limited in nature and specifically is targeting older IE versions (8 and 9) using an ASLR bypass that requires the presence of Office 2007/2010 on the machine.

    CVE-2013-3897: the unexpected use-after-free

    MS13-080 also fixes a second CVE vulnerability that has been exploited in limited attacks over the web. This issue is a user-after-free vulnerability in CDisplayPointer triggered with “onpropertychange” event handler. This exploit was found cached on a popular Javascript analysis website and reported to us. The exploit code for this issue, released probably around mid-September, uses heap-spray to allocate a small ROP chain around address 0x14141414 and is designed to target only IE8 running on Windows XP for Korean and Japanese language-based users, as showed in the Javascript code snippet below.

    We’d like to take this opportunity to thank our valued partners Trustwave, the National Cyber Security Centre of the Netherlands, and Renato Ettisberger from IOprotect GmbH  for reporting this vulnerability in a coordinated manner and for collaborating with us. We also decided to provide additional details of the exploit and its payload that will help security vendors and users to strengthen defense against these attacks while the security updates are applied.

    MALICIOUS URL SHA1
    hXXp://1.234.31.[x]/mii/swf.js 5F153C6ACB5F63691769E6B8C1FAC772928B08D8
    hXXp://1.234.31.[x]/mii/guy2.html C15DBB6E1206F55553FC892BEA41747FC56532AE
    hXXp://1.234.31.[x]/mii/fird.gif A44649623478987F87ACF6292865D3FCB4294072

    NOTE: [x] has been detected being a variable IP range using .153 and .154 values

    As observed in both exploits, attackers are able to target previous versions of Internet Explorer on older platforms where all the newest mitigations are not available or not enabled by default. As such, we advise users, to install and use the latest versions of Internet Explorer on modern Windows in order to raise exploitation challenges for attackers and have better defense. For more information about the impact of software mitigations on patterns of vulnerability exploitation, Microsoft released recently a whitepaper that can help to understand the role of software mitigations and exploitation strategies of attackers.

    Special thanks to IE team for assembling this fix in record time and Richard van Eeden for help analyzing the root cause of the bugs.

    - Elia Florio, MSRC Engineering

  • Software Defense: mitigating heap corruption vulnerabilities

    Heap corruption vulnerabilities are the most common type of vulnerability that Microsoft addresses through security updates today. These vulnerabilities typically occur as a result of programming mistakes that make it possible to write beyond the bounds of a heap buffer (a spatial issue) or to place a heap allocated object in an unexpected state such as by using the object after it has been freed (a temporal issue). Over time, attackers have developed a number of techniques to help them exploit various types of heap corruption vulnerabilities. Starting with Windows XP Service Pack 2, Microsoft began introducing hardening changes to the Windows heap manager that were designed to make it more difficult to exploit heap corruption vulnerabilities. In this blog post, we will review some of the general methods that have been used to exploit and mitigate heap corruption vulnerabilities and highlight hardening changes that have been made in Windows 8 and Windows 8.1 to further complicate exploitation. For more background on the Windows 8 heap architecture, please refer to the Channel 9 interview on the Windows 8 heap manager.

    Heap corruption exploitation, then and now

    In a previous blog post, we covered the history of heap-based exploitation and mitigation techniques from Windows XP through Windows 7. This blog post showed that prior to Windows Vista, most of the research on heap corruption exploitation techniques focused on corrupting heap metadata in order to achieve more powerful exploitation primitives (such as the ability to write an arbitrary value to any location in memory). One of the reasons attackers focused on corrupting heap metadata is because it was always present and therefore could enable application-independent (generic) exploitation techniques. The release of Windows Vista changed the landscape of heap exploitation through numerous heap hardening changes that addressed nearly all of the heap metadata corruption exploitation techniques that were known at the time.

    As a consequence of the hardening changes in Windows Vista, attackers have largely shifted their focus toward exploitation techniques that rely on corrupting application-specific data stored on the heap. For example, attackers will attempt to use a heap corruption vulnerability to corrupt the C++ virtual table pointer of an object on the heap or to corrupt the base or length field of a heap-allocated array to achieve the ability to read or write to any location in memory. There has been additional research on heap metadata corruption post-Windows Vista and there are a small number of known real-world exploits that have relied on these metadata corruption techniques[1,2,3,4], but as this blog post will show, all of the publicly known exploitation techniques that rely on metadata corruption have been addressed in Windows 8.1.

    Heap corruption mitigations

    The heap manager in Windows 8 and Windows 8.1 builds on the hardening changes of previous Windows releases by incorporating new security features that mitigate not only metadata corruption techniques but also less generic techniques that rely on corrupting application-specific data. These new security features can be broken down into the following threat categories: heap integrity checks, guard pages, and allocation order randomization. All of the security features introduced in Windows 8 have been inherited by Windows 8.1.

    Heap integrity checks

    The heap manager in Windows 8 and Windows 8.1 includes a number of new integrity checks that are designed to detect heap metadata corruption and terminate an application safely if corruption is detected. This section describes some of the noteworthy integrity checks that have been added.

    Catch-all exception handling blocks have been removed

    Previous versions of the Windows heap made use of catch-all exception handling blocks in certain cases where exceptions were considered non-fatal.  This had the potential to make it easier for attackers to exploit heap corruption issues in certain cases, in particular by allowing an attacker multiple attack attempts.  Therefore, these catch-all blocks have been removed from the heap in Windows 8, meaning such exceptions now lead to safe termination of the application.

    HEAP handle can no longer be freed

    The HEAP handle is an internal data structure that is used to maintain the state associated with a given heap.  Prior to Windows 8, an attacker could use a heap-based memory corruption vulnerability to coerce the heap into freeing the HEAP handle data structure.  After doing this, the attacker could force the heap to reallocate the memory that previously stored the HEAP handle state.  This in turn allowed an attacker to corrupt internal heap metadata, including certain function pointer fields.  The Windows 8 heap mitigates this attack by preventing a HEAP handle from being freed.

    HEAP CommitRoutine encoded by a global key

    The HEAP handle data structure includes a function pointer field called CommitRoutine that is called when memory regions within the heap are committed.  Starting with Windows Vista, this field was encoded using a random value that was also stored as a field in the HEAP handle data structure.  While this mitigated trivial corruption of only the CommitRoutine function pointer, it did not mitigate the case where an attacker could corrupt both the CommitRoutine and the field that stored the encoding key.  The Windows 8 heap mitigates this attack by using a global key to encode the CommitRoutine function pointer rather than a key that is stored within the HEAP handle data structure. 

    Extended block header validation

    Each heap allocation returned by the Windows heap has a header that describes the allocation’s size, flags, and other attributes.  In some cases, the Windows heap may flag an allocation as having an extended block header which informs the heap that there is additional metadata associated with the allocation.  In previous versions of Windows, an attacker could corrupt the header of an allocation and make it appear as if the allocation had an extended block header.  This could then be used by an attacker to force the heap to free another allocation that is currently in use by the program.  The Windows 8 heap mitigates this attack by performing additional validation on extended block headers to ensure that they are correct.

    Blocks cannot be allocated if they are already busy

    Some of the attacks that have been proposed by security researchers rely on reallocating memory that is already in use by the program (e.g. [3]).  This can allow an attacker to corrupt the state of an in-use heap allocation, such as a C++ object, and thereby gain control of the instruction pointer.  The Windows 8 heap mitigates this attack by verifying that an allocation is not already flagged as in-use (“busy”) when it is about to be allocated.  If a block is flagged as in-use, the heap takes steps to safely terminate the process.

    Encoded FirstAllocationOffset and BlockStride

    One of the exploitation techniques proposed in [4] involved corrupting heap metadata (FirstAllocationOffset and BlockStride) that is used by the Low Fragmentation Heap (LFH) to calculate the address of an allocation within a subsegment. By corrupting these fields, an attacker can trick the heap into returning an address that is outside the bounds of a subsegment and potentially enable corruption of other in-use heap allocations. The heap manager in Windows 8.1 addresses this attack by encoding the FirstAllocationOffset and BlockStride fields in order to limit an attacker’s ability to deterministically control the calculation of allocation addresses by the LFH.

    Guard pages

    One of the ways that the Windows 8 heap better protects application data and heap metadata is through the use of guard pages.  In this context, a guard page is an inaccessible page of memory that will cause an access violation if an application attempts to read from it or write to it.  Placing a guard page between certain types of sub-regions within the heap helps to partition the heap and localize any memory corruptions that may occur.

    In an ideal setting, the Windows heap would encapsulate all allocations in guard pages in a manner that is similar to full-page heap verification. Unfortunately, this type of protection is not feasible for performance reasons. Instead, the Windows 8 heap uses guard pages to isolate certain types of sub-regions within the heap. In particular, guard pages are enabled for the following types of sub-regions:

    • Large allocations. In cases where an application attempts to allocate memory that is larger than 512K (on 32-bit) or 1MB (on 64-bit), the memory allocation request is passed directly to the virtual memory allocator and the size is updated to allocate extra space for a guard page.  This ensures that all large allocations have a trailing guard page.
    • Heap segments. The Windows heap allocates large chunks of memory, known as heap segments, which are divided up as an application allocates memory.  The Windows 8 heap adds a trailing guard page to all heap segments when they are allocated.
    • Maximally-sized subsegments. Each heap segment may contain one or more subsegment that is used by the frontend allocator (the Low Fragmentation Heap, or LFH) to allocate blocks of the same size.  Once a certain threshold has been reached for allocating blocks of a given size, the LFH will begin allocating maximally-sized subsegments, which are subsegments that contain the maximum number of blocks possible for a given size.  The Windows 8 heap adds a trailing guard page to maximally-sized subsegments. For 32-bit applications, guard pages are inserted probabilistically to minimize the amount of virtual address space that is consumed.

    Allocation order randomization

    One of the behaviors that attackers rely on when exploiting heap buffer overruns is that there must be a way to reliably position certain heap allocations adjacent to one another.  This requirement stems from the fact that an attacker needs to know how many bytes must be written in order to corrupt a target allocation on the heap (while minimizing collateral damage to the heap that could cause the application and hence the attack to be terminated).  Attackers typically try to ensure that allocations are immediately adjacent to each other through techniques that are often referred to as heap massaging or heap normalization.  These techniques attempt to bring the heap into a state where new allocations are placed at a desired location with respect to one another.

    In Windows 8, a new security feature has been added to the LFH which randomizes the order of allocations. This means that allocations that are made through the LFH are no longer guaranteed to be placed immediately adjacent to one another even after an attacker has attempted to normalize the heap.  This has the effect of preventing an attacker from reliably assuming that an allocation containing a target object will be positioned after the allocation that they are able to overflow.  While an attacker may attempt to increase the reliability of their attack by corrupting more data or allocating more target objects, they run the risk of destabilizing the process by corrupting other heap state or causing the process to terminate by accessing a guard page as described in the previous section. This is a good example of several mitigations working together: neither is foolproof on its own, but combined they result in increasingly complex requirements for a successful attack.

    Although allocation order randomization helps make the internal layout of the heap nondeterministic, there are limitations to how far it goes. First and foremost, the performance of the Windows heap is critical as it is used as a general purpose memory allocator by the vast majority of the applications that run on Windows. As a side effect of this, allocation order randomization is currently limited to randomizing allocations within individual LFH subsegments (which accounts for the majority of allocations made by applications). This means backend allocations have no inherent entropy and therefore may be subject to deterministic allocation patterns, as noted in [5]. In addition to performance, there are also inherent limits to the effectiveness of allocation order randomization. If an attacker can read the contents of heap memory, they may be able to overcome the effects of randomization. Similarly, allocation order randomization is not designed to strongly mitigate heap vulnerabilities that are related to object lifetime issues, such as use after free vulnerabilities. This is because an attacker will generally be able to allocate a sufficient number of replacement objects to overcome the effects of allocation order randomization. We’ll discuss some other mitigations that are targeted at addressing use after free issues, which are increasingly preferred by exploit writers, later in this series.

    Conclusion

    The hardening changes that have been made to the Windows heap manager in Windows 8 and Windows 8.1 have been designed to make it more difficult and costly to exploit heap corruption vulnerabilities. This has been accomplished by adding additional integrity checks to metadata that is used by the heap, by protecting application data stored on the heap through the use of guard pages, and by randomizing the order of allocations. These mitigations do not make heap corruption vulnerabilities impossible to exploit, but they do have an impact on the time it takes to develop an exploit and how reliable an exploit will be. Both of these factors play a role in determining whether or not an attacker will develop an exploit for a vulnerability. With that being said, the fact that heap corruption vulnerabilities are the most common vulnerability class that we address through security updates means it is likely that we will continue to see additional research into new exploitation techniques for heap vulnerabilities in the future. As such, we will continue to look for ways to harden the Windows heap to further increase the difficulty of developing reliable exploits for heap corruption vulnerabilities.

    - Matt Miller

    References

    [1] Ben Hawkes. Attacking the Vista Heap. Black Hat USA. Aug, 2008.

    [2] Ben Hawkes. Attacking the Vista Heap. Ruxcon. Nov, 2008.

    [3] Chris Valasek. Modern Heap Exploitation using the Low Fragmentation Heap. SyScan Taipei. Nov, 2011.

    [4] Chris Valasek. Windows 8 Heap Internals. Black Hat USA. Aug, 2012.

    [5] Zhenhua Liu. Advanced Heap Manipulation in Windows 8. Black Hat Europe, Mar, 2013.

  • Software Defense: mitigating stack corruption vulnerabilties

    Introduction

    One of the oldest forms of memory safety exploitation is that of stack corruption vulnerabilities, with several early high-profile exploits being of this type. It seems fitting therefore to kick off this Software Defense series by looking at the status of software defense today with respect to this age-old problem.

    Mitigating stack-based corruption vulnerabilities

    The most common form of stack corruption – overrun of a buffer beyond the amount of stack space that was allocated for it – has been mitigated to some degree since Windows XP via the compiler-based /GS feature. A copy of a per-module random value, the /GS cookie, is placed between the stack local variables and stack metadata including the return address. Before using the return address, the program verifies the integrity of this local copy of the /GS cookie: if its value does not match the master per-process value then an overrun is assumed to have taken place and the program is terminated.

    The limitations of this defensive device have driven a number of refinements over the years; the main ones are summarized in the following table: 

     

     

    Scope of GS protection

    For performance reasons only a subset of functions are protected with a GS cookie. The scope of this protection was initially aimed primarily at character arrays, where attackers would supply malicious strings, often over the network that the program did not handle correctly. GS enhancements in Visual Studio 2010 extended the scope of GS protection to functions with a far more general range of data structures. Visual Studio 2013 builds on this further and also protects arrays of pointers.

    Protecting a function with /GS has a codesize cost – the prolog code to set up the GS cookie on the stack and the epilog to verify its value - and the runtime cost of actually executing these extra instructions. The cost of extending the scope of GS protection has been partially offset by a new compiler optimization: if usage of the buffers that have led to the GS cookie can be proven safe by the optimizer – i.e. all writes to the memory associated with these variables is within the bounds of their allocated stack space – then the GS cookie is eliminated.

    Enabling /GS still typically only inserts a GS check on less than 10% of functions – though clearly this varies considerably depending on usage of local variables in each individual application.

    Evading the GS check through exception abuse

    An important aspect touched on above deserves further discussion – the cookie check only occurs at the end of the function. This means that there is a window between the stack corruption and the GS check in which an attacker can seek to gain control. One favoured approach has been to trigger an exception and abuse the resulting exception handling process.

    On x86, exception metadata associated with SEH is stored on the stack: this includes pointers to the handler code that should be invoked. If the attacker can use the initial stack corruption to modify this SEH metadata – replacing the function pointer with an address of his choosing – then when the exception dispatching code runs, it will transfer control to the attacker-controlled address.

    Mitigating exception metadata abuse on x86 platforms

    Again compile-time techniques can help - /SAFESEH effectively creates a whitelist of exception handler addresses. In the corrupted SEH metadata scenario above, the attacker’s modified ‘pointer to exception handler’ address is not on the whitelist thus defeating the simple form of this exploitation technique. It is however costly: all code needs to be recompiled to benefit – as any non-SAFESEH code in the program introduces a “code with unknown SAFESEH whitelist” module – which for application compatibility purposes means that any address inside that module is assumed to be on the whitelist.

    Windows XP SP2 included a recompile of most OS binaries with /SAFESEH – but even that is not sufficient. Any 3rd party browser plugin (not compiled with /SAFESEH) provided a potential means to evade the /SAFESEH validation.

    SEHOP

    SEHOP, supported initially in Windows Vista SP1 (off-by-default) and Windows Server 2008 (on-by-default), provides a more robust solution. We previously described SEHOP in detail, but a summary of the basic idea is as follows. When an exception occurs, SEHOP walks the entire list of SEH metadata structures on the stack and verifies that it terminates at a special “known good handler address”. Any attacker corruption of one of these structures overwrites the forward pointer to the next SEH metadata structure and so breaks the integrity of the list, which is therefore detected by the SEHOP check.

    Windows 7 added support for per-process opt-in to SEHOP.

    SEHOP in Windows 8 and Windows 8.1

    Windows 8 raises the bar in that SEHOP is enabled by default for applications that built to run on Windows 8 and above (more precisely for any application built with subsystem version greater or equal to 6.2 – see /SUBSYSTEM for details).

    In Windows 8.1 SEHOP is further improved in a couple of ways.

    First SEHOP now has a range of 64 possible distinguished FinalExceptionHandler values that may be chosen, instead of just the one handler address within the system DLL that was used previously.  The actual distinguished FinalExceptionHandler value used to validate the exception handling frame chain is selected at random during process startup, and differs on a per-process basis.  The advantage of this is that SEHOP no longer has a system-wide shared secret, but a per-process secret, such that a local attacker can no longer assume that they know the distinguished value required to pass the frame validation check in a separate process on the local machine.  All of the possible FinalExceptionHandler values are also valid SafeSEH handlers.

    Secondly, Windows 8.1 adds support for SEHOP in kernel mode and enables this by default. Like the enhanced version of SEHOP for user mode, kernel mode SEHOP has 64 possible FinalExceptionHandler addresses, so just disclosing the kernel base address is not enough to defeat kernel SEHOP; one has to be able to read arbitrary kernel memory to do that.

    GS limitations and future work

    The effectiveness of the GS design described thus far – even if it were applied to every stack frame and one assumed that the cookie check were always reached after stack memory corruption occurred – is limited to cases where the cookie value is altered. This is what is detected. Important classes of stack-based vulnerability therefore remain that are not mitigated today for example targeted attacker-controlled writes to a stack address, or stack underruns – i.e. the direction of the writes goes towards the start address of the allocation.

    Visual Studio 2012 updates /GS to emit range checks to mitigate one of the most common types of targeted write scenario that we were seeing through MSRC.

    Recently published trend data shows that the number of successful exploits of stack-based vulnerabilities represents but a handful of the set of issues faced by our customers.

    The obstacles posed by GS, SafeSEH and SEHOP and opt-in to these measures by increasing numbers of developers and IT professionals are likely part of the reason behind this.

    Investment in static analysis tooling has also likely played a part, some of which is available to developers through compiler warnings such as C4789 and CodeAnalysis warnings such as C6200. The lifetime of a stack-based buffer tends to be shorter than its heap counterpart: it is limited to execution of one function – albeit potentially with many callees – making it more tractable to completely analyse its use across the entire program. By contrast pointers to heap allocations are frequently stored in multiple objects with a more complex usage pattern by the program, making it harder for analysis to track usage of a heap buffer with the same level of precision.

    Although some unmitigated stack-based vulnerability classes do occasionally arise in practice – for example MS08-067 which was an underrun of a stack-based array, these are relatively isolated examples. As attacker focus has shifted to the heap, so the priority accorded to improving defensive measures there has increased.

    Conclusion

    Exploitation of stack-based corruption vulnerabilities is one of the oldest forms of memory safety exploit. History shows a succession of mitigation refinements developed to counter to attacker innovations in this area. We note a series of evolutions:

    -          Mitigation robustness and completeness has improved over time, including the protection of arrays of pointers by /GS in Visual Studio 2013 and a move to a per-process rather than a system-wide secret for SEHOP in Windows 8.1.

    -          Counter-measures to thwart exception handler abuse have evolved from expensive (from an engineering perspective) measures such as /SAFESEH that requires recompilation to OS-based SEHOP that can be applied on a per-process basis to existing applications.

    -          Default settings have evolved over time; e.g. user-mode SEHOP is now on-by-default for applications designed for Windows 8 and Windows 8.1, and kernel mode SEHOP is both new and enabled in Windows 8.1.

    A state of relative maturity has been reached with fewer stack-based vulnerabilities being reported or exploited. Does this mean we are “done”? – by no means! Rather attacker attention appears to have turned to other less mature areas. And as attacker focus has shifted, so has defense. The next article takes a closer look at some of the advances related to memory corruption on the heap.

     

    Tim Burrell, MSEC Security Science

  • Assessing risk for the October 2013 security updates

    Today we released eight security bulletins addressing 25 CVE’s. Four bulletins have a maximum severity rating of Critical while the other four have a maximum severity rating of Important. We hope that the table below helps you prioritize the deployment of the updates appropriately for your environment.

    Bulletin Most likely attack vector Max Bulletin Severity Max Exploit-ability Likely first 30 days impact Platform mitigations and key notes
    MS13-080

    (Internet Explorer)

    Victim browses to a malicious webpage. Critical 1 Likely to see continued attacks against both CVE-2013-3893 and CVE-2013-3897. Addresses two CVE’s currently under limited attack and seven CVE’s not known to be under attack.
    MS13-081

    (win32k.sys and OTF font parsing)

    Most likely to be exploited attack vector requires attacker to already be running code on a machine and then uses this vulnerability to elevate from low-privileged account to SYSTEM.

    Additional attack vector involves victim browsing to a malicious webpage that serves up OTF font file resulting in code execution as SYSTEM.

    Critical 1 Likely to see reliable exploits developed within next 30 days.  
    MS13-083

    (ComCtl32)

    Victim opens a malicious RTF file with an embedded control in either Word or Wordpad, resulting in potential code execution in the context of the logged-on user. Critical 1 Likely to see reliable exploits developed within next 30 days. ComCtl32 is used in a number of different scenarios. We expect the most likely attack vector is via MSCOMCTL within an Office document. However, we encourage customers to apply the update on all systems to address other attack vectors as well.
    MS13-082

    (.NET Framework)

    Victim browses to malicious XBAP application hosted by an Intranet zone website. Critical 2 Less likely to see reliable exploit developed for this or other .NET Framework vulnerabilities.  
    MS13-085

    (Excel)

    Victim opens malicious Excel spreadsheet. Important 1 Likely to see reliable exploits developed within next 30 days.  
    MS13-086

    (Word)

    Victim opens malicious Word document. Important 1 Likely to see reliable exploits developed within next 30 days. Office 2010 and Office 2013 not affected.
    MS13-084

    (SharePoint)

    Attacker sends victim a link exploiting a Cross-Site Scripting (XSS) vulnerability on an Intranet SharePoint server for which they have access rights. When the victim clicks the link, an automatic action is taken on their behalf on the SharePoint server that they otherwise might not have wanted to execute. Important 1 Likely to see reliable exploits developed within next 30 days. By default, modern browsers block XSS attacks in Internet Zone sites.
    MS13-087

    (Silverlight)

    Possible to use as component in multi-stage attack as this vulnerability allows attacker access to memory addresses and/or contents from the same process. Important n/a No potential for direct code execution. Information disclosure only.

    - Jonathan Ness, MSRC Engineering