*36C3 preroll music* Herald: The next speaker works as a security consultant at Payatu software labs, and he loves finding security flaws in the Microsoft Edge browser. And incidentally, this is the topic for this next talk. So please give a big round of applause to Nikhil Mittal. *applause* Nikhil Mittal: So, welcome to the talk: Breaking Microsoft Edge Extensions Security Policies. My name is Nikhil, I work at Payatu Labs. And I am into web browser vulnerability research. So to start with this presentation, I would like to know how many of you uses browser extensions in general, like... Oh, nice. So many of us. OK. So a browser extension is something that extends the functionality of your web browsers. We have a typical examples like Adblock Plus, which I think most of the people uses to block the ads on some certain sites like YouTube. And Grammarly and some sort of password managers as well. So these extensions are capable of managing most of your data because they can handle the cookies, bookmarks, storage, passwords, history and what not. So that being said, we all have to agree on a point that these extensions are powerful, because they can deal with your cookies, bookmarks and other sensitive information in the browsers. So here is how simple AdBlock Plus extension looks like on Microsoft Edge, which is pretty much doing its job. Now. Have you ever tried to figure out what this extension is capable of doing in your browser? So if you look at the settings. Here we have a couple of permissions, which I've listed down on the next slide. So it's simple Adblock Plus extension, can read and change content on websites that you visit. It can read and change your favorites. It can see the websites you visit. It can read and change anything you send or receive. And it can also store personal browsing data on your browser and it can also display notifications as well. So there are so many things a simple Adblock Plus extension can able to do in your browser. So you might ask like how browsers recognize these permissions, like a extension is able to do so many things in my browser. But how does browser recognize like where are these permissions coming from? So here is a permission modeling browser extensions. So under the source of every extensions, we have a file called as manifest.json and inside of manifest.json file we have a permission area. So, here's a quick example of a permission area, where we have some permissions. So the first one is a https://www.google.com, which we'll see right after this slide. The next permission we have is bookmarks and cookies, history, storage and tabs. So let's suppose an extension has a permissions with the bookmarks and cookies. So that means that extension can handle your bookmarks. It can manipulate them. It can edit them. It can remove them and what not. So the same goes with the cookies, history as well. And there are other important permissions as well available for the browsers. So apart from these permissions, the most interesting permission that I was looking for is the host access permissions. So the host access permission is something that defines on which certain domains your browser extensions should able to run. So in this case, let's suppose we have assigned a permissions to a https://www.google.com. So that means this extension should able to run on Google.com only, not even the subdomain that is developer.google.com or mail.google.com. So this you can also verify with the tiny box that says this is allowed to read and change content on some sites www.google.com. Now the second permission we could have in this here is https://*.google.com. So basically this also covers the subdomains as well. And the third possible permission we can have is *://*.google.com. So basically this is now not only I'll work on google.com, but basically on all the protocols as well, which is HTTP, HTTPS, might be FTP. That belongs to the particular domain. So apart from these three permissions, we have the another permission in the roll, which is . This permission is so special because once a browser extension is assigned to all_urls permissions that can execute Javascript code on every domain that you visit. So let's suppose you are on google.com or maybe you're on bing.com or anything else it will work on most probably on every domain. But there are few restrictions with the all_urls permissions. That is, it cannot run on privileged pages. So if privileged pages in browser is something that contains some sort of sensitive settings on your browser data, so you might heard of chrome://settings, which contains the password manager for Chrome. And also you can identify the credit card and debit card information on chrome://settings as well. So you can imagine a situation once the extension is able to run a Javascript code on Chrome setting page then it can probably read, or it can steal all of your passwords and credit and debit card information as well. So on the Edge, we have a similar page, which is about:flags. So here you can see one extension with permission is assigned. It can read and change content on websites you visit. As for the Edge. So here's a quick snap of about:flags in Edge. And so if you look at the first part, you will figure out there are a few embedded permissions. Like you can enable Adobe Flash Player. You can also enable developer features. And also you can enable and disable allow an unrestricted memory consumption for the Web pages as well. And it also has some standard previews features, like you can enable / disable some experimental Javascript features as well. So now you can imagine what the sensitivity of this page contains, okay? So let's quickly build an extension. So that will break most of the things in Edge. So as I said, every extension has a manifest.json file which has all the permission and other configurations. The second file that we will be needing is popup.html. So popup.html is nothing, but it's just interface for the browser extension. So basically you might have noticed as soon as you click on any of the browser extension, a pop up appears on your window for that contain some sort of functions. That is nothing but just a popup.html file. And then again we have a popup.js which has all the Javascript code that executes according to the actions chosen by the popup.html. So this is how our extension should have looked. And on the edge. So we have seen a tiny Microsoft logo and as soon as you click on it, a popup will appear. It says, I am the evil extension and I have two options. The first one is open. The second one is execute. So as soon as you click on the open button, what it does is it will load google.com on the browser. And as soon as you click on the execute button, it will just alert(1) for you. So basically. So basically the interface is written in popup.html. And again, as soon as you click on execute, so the work is done by popup.js. So let's quickly look at the source code for the manifest.json file. The thing to notice here is that you can figure out the permission area on line number 10, which is set to http://www.google.com. That means it's clear that this extension should be able to run on google.com only. I mean not on the subdomains even. So here's the source code for the popup.html, which is just a simple HTML file that has two buttons. The first one is open, the second one is execute. And it has a popup.js at the end. So here we have the popup.js. So in very brief manner. What it does is as soon as you click on the open button, it loads google.com. And as soon as you click on the execute button, it calls the JavaScript. It alerts document.domain for you. So there are so many APIs available for the browser extensions that you can use like history API and some sort of proxys API, tabs API. But for me this tabs API was so interesting because it allows you to play with different tabs like it has some function, methods inside, like tabs.create. So what it does is it allows you to create a new tab with any arbitrary domain and it also has tabs.update. And what it does is it allows you to update the page with the next URI. And tabs.duplicate is also important because it allows you to make a exact replica of an already open tab. The next method is tabs.executeScript. So this is pretty simple. This allows you to execute JavaScript code and tabs.hide and tabs.reload, which is pretty easy. And there are so many other methods as well. So out of them. The most interesting one for me was create and update and also the duplicate method. So let's say if you want to load a new. So let's say if you want to load bing.com on a new tab using a browser extension so you can just write this five lines of code that calls browser.tabs.create. And then it passes a URL which is https www.google.com. So this is as far as the documentation and this is for the good boys like not for us. So as an evil mind, like I was interested to know, like what would happen if I tried to load local files instead of a normal domain? So then I replaced the bing URL with a particular local file URI to try to figure out like how browser will treat it. Will it open it or not? So so the next moment Edge gives me this nice error. Like, ok, I can't reach this page and you make sure you have got the right web address. That is ms-browser-extension and then the part for the extension and it appends the file URI part in the last. So basically is assumes that this is a relative path and I'm going to add it with the extension path and I'm going to try and I'm going to open it. So since that particular path doesn't exist, it gives us an error. So this is not a thing with the extension as well. But this is in general like any of the browser. They don't allow you to load local files at any cost because this might lead an issue to steal your local systems files so you can see the image and the Edge and Chrome browsers. So here I am trying to load local files using the Javascript. So every time it says okay, we are not allowed to do that because we care about our users and we will protect them. So since we figured out this browser.tabs.create method was not working for us, the next method that I was looking for the update. So I tried the same thing with the update method and somehow it worked for me. So next. Once I figured out, okay, now I can load the local files. Now I want to load the privileged pages because they're also interesting for me. And it was also working fine for me at the moment. So here you can see as well as you click on the open button browser load, say local file for me and also a privilege page on Edge. So I've reported this back to Microsoft, but, and they quickly responded back to me saying we don't support download API. So even if you load the local files, you have no way to steal it. Like, you literally cannot do anything by loading the local files. And we are not going to fix it. So I said, okay, let's do it another way. So the next moment the idea came to my mind is to use the JavaScript URI. A JavaScript URI is something that start with the Javascript protocol. It has a particular syntax like first javascript and then colon and then the Javascript code. Here we have a simple examples like as soon as the a href javascript:alert(1), it gets rendered in the browser and you click on the test, a Javascript code will pop up on your browser. So the good thing about the JavaScript URI is that they execute in the main domains reference unlike the data URIs. So you can look into the image. We have javascript URI and the data URIs as well, that points to alert document.domain. And one Javascript URI says I'm on htmleditor.squarefree.com. While the data URI said the null domain. So basically the data URI was supposed to execute on the main domains reference a couple of years back, but then it creates a lot of mess with the browser. So browser vendors they decided to execute in the null domain reference to just to make it do the safe. So at this point of time I decided, ok Javascript URIs are like the best candidate for us, so why not try it? So I've tried the same Javascript URI with browser.tabs.create and again, it was, it doesn't work for me. But again, we have a friend called dot update method. I tried the same thing with the JavaScript URI that points to browser.tabs.update, which again calls javascript:alert(document.domain). And it worked for me this time. So you can figure it out with this picture. This extension should have able to run on Google dot com. Now we are on a big dot com and if you click on the open button, we have a Javascript code execution on bing.com. This is how bad it was, because that's a total violation of the privacy, because the user believes that this extension shouldn't be able to run on the other domain, except the google.com. So this was again reported to the Microsoft saying, okay. So in the last time I reported like I'm able to load the local files, but you said I'm not going to fix it. And now we have a JavaScript code execution as well. So then again, they said: Okay, like we got your concern. We understand what you're trying to say, but can you also alert users's cookies as well? Like, is it possible to steal the user's cookies? Then I said, okay, why not? So instead of document or domain, you can just use document.cookie to pop up users cookies as well. So. Since we have host access permission bypass on Edge so we can steal Google e-mails, even Facebook data or anything like that. So to demonstrate this attack, let's suppose we have a simple Google E-mail. It says, I'm a secret e-mail and I have some coupon code for thousand dollar cashback. And then there we have some random coupon code. So to demonstrate this attack, you can see I'm using browser.tabs.update that points to a certain Javascript URI and what it does is it fetches the particular e-mail with the particular ID and opens a new tab and send it to the leak.html. And further, what leak.html does is it copies the value from location.hash and write it onto the page. So as soon as you click on the open button, if you are on mail.google.com, it will steal the particular e-mail and display it back on the attackers domain. So this is how I was able to steal the google e-mails. So this proof of concept was sent to the Microsoft and the same thing with the local files as well. Like I thought, okay, now it's working for the domain. Now what if we tried with the same thing with the local files as well? So yeah, in this case it was, it worked as well. So if you remember in the last in the past when we were able to load local files, but Microsoft says, OK, we are not going to fix it because we don't support download API. And now we have a Javascript code execution on local files as well. So we can chain both of these bugs to steal the local files as well. So here's a simple proof of concept. So at first what we are doing is browser.tabs.update that points to a file URI. And again, browser.tabs.update that points to a javascript URI. So Microsoft was like, OK. Now we have to fix. But what is next? So so far we have Javascript code execution on local files. We also have host access permission bypass. Now what is next? So the next thing that came to my mind is always the privilege pages, as I already explained the sensitivity of the privileged pages. So the next moment I was so excited that this will work on the privileged pages as well. So again, I wrote this five line of code and tried to execute in reference to about:flags. And surprisingly, it was not, it wasn't working for me. And I was so surprised, like why this is not working and like shaking my head, like, what is wrong? So the next moment I was trying to figure out what is wrong with this implementation, like why it is not working. Maybe there are some errors in the console. So I try to open the developer console to figure out the possible errors. But you can see there is no such errors at all. So the reason for that is most of the pages like the sensitive pages in the browsers like Chrome, Firefox and even in Edge are protected by the CSP to make sure there shouldn't be any JavaScript code execution. But we cannot see any CSP errors here as well, which was pretty strange for me. So then again, I asked to myself, like, why this black magic is not working on privileged pages. Even when we don't have the CSP error, maybe this time Edge is playing smart. Do we have any other way to load about:flags in Edge? Then the next idea that came to my mind is to use the res protocol. So res protocol is something that is used to fetch some sort of resources from a module. So instead of about:flags, we can call res://edgehtml.dll/flag.htm and the next moment it worked. So... *applause* Mittal: So this way we have now Javascript code execution on privileged pages as well, which is pretty bad. So once you have Javascript code execution on privileged pages, you can enable and disable Adobe Flash Player and there are other methods, other possible options which we have already discussed, can also be possible with the same type, with the same thing. So again, what we need to do is to call browser.tabs.update that points to edgehtml.dll/flags.htm. And again, a file, again some sort of javascript URI to fetch, get element by ID and then click on it. So it will toggle the Adobe Flash Player setting on the Edge. Again, what is next? So this was pretty enough for me. But again, like I was trying to figure out if we can do something else as well. And then I start with the reading mode. So a reading more is a feature implemented in Edge, which renders a page in a way that is like kind of pretty easy to read. So in this process, Edge makes sure that there shouldn't be any Javascript code execution on the page. The main purpose for reading mode is that to provide the users, to provide a simplified page to the users. So basically there should not be any advertisement or something like that. So for that reason, browser vendors, they make sure there shouldn't be any Javascript code execution on reading mode. And there was one bug with the reading mode as well, like you cannot put any document in the reader mode until unless browser identified its compatibility. But you can append the read: protocol in the in the first and then the URL that points to some sort of domain and then Edge will load the particular resources in the reading mode as well. So fortunately, I tried the same attack on the reading mode as well. But since the reading more was protected with their certain CSP and then, so you can see the CSP error. It says we do not allow inline script and it really blocked by the Edge. So reading mode was kind of safe, at least for the test cases, but in some certain test cases it worked for me, but I was not able to I was not able to reproduce it further. So that's why I marked it as safe. The other possible features we can have is the Javascript code execution on other extension pages. Like again, you can imagine a situation: We have... You can imagine a situation when one extension is able to disable another extension in browser, like how bad it will be. So again, now we are on a internal page that belongs to Adblock Plus. And if we tried to run our extension on this page, then again, we have a CSP violation issues. So that was safe. The next thing was some CSP privilege issues because the host permission will not work if there is any CSP error. So next, I tried to figure out if we can use the execute script API to figure out how to deal with the CSP. So let's assume we have a page where the CSP is implemented properly and we have a host permission for the same. So you can see the code where we are saying the content security policy, which is set to default- src self. And we are using browser.tabs.executeScript which this code and then where we have to pass the JavaScript code, which is a simple alert(document.domain). So the way extensions deal with the CSP is that most of the browsers, they will allow Javascript from any extensions until unless they will try to change the DOM tree of particular documents. So let's suppose we have the first example right here. In this case, so as I said, let's assume we are on a page which has a perfect CSP in place like this. And we tried to change the DOM for that particular page. So the possible base we have is either we can use document.write or we can use document.body.innerHTML and then insert the Javascript code. And then the other possible way we have is to generate a random element and then write inside it. So all these ways to manipulate the particular DOM tree on a CSP protected page was not allowed by most of the browsers like Firefox and Chrome, but it was not protected in case of Edge like the executeScript API as straightforward as execute any of the Javascript code on any domain, whether you try to change on, whether you tried to change the DOM on a CSP protected page or not. Like it doesn't matter for it. So to conclude with this presentation is that Edge extensions are still in development. Most of the APIs are not supported till the time because and the Edge that it has moved to the new Chromium based browser as well. So I'm not sure whether there is started developing extensions API or not, but the ActiveTab is one of the interested permission to work on because it allows you to execute Javascript code on the current domain. So if you are able to perform the same sort of the same attack of the tabs API as well. So pretty much you can have all what I presented here as well. So Microsoft, they finally decided to fix this bug in March 19 update with the highest possible bounty they have with the CVE-2019-0678. Now, that's it. Herald: So thank you, Nikhil for an interesting talk. If you have questions about the talk, we have three microphones, one, two and three in each one of the aisles. If you have a question, please come to the microphone. We'll start from microphone number three. Question: Hi. And thank you for the interesting talk. I have one question. Is this back or is this API also relevant for the new, for the new Edge coming in January based on Chromium engine? Mittal: No, I guess. So the APIs are the same, but since the new Edge is running on Chrome so they will not support this API because of they use some others calling conventions, I guess, I believe. Does that answer your question? Q: Yeah. But I have a second one. Herald: Yeah. Go for it. Q: Okay. And the second one is you tried to open the pages via the res Protocol. But the functionality of those pages, is it also handled by Edge while opening it through the res protocol, not about the about protocol? Mittal: Yes, I guess. Q: Okay. They were also working? Mittal: Yeah. Q: Okay. Thank you. Herald: Any more questions from the crowd or from the internet? Okay. Then another round of applause for Nikhil for a great talk. *36c3 outro music*