 He's a security consultant at Payatoo 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. So, welcome to the talk, Breaking Microsoft Edge Extension Security Policies. My name is Nikhil. I work at Payatoo Labs, and I'm into web and browser vulnerability research. So, to start with this presentation, I would like to know how many of you use browser extensions in general? Like, oh, nice, so many hands. Okay, so a browser extension is something that extends the functionality of a web browser. We have typical examples, like at Block Plus, which I think most of the people use is 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 whatnot. 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's 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? Oh, nice. So, if you look at these settings, here we have a couple of permissions, which I've listed down on the next slide. So, a 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, how browsers recognize these permissions? Like, 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's a permission model in browser extensions. So, under the source of every extension, we have a file called as manifest.json, and inside a manifest.json file, we have a permission array. So, here's a quick example of a permission array, where we have some permissions. So, the first one is scdps www.google.com, which we'll see right after this slide. The next permission we have is bookmark, and cookies, history, storage, and tabs. So, let's suppose an extension has a permissions with the bookmark and cookies. So, that means that extension can handle your bookmarks, it can manipulate them, it can edit them, it can remove them, and whatnot. 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, a host access permission is something that defines on which certain domains your browser extensions should be able to run. So, in this case, let's suppose we have assigned permissions to scdps www.google.com. So, that means this extension should be 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 by 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 scdps strict.google.com. So, basically this also covers the subdomains as well. And the third possible permission we can have is astrick colon slash slash astrick.google.com. So, basically this says now not only I'll work on Google.com but basically on all the protocols as well, which is scdps might be FTP, that belongs to the particular domain. So, apart from these three permissions, we have the another permission in the row, which is all underscore URLs. This permission is so special because once a browser extension is assigned to all URL, all underscore URL permissions that can execute JavaScript code on every domain that you visit. So, let's suppose you are on Google.com or maybe you are on Bing.com or anything else, it will work on most probably on every domain. But there are few restrictions with the all underscore URLs permissions, that is it cannot run on privileged pages. So, a privileged pages in browser is something that contains some sort of sensitive settings and your browser data. So, you might hear it off Chrome slash settings, which contains the password manager for Chrome and also you can identify the credit card and debit card information on Chrome slash settings as well. So, you can imagine a situation once extension is able to run a JavaScript code on Chrome settings page, then it can probably read or it can steal all of your passwords and credit and debit card informations as well. So, on the edge, we have a similar page, which is about dot flags. So, here you can see once extension with all underscore URL permission is assigned, it can read and change container on website you visit as per the edge. So, has a quick snap of about dot flags and edge so if you look at the first part, you will figure out there are few important permissions like you can enable Adobe Flash Player, you can also enable developer features and also you can enable and disable allow undistricted 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 the sensitivity of this page contains, okay. So, let's quickly build the extensions 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.stml. So, popup.stml 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 popup appears on your window for that contains some sort of functions. That is nothing but just a popup.stml file. And then again, we have a popup.js which has all the JavaScript code that executes according to the extensions chosen by the popup.stml. So, this is how our extension should have looked on the edge. So, you have seen a tiny Microsoft logo and as soon as you click on it, a popup will appear which says I'm 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 one for you. So, basically the interface is written in popup.stml and again, as soon as you click on execute and 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 permissions, permission array, online number 10, which is set to sttp colon slash slash 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 a source code for the popup.stml which is just a simple stml file that has two buttons. The first one is open, the second one is execute and it has a popup.js in 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 a JavaScript, it alerts documented 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 proxies 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.deplicate is also important because it allows you to make an exact replica of a already opened tab. The next method is tabs.execute.script. So, this is pretty simple. This is allowed you to execute JavaScript code and tabs.hide and tabs.relate, which is pretty easy. So, and there are so many other methods as well. So, out of them the most interesting one for me was create an update and also the duplicate method. So, let's see if you want to load a new... So, let's see 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 says that calls browser.tabs.create and then it passes a URL which is stdpsww.google.com. So, this is as per the documentation and this is for the good boys like not for us. So, as an evil mind like I was interesting to know like what would happen if I try to load local files instead of a normal domain. So, then I replace 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, the next moment edge gives me this nice error like okay, 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 path for the extension and it depends the file you are a path in the last. So, basically it 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 part, that particular part 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 browsers, 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'm 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 are 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 loads a local file for me and also a privileged page on edge. So, I've reported this bug to Microsoft but 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 AHRF JavaScript colon alert one, 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 executes in the main domain's reference unlike the data URIs. So, you can look in the image, we have JavaScript URI and the data URIs as well that points to alert, documented domain and one JavaScript URI says, I'm on html.squaredfree.com while the data URIs say the null domain. So, basically the data URIs was supposed to execute on the main domain's reference a couple of years back but then it creates a lot of mass with the browser. So, browser vendors, they decided to execute and the null domain reference too, just to make it too safe. So, at this point of time, I decided, okay, JavaScript URIs are like the best candidate for us, so why not to try it? So, I've tried the same JavaScript URI with browser.tabs.create and again, it doesn't work for me but again, we have a friend or called update method and I've tried the same thing with the JavaScript URI that points to browser.tabs.update which again calls JavaScript call and alert, documented domain and it worked for me this time. So, you can figure out with this picture, this extension should have able to run on google.com and now we are on a bing.com and if you click on the open button, we have a JavaScript code execution on bing.com. Like, this is how bad it was because that's a total violation of the privacy because the user believes that this extension shouldn't able to run on the other domain expect 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 understood what you're trying to say but can you also alert users 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 or cookie to pop up the user's cookies as well. So, since we have host access permission bypass on edge, so we can steal google emails, even Facebook data or anything like that. So, to demonstrate this attack, let's suppose we have a simple google email which says I'm a secret email and I have some coupon code for $1000 cash back and 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 email with a particular ID and opens a new tab and send it to the leak.stml and further, what leak.stml does is it copies the value from location.hash and write it on to the page. So, as soon as you click on the open button if you are on mail.google.com, it will steal the particular email and displayed back on the attackers domain. So, this is how I was able to steal the google emails. 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 same thing with the local files as well? So, yeah, in this case 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, okay, 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, that's a simple proof of concept. So, at the first, what we are doing is browser.times.update that points to a file URI and again browser.times.update that points to a JavaScript URI. So, Microsoft was like, okay, 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 by pass. Now, what is next? So, the next thing that came to my mind is always the privileged 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.flex. And surprisingly, 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 tried 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 on the edge are protected with 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. Or do we have any other way to load about dot 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 certain of resources from a module. So, instead of about dot flags, we can call res colon slash slash edges tml.dll slash flag dot stm. And the next moment, it worked. 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 adder of flesh player. And there are other method which we have other possible options which we have already discussed can also be possible with the same thing. So, again what we need to do is to call browser.tibes.update that points to ishtml.dll slash flags dot stm. And again, again some sort of JavaScript URI to fetch get element by ID and then click on it. So, it will toggle the adder of flesh 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 stuck with the reading mode. So, a reading mode 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 age 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 it, identify it, it's a complicity. But you can append the read colon protocol in the first and then the URL that points to some certain of domain and then age will load the particular resources in the reading mode as well. So, fortunately, I've tried the same attack on the reading mode as well, but since the reading mode was protected with a certain CSP and then, so you can see the CSP error which says we do not allow inline script and it will be blocked by the age. 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 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 try to run our extension on this page, then again we have a CSP violation issues. So, yeah, 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 try to figure out if we can use the execute script API to figure out how they 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.tab.executive script which says code and then where we have to pass the JavaScript code which is a simple alert document or 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 document. 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 perfectly CSP in place like this and we try to change the DOM for the particular page. So, the possible base we have is either we can use document.write or we can use document.body.innerSTML and then sort in JavaScript code and then another possible way we have is to generate a random element and then write inside it. So, all these ways to manipulate a 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 execute script API is straightforward as execute any of the JavaScript code on any domain whether you try 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 in the Edge it has moved to the new Chromium-based browser as well so I'm not sure whether they are still 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 some sort of the same attack with ActiveTab 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 CV 2019 0678. Yeah, that's it. 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 up to the microphone. We'll start from microphone number three. Hi, and thank you for the interesting talk. I have one question, is this bug or is this API also relevant for the new Edge coming in January based on Chromium Engine? No, I guess. So, the APIs are 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. Is that answer your question? Yeah, but I have a second one. Yeah, go for it. Okay, 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? Yes, I guess. Okay, we are also working. Yeah. Okay, thank you. Any more questions from the crowd or from the internet? Okay, then another round of applause for Nikhil for a great talk. Thank you.