Exploiting a Microsoft Edge Vulnerability to Steal Files

This blog post documents our Security Researcher Ziyahan Albeniz’s experiment in exploiting a Microsoft Edge browser vulnerability. He explains how a combination of SOP, the ability to email clickable links and a vulnerability in both the Windows Mail and Calendar applications actually enable the exploit. It includes his Proof of Exploit video.

In 2015, Microsoft released the Edge browser. When it was first developed, it was named Project Spartan. Unlike Internet Explorer, Edge supports a wide range of modern security measures such as Content Security Policy (CSP), as well as modern JavaScript and CSS features. Ditching the development of Internet Explorer and starting over with a modern browser like Edge brought many new security advantages – but also, some problems.

One thing that's often overlooked in similar, new development projects is the knowledge gained from years of small security fixes on the original product. Those experienced with the inner workings will know that your team would probably initially get more wrong than right during the process of developing a new browser today. The reason for this is that browser security is under constant redevelopment as new hacks arise, since browsers are viewed as one of the richest sources of potential attack surfaces by hackers and security professionals alike. Small security holes that used to lead to the leakage of user data in browsers have been resolved over the years. Some were more severe than others, but most of them weren't immediately obvious in the first place. It is these security fixes, and the knowledge that comes with it, that may get lost when redesigning a web browser. That might explain why Microsoft Edge was the only browser I found that was vulnerable to this flaw.

Microsoft Edge browser

Note: this vulnerability has already been fixed by Microsoft.

Who is at Risk From This Microsoft Edge Vulnerability?

I've successfully tested my exploit on Microsoft Edge 40.15063.0.0.

How Can You Steal My Local Files?

Let's first think about why I shouldn't be able to steal your local files! The Same Origin Policy (SOP) would prevent https://attacker.com from reading file://C:/your/stuff.txt, for example. The reason is that they have different origins. In order to read data using a JavaScript-issued request, the protocol, the hostname and the port need to match. However, file URLs are a little special. The file:// protocol and the https:// protocol are obviously different, which is why attacker.com can't read your local files. But what if we're dealing with two file URLs neither have a hostname nor a port? They only have the file protocol scheme and a path. This means that the two file urls would automatically be from the same origin because:
  • The port matches: Both have no port
  • The hostname matches: There is no hostname on both of them
  • The protocol scheme matches: Both use the file:// scheme
In other words, if the browser developers wouldn't take the special format of file:// urls into consideration, it would be possible for me to read the content of any local file if you simply opened a malicious HTML file saved on your machine! You might conclude that this is not a very convincing attack vector – perhaps because you've never download random HTML files. In addition, Windows might block the file you just downloaded, since it came from another computer. At least, this was the case when I tested the attack.

Is This a Realistic Threat? Or Is It a Theoretical Scenario?

Do you think an attacker could somehow convince a potential victim to download a HTML file and execute it? Due to the existence of another attack vector, it turns out that this is not merely a theoretical scenario. If you can't deliver your HTML file through the browser, why not simply mail it to your victim? In the last few years we've become all too cognisant of the fact that it can be A Very Bad Thing to open unknown attachments such as .exe files, .js files and even Word documents. But HTML files? There is no obvious immediate danger. After all, we request many HTML files in our browsers every day. I drafted an email from another computer, added the file as an attachment and then opened the attachment in the Mail and Calendar app. Much to my surprise, it worked. I expected that the app, like the Edge browser, would block the attachment. But this was not the case at all. When I sent the email as an attachment and waited until a user opened it, it would immediately send local files of my choosing to my server, where I could store and read them. There is probably no antivirus program that would recognize my file as malicious, and, I could extract the files over a secure HTTPS connection. This is what makes this attack so stealthy! The Windows Mail and Calendar version where I tried my exploit was version 17.8600.40445.0 (This bug was reported too). But there are other ways to deliver the file, depending on the target's installed programs.

Microsoft Mail

How Can I Protect My Files?

The only way to protect yourself is to update to the latest versions of the Edge browser and Windows Mail and Calendar applications. And, of course it's best to never open attachments from unknown senders, even if the extension doesn't initially appear to be malicious. But this was a very theoretical post. If you want to see my exploit in action, you can watch my proof of exploit video.

Proof of Concept Video of the Attack

If you think this was a very theoretical post, see my exploit in action in this proof of exploit video.

Code for Exploiting the Edge Vulnerability

Below is also the code that the hacker can use in the HTML file to exploit this Edge vulnerability.
<html>
<head>
<script>
let resultDiv = document.getElementById("result");
    let xhr= new XMLHttpRequest();
    let user = document.location.href.match(/file:\/\/\/C:\/Users\/([a-z0-9\-]*)\//i)[1];
    xhr.open("GET",'file://C:/Users/${user}/Desktop/secret.txt");
    xhr.onreadystatechange = ()=> {
     if(xhr.readyState==4) {
     resultDiv.innerText = xhr.responseText;
     }
    }
    xhr.send();
</script>
</head>
<body>
</body>
<div id="result"></div>
</html>