WEBVTT

00:00.000 --> 00:12.440
And I'm glad to welcome Jan Luca Varisco, who is going to talk about modern security features

00:12.440 --> 00:14.720
for web apps and the Pro Regions.

00:14.720 --> 00:15.720
Thank you very much.

00:15.720 --> 00:16.720
And hi.

00:16.720 --> 00:26.560
So, good afternoon everyone, glad to be here with you, just as a background before we move

00:26.560 --> 00:27.560
forward.

00:27.560 --> 00:28.560
I'm Jan Luca.

00:28.560 --> 00:34.880
I spent the last 20 years, both in the public and private sector, June Sutter, mostly, and

00:34.880 --> 00:40.720
they got interested over the last year's security and everything that actually entails.

00:40.720 --> 00:43.200
How can we make the web better from a security standpoint?

00:43.200 --> 00:45.520
So, happy to be here today with you.

00:45.520 --> 00:49.240
Now, today I'm going to try to answer this question.

00:49.240 --> 00:52.680
Did I know it's what actually keeps everybody awake at night?

00:52.680 --> 00:56.000
That is, how can we actually make the web?

00:56.000 --> 01:00.240
Now, can we fix the web not to be a scary place?

01:00.240 --> 01:06.000
Now, if I actually had to summarize where we are from a security standpoint in a single

01:06.000 --> 01:11.840
slide, but I'll try to go beyond that, is where three main pillars that I like to

01:11.840 --> 01:18.120
call actually the three capital scenes that are fundamentally encryption, injection, and

01:18.160 --> 01:20.360
a fundamental isolation.

01:20.360 --> 01:24.160
When it comes to encryption, of course, and isolation, I'm referring to the lack of

01:24.160 --> 01:30.800
it, if you actually want to shake the hand of whoever is actually sitting next to you,

01:30.800 --> 01:34.240
I think we did a very good job on the encryption side over the last years, so congrats

01:34.240 --> 01:36.040
everyone.

01:36.040 --> 01:41.680
On the injection side, there's still a lot to do in there, but things are getting better.

01:41.680 --> 01:46.440
And on the isolation side, so today the talk is going to be covering both the injection

01:46.480 --> 01:48.480
and the isolation part of it.

01:48.480 --> 01:54.640
Now, when we talk about injection, we start from the simplest of our nightmare, trust

01:54.640 --> 01:58.520
the scripting, and I'm pretty sure you are all familiar with trusted scripting and actually

01:58.520 --> 02:04.200
countless similar approaches and similar patterns that you might have seen when responding

02:04.200 --> 02:10.680
to the incident on your company, working on projects, without a peers, and fundamentally,

02:10.720 --> 02:17.920
we had to always address injections from a standpoint on how can we mitigate multiple

02:17.920 --> 02:19.720
classes of vulnerabilities in there.

02:19.720 --> 02:24.480
So, CRETSESS scripting being our like entry points in there.

02:24.480 --> 02:28.760
Isolation here is pretty interesting also because when you think about isolation, when

02:28.760 --> 02:35.400
you think about how can we fundamentally try to respond to new classes of flows?

02:35.400 --> 02:41.320
We had micro-protectual issues, you might recall spec, meltdown, the subsequent patches

02:41.320 --> 02:46.600
that got applied, how old your Linux kernel and your Linux machines became lower at some

02:46.600 --> 02:51.560
point in time, here are quite old, some additional set of patches, and fundamentally

02:51.560 --> 02:58.240
in here isolation is pretty interesting because we might be talking about same site isolation,

02:58.240 --> 03:01.840
same origin isolation, and several other type of isolation that we're going to be covering

03:01.840 --> 03:04.280
today.

03:04.280 --> 03:10.680
Now, it all actually started, if you make a request to any page of there, you can see an

03:10.680 --> 03:14.600
example in here, we can split the request between three of the areas that I wanted to

03:14.600 --> 03:16.640
cover today.

03:16.640 --> 03:20.840
Content security policy and trusted types that we're going to be covering today, the two

