And I'm glad to welcome Jan Luca Varisco, who is going to talk about modern security features
for web apps and the Pro Regions.
Thank you very much.
And hi.
So, good afternoon everyone, glad to be here with you, just as a background before we move
forward.
I'm Jan Luca.
I spent the last 20 years, both in the public and private sector, June Sutter, mostly, and
they got interested over the last year's security and everything that actually entails.
How can we make the web better from a security standpoint?
So, happy to be here today with you.
Now, today I'm going to try to answer this question.
Did I know it's what actually keeps everybody awake at night?
That is, how can we actually make the web?
Now, can we fix the web not to be a scary place?
Now, if I actually had to summarize where we are from a security standpoint in a single
slide, but I'll try to go beyond that, is where three main pillars that I like to
call actually the three capital scenes that are fundamentally encryption, injection, and
a fundamental isolation.
When it comes to encryption, of course, and isolation, I'm referring to the lack of
it, if you actually want to shake the hand of whoever is actually sitting next to you,
I think we did a very good job on the encryption side over the last years, so congrats
everyone.
On the injection side, there's still a lot to do in there, but things are getting better.
And on the isolation side, so today the talk is going to be covering both the injection
and the isolation part of it.
Now, when we talk about injection, we start from the simplest of our nightmare, trust
the scripting, and I'm pretty sure you are all familiar with trusted scripting and actually
countless similar approaches and similar patterns that you might have seen when responding
to the incident on your company, working on projects, without a peers, and fundamentally,
we had to always address injections from a standpoint on how can we mitigate multiple
classes of vulnerabilities in there.
So, CRETSESS scripting being our like entry points in there.
Isolation here is pretty interesting also because when you think about isolation, when
you think about how can we fundamentally try to respond to new classes of flows?
We had micro-protectual issues, you might recall spec, meltdown, the subsequent patches
that got applied, how old your Linux kernel and your Linux machines became lower at some
point in time, here are quite old, some additional set of patches, and fundamentally
in here isolation is pretty interesting because we might be talking about same site isolation,
same origin isolation, and several other type of isolation that we're going to be covering
today.
Now, it all actually started, if you make a request to any page of there, you can see an
example in here, we can split the request between three of the areas that I wanted to
cover today.
Content security policy and trusted types that we're going to be covering today, the two
headers you see out there, content security policy with the goal of blocking third-party
app scripts from execution, and the third part of it that is pretty interesting is,
how do we make isolation working to address cross-set three because forgery, access
aside, and several other type of classes of vulnerability is that we might be wanting to
address with fetch metadata headers and some other things that I will be going through
today.
Now, let's go into the isolation mechanism because I think we have a lot to unpack in here.
Now, why do we even bother on isolation isolation is pretty interesting because we might
have isolation when we consider attacking windows, and we will see what windows means,
and when we see attacking on resources.
Now, it's pretty interesting to see how you can do cross-set search and in general, leaking
information from a given tab, from a given window of your browser, and that we want to
address actually with how not to leak information, how not to attack, how actually to
mitigate attacks at the resources level, and so the first things that I want you to start
with is like we said, we might have three scenarios actually to address the same origin
site, the same site in here, and actually the cross-site, same origin as you can imagine
same URL, same path, I mean different paths from the same URL, but the schema is actually
the same.
Same site with potentially the same schema and actually your digital domains, what's interesting
in here that we're going to be also addressing today is actually our cross-site might
come and do, and that we mitigate all of those three, and what that actually does, origin
versus sites, has to be along.
Now, when we consider a relation for resources, there's a very nice things, how many
people of you, I mean how many of you have deployed, for instance, fetch me today the
request headers across your applications, it's a very no one, 1, 2, 3, 4, good, you're
the best.
So what's interesting in here is actually that we always consider ourselves to be in
charge of taking decisions, granting decisions to the request, granting decisions to the
clients, but what if actually we make the server itself, make those security decisions
on our behalf.
What if based on the source, based on the context of each HTTP request, we can consider,
for instance, which website generates the request, for instance, what, record mode, the
note in the type, and also anything with the type of request, and what if we can also
consider the destination in there, what type of data are we talking about, what if we can
instrument each of those requests to perform and behave differently across HTTP requests
that we're going to be considering the site.
Let's have a look at, for instance, this example, where when we call this URL, like this
full JSON, at site.example, we are fundamentally setting three errors, set set site,
set set mode, and actually the destination in there.
Here we're starting to set to allow the same origin.
Here we're starting to consider also our QURS policy, of course, policy, if you're
allowed so.
And then we're also defining what you do with the destination in there.
Now let's consider, for instance, something where we might not want to allow to get through.
We can set the thing with, we can instrument you had there to be behaving in a way that
cross-site, for instance, is actually handled as such, and behaves differently to block
for instance, that either request.
And even request is pretty interesting, because over the last couple of years, we've seen
a lot of C-O-O-P issues called cross-aging opener policy, where, fundamentally, if you
look at the screen here, we fundamentally define an opener, like we open a window, we sense
the messages, we count whatever we want to count, and then we allow the opener itself
to open a new window to any victim website.
And if we're not actually careful with that, we can, interestingly, control windows and
taps with windows opener.
I'm sure if you do a lot of web applications, scanning, a lot of web application security,
you might have seen a lot of the cross-aging opener policy being flagged such.
It's pretty interesting in here, because based on the policy you're going to be setting,
you might be able to call from a given tap that might be a legitimate.
You might be able to redirect that user to evil page.
What you want to make sure there is that with the cross-aging opener policy, you define
what kind of behavior, like same origin, for instance, the opener should be allowing for.
From a given tab, you might be calling another application if and only within the same
origin.
You might not want to allow WWWGoogle.com to have an opener policy allowing you to go to www.donclicment
.com.
Now, what can we also do to do injection defenses?
Trusted types, it's something that actually, as it can imagine in here, we want to solve
several types of process scripting we set, and Dom, process scripting is one of the things
that makes, means behaving the Dom API pretty interesting, because it allows us to fundamentally
use control strings, and we need to make sure that those strings, when converted into code,
are sanitized.
And when you look at the here, for instance, at the given URL, you might be wanting to address
that process scripting in the Dom and handle it as such.
Now, Trusted types is a very good idea.
It's been around for a couple of years, actually several years, to be honest with you.
What's relevant for this is that any HTML string, any script string, any URL, that you might
be triggering, get fundamentally typed into three new types, Trusted HTML, Trusted
Script, and Trusted Script URL.
What you're getting there is that when you force Trusted types, those are fundamentally
sanitized process and handled in a more secure way from a Dom perspective.
So if we want to address any type of process scripting, like a Dom level, we can use Trusted
types to accepting objects in the given way we expect you.
You can set up policies as you can imagine in here where you create validation rules.
You can actually use those policies to create those objects, define as Trusted types.
And then you can enforce that policy setting, the constituency policy had such so that
the Trusted types are kept along.
Now, you might be wondering, how do I get an understanding from a reporting perspective
on whether my rollouts of Trusted types are actually misbehaving my web application.
You can also deploy them with a reporting mode where you get a lot of information from
Trusted types information that we just printed in there.
So you all set in reporting mode, for instance, the constituency policy.
You define a such where you might be requesting Trusted types for a type script, for instance.
And then we might having actually the Dom to accept report findings and strings in here,
but then we want to make sure that we want to accept for instance Trusted types and handle
them as such.
If we need to summarize in here how Trusted types behave, for instance, you have to simplify
security reviews, so you need to dramatically reduce the amount of time spent on code
base and handle that code base as such.
And then you can implement the Trusted types and reporting things as part of your security
validation pipeline that you might have established.
Now, this is all interesting because, fundamentally, we all came back to our best friend
that is content security policies.
And content security policies, let's think about content security policy level free, for instance,
comes actually with a very big challenge.
Now, CSP policies have been around for a while, there are strong defense in that mechanism.
They're not bulletproof as we will see in a while, but they are in did something that
do work against trusted scripting.
And we can control them with scripts, scripts can get executed, plugins can be loaded.
And it's actually not sold in the main problem we're here for, that is, it's keeping
or fixing bugs.
Now, enabling a content security policy is, why do we so scape today?
I'm pretty sure many of you did that.
You can enable that in reporting on remote, you start collecting CSP reports, you start understanding
how your scripts, how all the things and types you're loading, you're actually loading
into application behave, and then you can, of course, enforce it.
Now the problem is that very easily your web application is going to be looking like this.
I'm not a fan of allow lists, and you should be either because fundamentally, it's not
going to work.
Allow list is going to be prone to errors, and allow list is not going to make it in
a way that it's maintainable, as I can see here is the mess, I'm sure you spend a lot
of time into CSP policies that were bigger probably than your web code base, and CSP
policies are fundamentally something we shouldn't be behaving on with an allow list approach.
Now, the allow list approach though, it's actually pretty good at blocking third-party
JavaScript, because fundamentally we're going to be defining whatever we want, and we're
going to be allowing one, two, three, hundred.
But then the problem is that it's not maintainable, as we said, and it's not a strong
mitigation against trusted scripting, because CDN, because common URLs, because many
assets that fundamentally cost several type of resources make things pretty interesting.
And so my advising here, of course, I'm pretty sure you know already, is to fundamentally
not allow the list things and not rely on them for CSP policies.
Now, let's have a look at how to bypass this, I mean, how bypasses are applied over CSP
policies.
If you look at several of this CSP policies that can be bypassed, you will see that it might
be a configuration issue, it might be an allow list problem, like we said, it might also
be that we might be enabling a library that fundamentally brings in a lot of tax
surface, and it might also be things that don't make that allow list approach maintainable
at all.
There's several ways to, and you might have seen also a lot of the bug bounces out there
by passing a lot of the CSP policies in there.
So there's a solution for that.
There's a solution for that that is fundamentally what if, instead of handling something
that the attacker also can predict, we use actually Nons, and we use Nons that are fundamentally
generated by something that is like a random number, random ideas, and the likes, and
the attacker itself, it's not going to be able to inject that ID on their side.
It's not going to be able to, I mean, when you, when you actually enforce the Nons part
of it, the attacker is not going to be able to inject that and hence, inject the script without
the Nons will be fundamentally blocked in the browser.
So even if you get an injection without a proper Nons that is set on the server side
or the application side, you can see in here that you will not be able to execute that.
And that's where I actually, not only the proof, but way better than it used to be before.
Now, the problem with that is that, from a maintenance perspective, actually, you might
have to do a lot of refactoring, and a lot of third-party is created, widgets, and the likes,
you might see a lot of violations into your report.
And so it has to be done with actually this kind of BDT and maintenance of BDT mind,
and it's not quite straightforward out there.
So we can go the extra mile, and we can do strict dynamic interferes.
So script acts, we might be wanting to cover on these scripts, and we might be wanting to
make sure that on these script acts in response body are actually needing the Nons attribute.
Not all scripts, not all the includes that we do in there.
So third-party scripts are validated, and also the potentially larger refactoring it's
taken care of.
Now, how do I deploy this?
First of all, you don't want to actually break your stuff.
So you remove all the CSV blockers that you might have.
You actually start heading, as we said, the script acts across your CSV Nons' into the
script acts, and you start there.
You can also do the CSV policy reporting mode, so before turning and sleeping the
kind on your production application, you start actually light with a fundamentally enforcing
it in reporting on the mode.
I need to go a bit faster, because we're getting over time.
So I'm going to skip a bit of this.
I'm going to give you the back, but fundamentally the way this works, removing actually the
CSV blockers, is if we do it in a strong way, like inline events, like this one,
I'm going to be becoming, as you can see, the refactoring here, we're going to be covering
at the way we load.
We do the list load of JavaScript calls, or any type of script request that's fundamentally
collapsing external URLs, external scripts, or execute codes in there.
And when we set it up, we can see how we can have a strong, stronger, it sounds like a
buff punk song, but we can add actually a very interesting approach into, we set a CSV
policy that has strict dynamic, but allows unsafe evil.
We go for strict dynamic that it is, and then we even remove strict dynamic to the
strongest one.
But to do that, we need to have a migration path towards actually the CSV policy.
And so my advice in here is that side would report in mode and get it from there.
And now what's making things even more interesting is that you can use CSV ashes for
static HTML, so if you're any of parts of your site use static HTML, you can actually
use those ashes for the, again, in here, you need to compute and you need to account
for the tags in a way that is capable and probably bring, broadly, from your CICD pipeline
in there.
Now, I want to complete the session today with something that is launching at the end
of the month.
When I first announced that I was making this talk, everybody from OZL and reached
out to me and said, hey, you need to, you actually need to make sure that you mention
the sanitizer API, it's coming live this month.
And it's saying sanitizer API is pretty cool to be honest with you.
Scentizer API is fundamentally taking the pain away from you in regards to taking strings
of HTML, for instance, in fields throughout unwanted elements, stripping things, sanitizing
each timeline to days and all the likes, and this API, it's actually shipping at the end
of the month, it's already available in Mozilla nightly, it's available in Chrome, where
the experimental web feature is enabled, and as you can see in the spreadsheet in here,
all you have to do on the left side is actually what makes things on the right side to
be mitigated.
The typical traditional simplest cross-scripting that you see on the right side, it's
fundamentally mitigated by, for the first time also, we have a very simple method that is
at HTML, there should be quite straightforward to set, and it allows that for sanitizing
that when you develop, when you make things much simpler in a much secure way to sanitize
using that sanitize API, you can make things in a way that, for instance, all the unwanted
HTML entities, stripping characters, stripping tags, and the likes can be handled very
simple from there.
If you have a custom policy, you can also use the sanitizer API and pass sanitizer content
to work it in a way that you can be much more flexible than the traditional normal behavior
that you're going to be having.
I want to thank you, and I wish you a good day.