This subtitle is not finished yet. If you are able to, please support us and watch the talk in amara for the last changes: https://c3subtitles.de/talk/1297 Thanks!
*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*
Subtitles created by many many volunteers and the c3subtitles.de team. Join us, and help us!