03:20.840 --> 03:26.760
headers you see out there, content security policy with the goal of blocking third-party

03:26.760 --> 03:32.440
app scripts from execution, and the third part of it that is pretty interesting is,

03:32.440 --> 03:39.640
how do we make isolation working to address cross-set three because forgery, access

03:39.640 --> 03:45.040
aside, and several other type of classes of vulnerability is that we might be wanting to

03:45.040 --> 03:50.200
address with fetch metadata headers and some other things that I will be going through

03:50.200 --> 03:51.200
today.

03:51.200 --> 03:56.600
Now, let's go into the isolation mechanism because I think we have a lot to unpack in here.

03:56.600 --> 04:01.800
Now, why do we even bother on isolation isolation is pretty interesting because we might

04:01.800 --> 04:07.840
have isolation when we consider attacking windows, and we will see what windows means,

04:07.840 --> 04:10.920
and when we see attacking on resources.

04:10.920 --> 04:17.800
Now, it's pretty interesting to see how you can do cross-set search and in general, leaking

04:17.800 --> 04:22.840
information from a given tab, from a given window of your browser, and that we want to

04:22.840 --> 04:28.240
address actually with how not to leak information, how not to attack, how actually to

04:28.240 --> 04:35.040
mitigate attacks at the resources level, and so the first things that I want you to start

04:35.040 --> 04:40.600
with is like we said, we might have three scenarios actually to address the same origin

04:40.600 --> 04:46.400
site, the same site in here, and actually the cross-site, same origin as you can imagine

04:46.480 --> 04:52.400
same URL, same path, I mean different paths from the same URL, but the schema is actually

04:52.400 --> 04:53.880
the same.

04:53.880 --> 05:00.680
Same site with potentially the same schema and actually your digital domains, what's interesting

05:00.680 --> 05:04.720
in here that we're going to be also addressing today is actually our cross-site might

05:04.720 --> 05:09.400
come and do, and that we mitigate all of those three, and what that actually does, origin

05:09.400 --> 05:12.440
versus sites, has to be along.

05:12.440 --> 05:17.680
Now, when we consider a relation for resources, there's a very nice things, how many

05:17.680 --> 05:22.960
people of you, I mean how many of you have deployed, for instance, fetch me today the

05:22.960 --> 05:30.040
request headers across your applications, it's a very no one, 1, 2, 3, 4, good, you're

05:30.040 --> 05:31.040
the best.

05:31.040 --> 05:37.400
So what's interesting in here is actually that we always consider ourselves to be in

05:37.400 --> 05:43.760
charge of taking decisions, granting decisions to the request, granting decisions to the

05:43.760 --> 05:49.520
clients, but what if actually we make the server itself, make those security decisions

05:49.520 --> 05:51.160
on our behalf.

05:51.160 --> 05:56.680
What if based on the source, based on the context of each HTTP request, we can consider,

05:56.680 --> 06:03.080
for instance, which website generates the request, for instance, what, record mode, the

06:03.080 --> 06:08.600
note in the type, and also anything with the type of request, and what if we can also

06:08.600 --> 06:13.520
consider the destination in there, what type of data are we talking about, what if we can

06:13.520 --> 06:20.600
instrument each of those requests to perform and behave differently across HTTP requests

06:20.600 --> 06:22.440
that we're going to be considering the site.

06:22.440 --> 06:27.600
Let's have a look at, for instance, this example, where when we call this URL, like this

06:27.600 --> 06:34.800
full JSON, at site.example, we are fundamentally setting three errors, set set site,

06:34.800 --> 06:38.000
set set mode, and actually the destination in there.

06:38.000 --> 06:41.400
Here we're starting to set to allow the same origin.

06:41.400 --> 06:46.000
Here we're starting to consider also our QURS policy, of course, policy, if you're

06:46.000 --> 06:47.000
allowed so.

06:47.000 --> 06:50.440
And then we're also defining what you do with the destination in there.

