*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*