Status: Fixed (as of Jan 13, 2016)

Recently a Universal Cross-Site Scripting(UXSS) vulnerability (CVE-2015-0072) was disclosed on the Full Disclosure mailing list. This unpatched 0day vulnerability discovered by David Leo results in a full bypass of the Same-Origin Policy(SOP) on the latest version of Internet Explorer. This article will briefly explain the technical details behind the vulnerability.

The Attack

The original Proof-of-Concept(PoC) can be boiled down into the following simplified one:

<iframe src="redirect.php"></iframe>  
<iframe src="https://www.google.com/images/srpr/logo11w.png"></iframe>  
<script>  
    top[0].eval('_=top[1];alert();_.location="javascript:alert(document.domain)"');
</script>  

The simplified PoC requires an iframe with a HTTP redirect to a resource on the target domain, and another iframe which also loads a resource on the target domain. What is worth noting is that the two resources do not necessarily need to be the same, nor their Content-Type matter. In summary:

  1. Browser renders the first frame and issues a request to redirect.php.
  2. Browser renders the second frame and issues a request to target resource.
  3. Browser executes the script which invokes eval on the WindowProxy object of the first frame and perform the following steps:
    1. Assign the WindowProxy object of the second frame to a variable.
    2. Pop-up an alert dialog box.
    3. Wait until the dialog box is closed by the user.
    4. Change the location via the variable assigned of the second frame and inject payloads.
  4. The injected payload is executed in the second frame on the target's origin.

Updated: The resource requested by the first frame does not need to be on the target domain.

Under The Hood

Apparently, the key of the vulnerability appears to be the dialog box. Before diving into it, it is necessary to know that modal dialogs like alert, prompt, and confirm (or other synchronized functions) will freeze browsers' process due to JavaScript's single-threaded nature. However, the concrete implementation slightly differs on different browsers. Let's take a look on the timelines of each browser handling the PoC:

Firefox

Timeline for Firefox

When the dialog box pops up, Firefox will continue to handle network requests. After the target resource on frame 1 was redirected and finished loading, the original script execution will be terminated and the dialog box will be closed automatically at the same time (NS_ERROR_NOT_AVAILABLE: prompt aborted by user). Therefore, anything after the dialog box will never be executed.

Chrome

Timeline for Chrome

When the dialog box pops up, all network traffic in Chrome will be clogged up until the dialog box is manually closed. After that, even the location change can be executed, there won't be any danger since the origin of frame 1 remains the same (attacker's) instead of target's origin.

Internet Explorer

Timeline for Internet Explorer

When the dialog box pops up, Internet Explorer will also continue to handle network requests. However, when the dialog box is manually closed after the target resource finished loading, the location change will be executed on behalf of the target resource (i.e. target's origin).

The Root Cause

Before redirecting to target resource, script execution does not break SOP because redirect.php is still on the same origin of the attacker's. However, once the target resource finished loading on frame 1, Internet Explorer will update the origin information accordingly. As a result, the previous script execution will suddenly be executed on the targets' origin.

As a side note, the attack has to be done using two frames because Internet Explorer will remove all the object references once navigation occurs. The suggested fix would be either terminate the script execution or remain the origin information when navigation occurs.

Updated: It turns out it is not completely a Time-of-check Time-of-use(TOCTOU) issue. In fact, the origin check is discarded after the thread blocking finished.

User Interaction

It seems that the attack requires user interaction (dialog box) which makes it less plausible, while it actually does not. Consider the following improved PoC:

<iframe src="redirect.php"></iframe>  
<iframe src="https://www.google.com/images/srpr/logo11w.png"></iframe>  
<script>  
    top[0].eval('_=top[1];with(new XMLHttpRequest)open("get","sleep.php",false),send();_.location="javascript:alert(document.domain)"');
</script>  

In essence, abusing dialog boxes is just one way to achieve thread blocking. We can issue a synchronous request with an artificial delay using XMLHttpRequest

Affected Versions

It is confirmed that the vulnerability affects Internet Explorer 10 and 11 on Windows 7 and Windows 8.1.
Windows 10 is not affected (Edge/IE).

Remedy

  • For site owners, there is no feasible way to prevent this attack. Some suggest relying on X-Frame-Options(XFO), but it is not helping much unless you are confident that all responses have XFO applied.

  • For normal users, consider switching to other browsers until Microsoft patches the vulnerability.

References