06:50.440 --> 06:57.240
Now let's consider, for instance, something where we might not want to allow to get through.

06:57.240 --> 07:03.720
We can set the thing with, we can instrument you had there to be behaving in a way that

07:03.720 --> 07:09.680
cross-site, for instance, is actually handled as such, and behaves differently to block

07:09.680 --> 07:13.440
for instance, that either request.

07:13.440 --> 07:17.360
And even request is pretty interesting, because over the last couple of years, we've seen

07:17.360 --> 07:24.480
a lot of C-O-O-P issues called cross-aging opener policy, where, fundamentally, if you

07:24.480 --> 07:32.240
look at the screen here, we fundamentally define an opener, like we open a window, we sense

07:32.240 --> 07:37.840
the messages, we count whatever we want to count, and then we allow the opener itself

07:37.840 --> 07:41.600
to open a new window to any victim website.

07:41.600 --> 07:48.520
And if we're not actually careful with that, we can, interestingly, control windows and

07:48.520 --> 07:50.520
taps with windows opener.

07:50.520 --> 07:54.480
I'm sure if you do a lot of web applications, scanning, a lot of web application security,

07:54.480 --> 07:59.680
you might have seen a lot of the cross-aging opener policy being flagged such.

07:59.680 --> 08:05.240
It's pretty interesting in here, because based on the policy you're going to be setting,

08:05.240 --> 08:09.280
you might be able to call from a given tap that might be a legitimate.

08:09.280 --> 08:13.160
You might be able to redirect that user to evil page.

08:13.160 --> 08:18.280
What you want to make sure there is that with the cross-aging opener policy, you define

08:18.280 --> 08:24.880
what kind of behavior, like same origin, for instance, the opener should be allowing for.

08:24.880 --> 08:29.520
From a given tab, you might be calling another application if and only within the same

08:29.520 --> 08:30.520
origin.

08:30.520 --> 08:38.720
You might not want to allow WWWGoogle.com to have an opener policy allowing you to go to www.donclicment

08:38.720 --> 08:39.720
.com.

08:39.720 --> 08:44.880
Now, what can we also do to do injection defenses?

08:44.880 --> 08:50.160
Trusted types, it's something that actually, as it can imagine in here, we want to solve

08:50.160 --> 08:55.120
several types of process scripting we set, and Dom, process scripting is one of the things

08:55.120 --> 09:04.120
that makes, means behaving the Dom API pretty interesting, because it allows us to fundamentally

09:04.120 --> 09:10.600
use control strings, and we need to make sure that those strings, when converted into code,

09:10.600 --> 09:12.600
are sanitized.

09:12.600 --> 09:17.160
And when you look at the here, for instance, at the given URL, you might be wanting to address

09:17.160 --> 09:21.160
that process scripting in the Dom and handle it as such.

09:21.160 --> 09:23.800
Now, Trusted types is a very good idea.

09:23.800 --> 09:30.240
It's been around for a couple of years, actually several years, to be honest with you.

09:30.320 --> 09:36.600
What's relevant for this is that any HTML string, any script string, any URL, that you might

09:36.600 --> 09:43.140
be triggering, get fundamentally typed into three new types, Trusted HTML, Trusted

09:43.140 --> 09:45.360
Script, and Trusted Script URL.

09:45.360 --> 09:50.760
What you're getting there is that when you force Trusted types, those are fundamentally

09:50.760 --> 09:58.840
sanitized process and handled in a more secure way from a Dom perspective.

09:58.840 --> 10:04.040
So if we want to address any type of process scripting, like a Dom level, we can use Trusted

10:04.040 --> 10:08.840
types to accepting objects in the given way we expect you.

10:08.840 --> 10:13.720
You can set up policies as you can imagine in here where you create validation rules.

10:13.720 --> 10:19.920
You can actually use those policies to create those objects, define as Trusted types.

10:19.920 --> 10:26.400
And then you can enforce that policy setting, the constituency policy had such so that

10:26.400 --> 10:29.240
the Trusted types are kept along.

10:29.240 --> 10:34.480
Now, you might be wondering, how do I get an understanding from a reporting perspective

10:34.480 --> 10:40.400
on whether my rollouts of Trusted types are actually misbehaving my web application.

10:40.400 --> 10:46.580
You can also deploy them with a reporting mode where you get a lot of information from

10:46.580 --> 10:49.480
Trusted types information that we just printed in there.

10:49.480 --> 10:53.920
So you all set in reporting mode, for instance, the constituency policy.

10:53.920 --> 11:00.800
You define a such where you might be requesting Trusted types for a type script, for instance.

11:00.800 --> 11:07.480
And then we might having actually the Dom to accept report findings and strings in here,

11:07.480 --> 11:12.040
but then we want to make sure that we want to accept for instance Trusted types and handle

11:12.040 --> 11:14.920
them as such.

11:14.920 --> 11:21.360
If we need to summarize in here how Trusted types behave, for instance, you have to simplify

11:21.360 --> 11:27.040
security reviews, so you need to dramatically reduce the amount of time spent on code

11:27.040 --> 11:30.160
base and handle that code base as such.

11:30.160 --> 11:35.360
And then you can implement the Trusted types and reporting things as part of your security

11:35.360 --> 11:38.480
validation pipeline that you might have established.

11:38.480 --> 11:47.360
Now, this is all interesting because, fundamentally, we all came back to our best friend

11:47.360 --> 11:49.600
that is content security policies.

11:49.600 --> 11:55.400
And content security policies, let's think about content security policy level free, for instance,

11:55.400 --> 11:58.320
comes actually with a very big challenge.

11:58.320 --> 12:04.280
Now, CSP policies have been around for a while, there are strong defense in that mechanism.

12:04.280 --> 12:10.520
They're not bulletproof as we will see in a while, but they are in did something that

12:10.520 --> 12:13.440
do work against trusted scripting.

12:13.440 --> 12:19.960
And we can control them with scripts, scripts can get executed, plugins can be loaded.

12:19.960 --> 12:25.400
And it's actually not sold in the main problem we're here for, that is, it's keeping

12:25.400 --> 12:27.120
or fixing bugs.

12:27.120 --> 12:33.040
Now, enabling a content security policy is, why do we so scape today?

12:33.040 --> 12:35.280
I'm pretty sure many of you did that.

12:35.280 --> 12:40.520
You can enable that in reporting on remote, you start collecting CSP reports, you start understanding

12:40.520 --> 12:45.920
how your scripts, how all the things and types you're loading, you're actually loading

12:45.920 --> 12:51.160
into application behave, and then you can, of course, enforce it.

12:51.160 --> 12:58.200
Now the problem is that very easily your web application is going to be looking like this.

12:58.200 --> 13:04.320
I'm not a fan of allow lists, and you should be either because fundamentally, it's not

13:04.320 --> 13:05.320
going to work.

13:05.320 --> 13:09.520
Allow list is going to be prone to errors, and allow list is not going to make it in

13:09.520 --> 13:15.320
a way that it's maintainable, as I can see here is the mess, I'm sure you spend a lot

13:15.320 --> 13:21.000
of time into CSP policies that were bigger probably than your web code base, and CSP

13:21.000 --> 13:26.000
policies are fundamentally something we shouldn't be behaving on with an allow list approach.

13:26.000 --> 13:32.080
Now, the allow list approach though, it's actually pretty good at blocking third-party

13:32.080 --> 13:37.880
JavaScript, because fundamentally we're going to be defining whatever we want, and we're

13:37.880 --> 13:41.360
going to be allowing one, two, three, hundred.

13:41.360 --> 13:44.960
But then the problem is that it's not maintainable, as we said, and it's not a strong

13:44.960 --> 13:55.440
mitigation against trusted scripting, because CDN, because common URLs, because many

13:55.440 --> 14:02.560
assets that fundamentally cost several type of resources make things pretty interesting.

14:02.560 --> 14:07.120
And so my advising here, of course, I'm pretty sure you know already, is to fundamentally

14:07.120 --> 14:13.560
not allow the list things and not rely on them for CSP policies.

14:13.560 --> 14:20.520
Now, let's have a look at how to bypass this, I mean, how bypasses are applied over CSP

14:20.520 --> 14:21.520
policies.

14:21.520 --> 14:29.200
If you look at several of this CSP policies that can be bypassed, you will see that it might

14:29.200 --> 14:34.440
be a configuration issue, it might be an allow list problem, like we said, it might also

14:34.440 --> 14:42.160
be that we might be enabling a library that fundamentally brings in a lot of tax

14:42.160 --> 14:49.560
surface, and it might also be things that don't make that allow list approach maintainable

14:49.560 --> 14:50.400
at all.

14:50.400 --> 14:55.520
There's several ways to, and you might have seen also a lot of the bug bounces out there

14:55.520 --> 14:57.880
by passing a lot of the CSP policies in there.

14:57.880 --> 15:00.360
So there's a solution for that.

15:00.360 --> 15:06.480
There's a solution for that that is fundamentally what if, instead of handling something

15:06.480 --> 15:12.040
that the attacker also can predict, we use actually Nons, and we use Nons that are fundamentally

15:12.040 --> 15:17.920
generated by something that is like a random number, random ideas, and the likes, and

15:17.920 --> 15:24.400
the attacker itself, it's not going to be able to inject that ID on their side.

15:24.400 --> 15:29.560
It's not going to be able to, I mean, when you, when you actually enforce the Nons part

15:29.560 --> 15:36.240
of it, the attacker is not going to be able to inject that and hence, inject the script without

15:36.240 --> 15:39.240
the Nons will be fundamentally blocked in the browser.

15:39.240 --> 15:42.780
So even if you get an injection without a proper Nons that is set on the server side

15:42.820 --> 15:48.020
or the application side, you can see in here that you will not be able to execute that.

15:48.020 --> 15:53.580
And that's where I actually, not only the proof, but way better than it used to be before.

15:53.580 --> 15:59.380
Now, the problem with that is that, from a maintenance perspective, actually, you might

15:59.380 --> 16:04.420
have to do a lot of refactoring, and a lot of third-party is created, widgets, and the likes,

16:04.420 --> 16:09.340
you might see a lot of violations into your report.

16:09.340 --> 16:15.220
And so it has to be done with actually this kind of BDT and maintenance of BDT mind,

16:15.220 --> 16:18.660
and it's not quite straightforward out there.

16:18.660 --> 16:22.460
So we can go the extra mile, and we can do strict dynamic interferes.

16:22.460 --> 16:27.860
So script acts, we might be wanting to cover on these scripts, and we might be wanting to

16:27.860 --> 16:33.860
make sure that on these script acts in response body are actually needing the Nons attribute.

16:33.860 --> 16:38.060
Not all scripts, not all the includes that we do in there.

16:38.060 --> 16:42.700
So third-party scripts are validated, and also the potentially larger refactoring it's

16:42.700 --> 16:47.940
taken care of.

16:47.940 --> 16:50.980
Now, how do I deploy this?

16:50.980 --> 16:53.660
First of all, you don't want to actually break your stuff.

16:53.660 --> 16:56.980
So you remove all the CSV blockers that you might have.

16:56.980 --> 17:03.740
You actually start heading, as we said, the script acts across your CSV Nons' into the

17:03.740 --> 17:05.580
script acts, and you start there.

17:05.580 --> 17:10.900
You can also do the CSV policy reporting mode, so before turning and sleeping the

17:10.900 --> 17:16.620
kind on your production application, you start actually light with a fundamentally enforcing

17:16.620 --> 17:18.620
it in reporting on the mode.

17:18.620 --> 17:24.460
I need to go a bit faster, because we're getting over time.

17:24.460 --> 17:25.980
So I'm going to skip a bit of this.

17:25.980 --> 17:31.660
I'm going to give you the back, but fundamentally the way this works, removing actually the

17:31.660 --> 17:39.340
CSV blockers, is if we do it in a strong way, like inline events, like this one,

17:39.340 --> 17:43.140
I'm going to be becoming, as you can see, the refactoring here, we're going to be covering

17:43.140 --> 17:45.260
at the way we load.

17:45.260 --> 17:51.220
We do the list load of JavaScript calls, or any type of script request that's fundamentally

17:51.220 --> 17:56.540
collapsing external URLs, external scripts, or execute codes in there.

17:56.540 --> 18:01.820
And when we set it up, we can see how we can have a strong, stronger, it sounds like a

18:01.820 --> 18:08.540
buff punk song, but we can add actually a very interesting approach into, we set a CSV

18:08.540 --> 18:14.100
policy that has strict dynamic, but allows unsafe evil.

18:14.100 --> 18:18.940
We go for strict dynamic that it is, and then we even remove strict dynamic to the

18:18.940 --> 18:19.940
strongest one.

18:19.940 --> 18:24.660
But to do that, we need to have a migration path towards actually the CSV policy.

18:24.660 --> 18:30.060
And so my advice in here is that side would report in mode and get it from there.

18:30.060 --> 18:35.020
And now what's making things even more interesting is that you can use CSV ashes for

18:35.020 --> 18:41.580
static HTML, so if you're any of parts of your site use static HTML, you can actually

18:41.580 --> 18:46.780
use those ashes for the, again, in here, you need to compute and you need to account

18:46.780 --> 18:53.420
for the tags in a way that is capable and probably bring, broadly, from your CICD pipeline

18:53.420 --> 18:54.420
in there.

18:54.420 --> 19:00.380
Now, I want to complete the session today with something that is launching at the end

19:00.380 --> 19:02.660
of the month.

19:02.660 --> 19:07.740
When I first announced that I was making this talk, everybody from OZL and reached

19:07.740 --> 19:12.260
out to me and said, hey, you need to, you actually need to make sure that you mention

19:12.300 --> 19:15.580
the sanitizer API, it's coming live this month.

19:15.580 --> 19:19.980
And it's saying sanitizer API is pretty cool to be honest with you.

19:19.980 --> 19:25.620
Scentizer API is fundamentally taking the pain away from you in regards to taking strings

19:25.620 --> 19:33.340
of HTML, for instance, in fields throughout unwanted elements, stripping things, sanitizing

19:33.340 --> 19:39.740
each timeline to days and all the likes, and this API, it's actually shipping at the end

19:39.740 --> 19:44.300
of the month, it's already available in Mozilla nightly, it's available in Chrome, where

19:44.300 --> 19:48.660
the experimental web feature is enabled, and as you can see in the spreadsheet in here,

19:48.660 --> 19:53.700
all you have to do on the left side is actually what makes things on the right side to

19:53.700 --> 19:55.100
be mitigated.

19:55.100 --> 20:00.220
The typical traditional simplest cross-scripting that you see on the right side, it's

20:00.220 --> 20:05.500
fundamentally mitigated by, for the first time also, we have a very simple method that is

20:05.500 --> 20:11.980
at HTML, there should be quite straightforward to set, and it allows that for sanitizing

20:11.980 --> 20:20.380
that when you develop, when you make things much simpler in a much secure way to sanitize

20:20.380 --> 20:25.860
using that sanitize API, you can make things in a way that, for instance, all the unwanted

20:25.860 --> 20:31.020
HTML entities, stripping characters, stripping tags, and the likes can be handled very

20:31.020 --> 20:32.660
simple from there.

20:32.660 --> 20:38.980
If you have a custom policy, you can also use the sanitizer API and pass sanitizer content

20:38.980 --> 20:43.740
to work it in a way that you can be much more flexible than the traditional normal behavior

20:43.740 --> 20:44.740
that you're going to be having.

20:44.740 --> 20:48.180
I want to thank you, and I wish you a good day.

