Transcript
[ Music ]
[ Applause ]
>> Hello everyone.
My name is John Wilander.
I am an engineer on the Safari
and WebKit team and I'm here to
present to you today how to
secure web content.
Or, as I like to call it, take
the Swede's advice.
So, you might be asking
yourself, web content, that's a
pretty broad term.
Is this session really for me?
Yes, it is for you.
To start off, apps use tons of
web content.
It may be used for ads, login
flows, splash screens.
You might be using Safari View
Controller to-- for parts of
your app.
You might have whole parts of
your UI rendered in a web view.
You might also have companion
web apps that are supposed to be
rendered in a web browser and
that are sharing content or
providing a joint experience
across apps and web apps.
So, really, yes, the session is
for you.
And security is important.
You want to stay in business?
You want to provide the best
customer experience.
You want to be ahead of your
competition.
You want to get this right so
that when they don't they are
the ones to fall, you stay in
the market.
OK. What are we going to cover
today?
We're going to have a look at
first securing your transports.
This is just a brief mentioning
from me about basics that we
need to do before we do the
rest.
If you don't secure your
transports, most other bets are
off.
Then we'll go into a look at
cross-origin lockdown.
This is basically me showing you
a bunch of technologies that are
available to you in WebKit and
in browser engines across the
line that can help you get into
more secure defaults for your
web content.
We would like to opt in for you,
but we can't test your sites for
you or your web content for you,
so we need you to opt in.
And then, as a motivation, if
you feel, well, why should I
care about these security
mechanisms, I'll actually show
you some attack scenarios and
map them back to the security
technologies so that you
understand where they come into
play and how they can defend
your web content.
So, let's head right in to
securing your transports.
This one should be familiar to
you.
So, this is about moving to
HTTPS and WSS.
WSS is for web sockets.
Now, just the fact that HTTP and
WS, the plain text equivalents,
still exist is not an excuse to
keep using them.
You need to move to secure
transports because that's what's
going to ensure that the content
that you are rendering in a
browser or in your app comes
from the server you expect it to
come from and no one has fiddled
around with the content in
transport.
So, moving to HTTPS for your
main content.
There are a couple of
technologies that can help you
get there.
First on your to-do list--
except for just moving to HTTPS
in general-- is strict transport
security or HSTS.
This is an HTTP response header
you can send to the rendering
engine, such as WebKit, and tell
it, hey, my domain should always
be loaded over HTTPS.
If there's ever an HTTP request
from me, just automatically
upgrade it for me to HTTPS.
Never making plain text
connections to my server,
please.
And this is also a thing you can
tell the rendering engine for
how long it should remember
this.
So, typically at least half a
year ahead in time.
Now, you might also be loading
content off of other servers,
servers that are not under your
control, not your domain name.
There's also a header you can
send to the browser engine
called upgrade insecure
requests, also an HTTP response
header, which tells the browser,
hey, go ahead and upgrade all
those other links to content
too, even if it's not from my
server and even if they have not
set strict transport security.
So, those two things that will
automatically upgrade to secure
transports.
Another thing you need to do is
make sure that you mark your
cookies secure.
This is an attribute you add in
your set cookie header,
semi-colon secure.
This means that you're telling
the network stack this cookie
should only ever be sent over a
secure transport.
If there for some reason is a
plain text request for my server
or to my server, don't send the
cookie.
And, since you should be using
secure transports, all of your
cookies should be marked secure.
Final-- finally on your to-do
list here for secure transports
is specific for apps.
You might have heard about app
transport security or ATS.
It is the default behavior for
iOS apps, meaning that they
should be using only secure
transports for network traffic.
Now, there is an opt out you can
have in your info p list to say,
hey, you know, for web content,
I'd still like to do insecure
requests.
Don't do that.
You should be saying no in this
info p list and specifically for
arbitrary web content loads.
OK. Now we've secured the
transport.
Let's move on.
We're now going to look at
cross-origin lockdown.
The reason why I call it
lockdown is this is really you
opting into saner, safer, more
secure defaults for your web
content.
We're locking it down to more or
less what it should have been
all along and then you open up
the specific things you want to
do.
So, let's move in and look at
what are cross-origin loads
anyway.
What are we going to lock down?
Well, web technologies have this
powerful feature where you can
weave together content from
different servers and different
origins.
Different domain names, if you
so will.
An example of this is images.
You can load images from any
server on the web into your web
content and that's a
cross-origin load.
You can also load scripts from
other servers.
Interestingly, those scripts
actually execute with the same
powers and privileges as your
own scripts, so you need to be
really careful what scripts you
load off of other servers.
They more or less own your web
content.
They are executing with the same
powers as you.
And, as a third example,
iframes.
You can embed full pages from
other servers.
Cross-origin, meaning from a
different domain name.
These are three examples of
cross-origin loads.
Now, we've had a security
mechanisms-- security mechanism
on the web for over 20 years
that has provided basic
protection for these
cross-origin loads and it's
called the same-origin policy.
And it differentiates-- here
you've got these examples with
real domain names.
So, you've got the example for
loading the image, you've got a
CDN where you loaded the script,
and you may have a social
widget, an iframe, coming from
social.example here.
And, just to mention, when I say
.example it's just me being sure
that I'm not talking about real
websites here.
If it's easier for you, you can
think of it as .com or .org.
Anyway, these are the
cross-origin loads and the
same-origin policy keeps track
of where did I load this image
from or where did I load this
script from, where did I load
this iframe from, so that it can
provide basic protection.
That basic protection means that
your page in this example cannot
reach into that iframe from
social.example and read its
bytes, read its contents, or
write to its contents.
The same-origin policy is
guarding, saying this part of
the page actually came from a
different server, you're not
allowed to just go straight in
there and change things or read
what the user happened to enter
into that form, for instance.
An easier way to think of the
same-origin policy is just
matching two pages, two tabs in
a browser.
One tab shouldn't be able to
just go into another tab and see
what the user's doing over
there.
It's the same-origin policy
effectively doing its job there
too.
So, the lockdown.
How do we lock this down
properly?
We've got the same-origin
policy, but it's not good
enough.
So, you need to opt in to some
more defaults.
Starting out with subresource
integrity-- I'll go through them
and I'll mention them here.
This is just a simple change in
the markup for your script tags.
The second part is content
security policy.
This is providing a full-on
security policy for your whole
page where you can say, hey, I
only want to load scripts from
over here.
I don't want to have any frames
from other servers, and so on.
We'll look at that.
And the third category here are
simple server configurations.
These are HTTP response headers
that you send out telling the
browser engine, hey, I want more
secure defaults, I don't want
these old legacy APIs that
you've been supporting because I
don't need them.
Please help me here.
So, let's dive into it and look
at subresource integrity.
Now, this is a perfectly
plausible way of loading that
framework from the CDN, your
content delivery network.
And that script tag is going to
just contain the URL to fetch
that script, right?
As I mentioned, you're now
relying on that CDN to provide
you with the right script that's
going to make your web content
work the way it's supposed to.
But actually, if they decide to,
you know, bump the version or if
something goes wrong on that
server, they're serving you--
they're sending you the wrong
script, your web content may be
crippled.
It may-- something may go wrong.
It might not work the way it's
supposed to.
You know what script you're
expecting, but what you're
sending out when you're just
sending a script tag like this--
looking like this-- is just
telling the browser whatever you
get back in JavaScript, execute
it.
A much better way is to say, no,
I want to make sure it's the
script I expect.
And-- but you can use the
integrity attribute in your
script tags.
In there you provide a check
sum, in this case with the
algorithm sha256, saying this is
the check sum of the script I
expect to get from my CDN, and
only if I get something that
matches this check sum, then you
execute it.
So, the browser engine will go
through and make sure to compare
that check sum before executing
the code.
Well, what happens if it doesn't
match?
What if they bumped the version
or something went wrong and I
got the wrong script?
Now my web content doesn't work
anymore.
Well, you add a check.
In this case, you've loaded or
tried to load a framework.
You checked did the framework
load OK, do I have that object
in my dom now.
If not, go load it from my own
server which I am in control of
and I don't make changes to
willy-nilly.
That may reduce performance, but
at least you have a still
functioning web content or
website.
OK. That's sub-resource
integrity.
Let's move on to content
security policy.
I mentioned this is like setting
a policy for your page, like
what should be allowed here, and
I actually think of it as an
architecture policy.
If you're a software engineer,
you want to keep track of your
dependencies.
What am I allowed to do here?
Who-- what can I load and what
can't I load?
So, this is again an HTTP
response header.
So, when you're sending out a
page from your server, you add
this header to the response,
saying, hey, I'm going to run
with a content security policy.
I'm going to be in control of
the content on my page.
Then you start out by saying the
default source for loading any
kind of content from remote
servers is myself.
Only load from my server by
default.
Now you've locked it down
completely and if there is any
kind of content load in the page
trying to pull something in from
a server that's not yours, it
will just be denied because
WebKit will deny that because it
doesn't match the policy you've
set.
And, as you see, I made a
comment there.
No inline.
That is also part of the default
behavior.
Once you set it this way, you're
also saying no inline scripting.
Only load scripts from files.
That's why I keep thinking of it
as an architecture policy
because you're separating logic
into files, separating from
markup, and separating from
styling, which are also in
files.
CSS files.
OK. Now, you wanted to load that
script from cdn.example and if
you just go with a default
source self, then that's going
to be locked down.
Right? You can't do remote
script loading.
Well, there's a whitelisting
mechanism in the content
security policy.
You just say script source, hey,
let's open up for cdn.example
because I actually want to load
script from there.
Now you can load from your own
server and cdn.example, but
nowhere else.
Well, you might want to have
that social media plugin, little
widget in there in an iframe,
well, you can add a frame source
directive saying I want to be
able to load iframes from
social.example, but no one else
gets to have an iframe on my
page.
Again, you're in control of
that.
And there's even a directive for
the reverse case when your
content is being loaded in an
iframe on someone else's page.
In this example, news.example is
loading your content in an
iframe.
You can send out the directive--
the last directive here in
content security policy frame
ancestors.
This is telling the browser,
hey, check whosever framing me
and all the way up to the top
page and they all have to be on
my list of what I allow.
So, in this case, your web
content has said news.example, I
have a business deal with them,
they're allowed to have my
content in an iframe.
OK. That's quite a lot, so let's
just review this line by line
quickly so we know what it's
saying.
Content security policy, you
start out default source self.
Lock everything down.
Everything that's going to be
loaded with a source attribute,
like loaded from a server, needs
to be from my origin, my domain.
Then you open up.
For script, you add what domain
names do I allow scripts from.
You say where do I allow myself
to load frames from.
You whitelist them.
And, finally, if you're ever
going to be in an iframe
yourself under someone else's
page, you put them in that white
list for frame ancestors.
OK. That's the content security
policy.
It has more knobs to turn and
we'll also see in a couple of
the attack scenarios a few
flavors of these things.
Moving on.
We're going to have a look at
cookies.
Cookies are-- they actually were
called magic cookies in the
beginning of the web, and they
really are magic in that we use
them for so many things.
And perhaps the most sensitive
thing is they authenticate
users.
Once you have logged in with
your credentials, you get a
cookie that holds your session
and that cookie, if it's moved
or its stolen and moved to
another browser engine in many
cases can impersonate that user.
So, you really need to protect
your cookies.
As I already mentioned, you
should mark them all secure so
that they never leak in plain
text requests.
But there are more things to do,
right?
So, looking at Http Only
cookies.
This is fairly old technology.
I would guess this has been
around for at least 15 years,
the ability to say HTTP only.
You might be familiar with the
web API document.cookie.
This is a way for JavaScript to
read and write cookies.
JavaScript is powerful.
And, as I mentioned, if you load
JavaScript from other servers,
they have access to all of your
user's cookies through this API.
You should not be offering them
that much power.
Instead, you should protect your
cookies, especially your
authentication cookies that are
effectively a way to log in as a
user by marking them Http Only.
This means that-- this cookie--
and this is the set cookie
header you are seeing here where
we are sending HTTP only, which
means don't expose this cookie
in the document.cookie API.
So, JavaScript can now not see
this cookie and of course not
fiddle with it, steal it, or
manipulate it.
So, this is something you should
be doing.
We also have another thing, new
technology as of the betas,
SameSite cookies.
Again, you are setting this on
the set cookie header that you--
when you're setting the cookie
in the browser.
See here I've got the same site
attribute equals strict.
There's also a lax version of
this, but what this is basically
saying is this particular
cookie, only send it when I am
the page owner, when I am the
main page, not when I'm
embedded.
When I own the whole user
experience, I have the whole web
view, then send this cookie.
So, in the embedded case, if
your web content is being
embedded by someone you don't
trust, the SameSite cookie will
not be sent and your server can
detect this.
Aha! I didn't get that SameSite
cookie, so either this user is
not logged in or I'm being
embedded and I'm not going to
allow this thing to happen were
that, for instance, a sensitive
transaction.
So, that's getting in control of
being embedded.
SameSite cookies.
OK. Cross-origin lockdown.
We're now going to look at
really brand new technology.
WebKit is first implementing
these two new response headers
and they're all about
restricting who gets to load
your resources.
Cross-origin resource policy.
We've already mentioned these
two types of content that are
allowed to be loaded
cross-origin, images, and
scripts.
And they've been around since
the origins of the web and
therefore there has never really
been a mechanism to say, hey, I
actually don't want any other
sites to load my scripts or load
my images.
Could I just only load them
myself please?
No, we've had this thing on the
web where anyone can load images
and scripts from any server.
And now we're providing you with
a control to tell the browser,
hey, I don't want that.
And it's called the cross-origin
resource policy.
In this particular example here,
I'm giving it the directive
same, meaning only my own site
can load this.
Only when my domain name is the
main page domain and I'm pulling
in this image, then load the
image into the web content
process.
Same thing for script here.
So, when someone else comes
along and tries to cross-origin
load your image or your script
and you're sending this response
header, those things won't be
loaded.
So, that puts you in control.
And this is new technology.
Finally, in the cross-origin
lockdown, we've got the
cross-origin window policy.
Now we're really getting into
the weeds of old web APIs.
You might be familiar with the
ability to open someone else's
page-- or for that matter your
own page-- in a new window.
Not like a regular link
navigation you click and you may
open a new tab or navigate in
the same tab, instead you're
opening a full-on new window.
Back in the days, we even saw
this in a form of ugly pop-overs
or pop-ups and those kind of
things, but it's the old API
window.open.
And it has some weird things
going on.
So, if your content is opened by
someone else, it looks to you as
if, whoa, the user just went to
my site, I got my SameSite
cookie, everything looks fine,
but the opener maintains a
handle and kind of owns your
window and has certain APIs to
control that window that the
opener can even navigate your
window outside of your control.
And with the new response header
cross-origin window policy, you
finally get to say no to this.
Most sites are not in the
practice of using this API and
this kind of communication where
the opener owns the window.
Like, it's a very rare thing to
see on the web, but it's there
and it works that way by
default.
By sending this header, in this
case deny, you're saying that
handle should not be there.
It's OK to open me, but you
don't get to control me from
that point.
There is also a way added in
this-- I'm not showing it here--
but you can say allow post
message.
You might want to be able to
talk between these two windows
without giving the opener
control of your window and then
you can say allow post message.
OK. That's also new technology
and now we've gone through the
cross-origin lockdown.
As you can see, that's not too
hard.
It's a set of response headers.
It's the content security policy
where you whitelist things, and
it's the integrity attribute for
script tags that's more or less
what we're talking about here.
I'll give you some motivation.
We're going to look at some
attack scenarios.
What are you defending against
and how to these security
technologies fit in with these
attacks?
We're going to look at
cross-origin attacks,
speculative execution attacks--
some people may have heard about
Spectre-- and we're going to
look at window control attacks.
Let's dive into the cross-origin
ones.
We're going to talk about
cross-site scripting, when
something goes bad with your
CDN.
And that one you kind of could
tell that I was going for,
right?
And cross-site request
forgeries.
Cross-site scripting.
Imagine you have built a
messaging app.
You have it as a native app with
a web view for rich formatting,
for instance, and you may have a
companion web app that one can
go or your users can go to in a
regular web browser, and you can
send messages to each other and
maybe with very rich formatting.
Most of your users are, of
course, nice.
Nice people sending each other
nice messages.
Some of them are angry sending
angry messages, but every now
and then comes along a malicious
user who might send a message
looking like this.
It starts out nice, hello, but
then it contains markup.
Now, if you have made a mistake
somewhere in the chain, in the
native apps web view or on the
website, where this will
actually be interpreted as real
markup instead of a message,
suddenly the attacker, the
malicious user here, is able to
run scripts in the recipient's
browser engine.
In this case, trying to steal
the cookies of that user.
But remember, the scripts are
running with full power.
They can take over your whole
UI, make requests on your-- on
the victim user's behalf.
Cross-site scripting, which this
is an example of, is a bad
thing.
You don't want it to happen to
you.
Luckily, you have marked your
authentication cookies Http
Only, right?
So, ha, they're not available to
that malicious script.
Now, Http Only cookies don't
protect you against cross-site
scripting.
That script is still running.
Http Only cookies protect your
cookies.
So, you need to do something
more and what did you do?
Content security policy.
You started out with default
source self, right?
Saying, eh, only I get to run
script on my page please.
And that means by default no
inline scripting and that whole
class of bugs just goes away.
Now there is no way to inject
script into your web pages and
make them execute because you
set the policy for the page.
OK. What could happen if your
CDN gets compromised?
This is bad and let's just hope
it doesn't happen, but it can
happen.
So, you're loading the framework
off of that CDN and you really
rely on this because it's
executing with the same powers
as your own scripts.
Now, what if they've been
compromised and are redirecting
that script request to
evil.example, loading attack
code.
Now suddenly you thought you got
a framework-- maybe they were
nice enough to bundle in the
framework, but they're also
doing some nasty things.
So, what did you do?
Well, you whitelisted script
source in your content security
policy, so the browser will just
refuse to execute any code
coming from evil.example.
OK. Oh, now the attacker needs
to be a little bit more sneaky.
He or she is probably going to
change the script on the CDN
server instead of redirecting it
to the evil.example server.
So-- and it's on your white
list, so you're going to load
and execute that script.
But, you've got subresource
integrity to save you.
You are in control of the
integrity of that script coming
from a server that you don't own
and if it doesn't match the
check sum, you're going to load
it off of your own server
instead.
So, that attack is also foiled.
OK. That's compromised CDN.
Final of the cross-origin
attack, the cross-site request
forgeries.
This really ties into the last
word, forgeries.
These are-- this is the attacker
trying to forge a request to
look like something one of your
users is trying to do, where
they're actually not.
So, we're back at the messaging
app and you have this forum
where the user is supposed to be
able to send messages.
And, frankly, when it comes down
to it, it's going to be HTTP
requests.
Probably in HTTP post when that
message comes into the server
and look at the cookies,
everything looks good, and then
you'll send that message off to
its recipient, right?
Well, now comes along the
malicious attacker that of
course has phished one of your
users, meaning sent a link and
lured that user onto the
attacker's site, evil.example,
and is showing some really,
really fascinating stats on
cats.
That makes the victim stay
around for a little while at
least.
I mean you've got to check these
stats out.
What the victim user doesn't
realize is that there's a hidden
resource load with your web
content sending a message on the
victim user's behalf-- which of
course automatically adds the
cookies, that's just how the web
works, right?
If a request goes out on the
wire, cookies are added, and to
your servers this looks like I
guess this user wants to send
this message.
That could be spam, that could
be sending links for malicious
software.
It could be breaking up with a
partner-- ah, OK, they won't go
that far, but malicious
software, we'll stay there.
So, you don't want this to
happen.
Luckily, you have used same-site
cookies.
They will not be sent in the
embedded case, which means that
your server will detect I'm
being embedded here.
I don't allow the user to send
messages from an iframe under
some other page.
I need to own the UI when I do
this sensitive thing, such as
sending messages, I'm just going
to deny this request.
This, again, puts you in
control.
OK. We have now covered
cross-origin attacks and looked
at how some of those security
mechanisms help us.
We're going to move on to
something that's really exotic
and new; Spectre attacks or
speculative execution attacks.
What I'm going to cover here is
what speculative execution is,
how it can be turned into an
attack, and then we'll look at
how to defend against it.
So, now we're deep down in a
CPU.
It's executing code.
It has reached a conditional.
It's going to do something
conditionally.
It's asking itself, hey, I've
got an array index here, x.
Is this index OK?
Is this in bounds or out of
bounds for my array read?
Because if it's out of bounds, I
should do some error handling
here, but if it's in bound I
should go ahead and load that
data in the array.
Now, modern CPUs learn over time
if they see the same code path
over and over again that, hey, x
is always in bound.
It's always OK to load this
array.
Why don't I go ahead and
speculatively do that, before I
know whether it's OK or not?
And this is how it works.
It does this code-- takes this
code path speculatively, loads
that data, and then when the
final answer comes in, in this
case, oops, no, this is one of
the rare cases where x was not
OK, you shouldn't have been
loading that data, it backs it
out and takes the right code
path.
How is this OK?
Well, it's OK because the
speculative path is not
committed.
It is only done in advance so
that we can take advantage of,
oh, I'm already done with all of
that work when the final answer
to the original question comes
in.
And that's speculative
execution.
How can this be turned into an
attack?
It turns out that cache effects
that are a result of the
speculative execution can be
monitored by malicious code and
then they can leak that data
read that was never supposed to
happen.
It was out of bounds, that load
should have not happened, but it
effects caches and by measuring
caches the-- an attacker can
leak that data that was not
supposed to be loaded.
OK. How does this map to web
content?
Remember the same-origin policy?
This thing that has been
protecting us for 20 years that
makes sure that the main frame
from one origin cannot reach
into and read the bytes of some
other frame, maybe your embedded
content.
With speculative execution
attacks, we can no longer rely
on the same-origin policy.
There is now an ability-- if you
can run scripts and you're in
the same process, the same web
content process as some other
content, you can read that
content through speculative
execution attacks.
OK. This is a big challenge for
the web.
I can tell you, I've been
sitting in meetings with the
other browser vendors.
We are working super hard to try
to fix this by default for the
web, but we need your help.
If you can opt into a bunch of
things-- we've already looked at
the defense mechanisms, right?
If you can opt into these, you
can help us by telling us, hey,
I have sensitive content.
I'm willing to have better
defaults.
You don't have to support these
legacy APIs for me.
Then we can be much more
aggressive in fighting
speculative execution attacks on
your behalf.
So, let's look at how this maps.
The basic thing you're going to
try to do here to fight
speculative execution attacks is
making sure your web content
never ends up in the same web
content process as a frame from
evil.example.
If they have a frame
evil.example, they can execute
code in your-- in the same
process that your web content
resides in and read your bytes.
So, how do we make sure this
never happens?
OK. We've got these things.
First, WKWebView.
Now we're looking at apps using
WebKit as a framework.
I'm looking here at Safari,
which is an example of an app
that has been using WKWebView
and we sometimes refer to it as
Modern WebKit, has been using it
for many, many years.
And it provides excellent
advantages.
For instance, these three tabs,
the evil.example, your web
content, and webkit.org are all
rendered in separate web content
processes.
Further, WKWebView provides you
with a separate process for
networking.
This is where cookies get added
and HTTP headers are parsed and
et cetera.
Now, speculative execution
attacks all rely on being in the
same web content process and
doing the speculation thing to
try to read things that the
attacker wasn't supposed to be
able to read.
Well, if you have separated
things into different processes,
this attack doesn't work, right?
You cannot do speculative
execution attacks across process
boundaries, so this is already a
defense here and of course
that's super important that the
web content process cannot reach
into the network process and do
speculative execution attacks
there.
But if you are still using
UIWebView, which, by the way, we
are deprecating as of the betas,
you're not in a very good place.
Now, if you have evil.example
and you have your web content
and you've got the network stack
and then you put this all in
your app, from the view of a
speculative execution attack,
this all blends together.
It's all the same process space.
There are no guards for
speculative execution attack in
this scenario.
You need to get off of
UIWebView.
If you move to WKWebView, you'll
instead get this.
Out of process, separated,
badness happening in the
evil.example content process
cannot affect the rest.
OK. We've moved to WKWebView.
Let's look at how content
security policy can help you.
You might have an embedded
social widget from
social.example, but then you
might have an injection attack,
maybe it's the messaging thing
again where someone can send
markup in a message and you
accidentally render it and they
pull in an iframe from
evil.example.
Well, you may also have an ad
there that you want to have
there and then the ad network
gets compromised and redirects
to evil.example and then pulls
in an iframe.
And, remember, you never want to
be in a web content process
together with a frame from
evil.example.
So, what have you done?
You have deployed content
security policy and you've
specified from where you allow
frames and please don't allow
evil.example.
This is how you protect
accidentally getting a frame in
your process from evil.example.
So, the reverse.
Can evil.example pull your web
content into the evil process?
Of course.
So, how do you protect against
that?
We are back at the content
security policy and now we see
frame ancestors.
And this is what I referred to
earlier with a slightly
different flavor.
You can actually say none and
this means never iframe me.
This content should never be in
an iframe from someone else.
This is my content.
Only I get to render this thing.
So, this-- if you place this,
that-- the evil.example page
cannot pull in your content in
an iframe.
And, of course, we do that
blocking in the network process.
That's important, right, because
a speculative execution attack
can only happen in the same
process space, so we cut it off
before it enters where
evil.example can execute
JavaScript.
OK. HttpOnly cookies, do they
really map to speculative
execution attacks?
Yes, they do.
They're even more important here
than to try to fight cross-site
scripting.
Why? Well, remember that old API
document.cookie is the way to
look at cookies from JavaScript?
Now that we don't-- we can't
rely on the same-origin policy
anymore, evil.example can reach
into an iframe from your content
and actually read the cookies.
Super bad.
But if you mark them HttpOnly,
WebKit will make sure to keep
them in the network process.
We don't need to move them into
the web content process because
they never need to be exposed in
the document.cookie API.
So, this automatically protects
the cookies against speculative
execution attacks.
SameSite cookies.
This is basically giving your
server control of the embedded
case.
Again, evil.example has decide
to try to pull off a speculative
execution attack against your
content.
Loaded an iframe with your
content, but the SameSite cookie
doesn't get sent, so your server
will know that, hey, I'm being
embedded here.
I'm not going to allow this.
So, you're going to deny this
whole resource load.
Server side.
And that way not end up in
evil.example's process.
Finally, to fight these attacks,
cross-origin resource policy.
Now, this was the new header I
told you about where you can
tell the web browser engine
that, hey, images, scripts, and
other things from my server,
only I get to load them.
So, if you say-- send this
header for your images and your
scripts on your server, we will
make sure to block them from
being loaded by evil.example and
we'll do that block in the
network process.
Again, giving you that process
separation so that a speculative
execution attack cannot read
your bytes.
OK. We have the final attack
category to have a look at and
this is a pretty brief one.
Window control attacks.
So, we're going to look
malicious window navigation,
sometimes referred to as
tabnapping, and then the
defense.
Again, we're back here at
evil.example and instead of
embedding your content, thus the
window.open opens your content
in a new window and you don't
get to know.
You don't get to decide, yeah,
OK, someone opened my web page.
And the SameSite cookie may be
sent here.
You might think everything's
good, but evil.example could
wait until your user loses focus
of that page of yours and then
use the handle to navigate it to
a fraud page that looks like
your page and asks the user to
please log in again, of course
stealing the credentials and
sending them off to the
attacker.
This is one of the things that
can happen if you leave the
control up to the opener.
Instead, you deploy the
cross-origin window policy, you
deny this thing, and there will
be no handler for the attacker
page to navigate your window
with.
So, that's the final defense in
attack.
It's time to take action.
We're going to review what we've
been looking at here, just so
that you know what you need to
go back to your office or your
home and start working on.
First, we have to secure these
transports.
Move to HTTPS and WSS.
You should have secure cookies.
You should also mark them
HttpOnly.
If you take the Swede's advice,
just make all of your cookies
HttpOnly and secure.
And you need to migrate off of
UIWebView to WKWebview.
These are the basics.
Then we have the defense
mechanisms we've been going
through.
Content security policy will
help you here with cross-site
scripting and speculative
execution attacks.
HttpOnly cookies will provide
you with some kind of protection
against cross-site scripting,
meaning the scripts can't steal
the cookies, but it will
definitely help you against
speculative execution attacks
because HttpOnly cookies are
kept in the network process.
Subresource integrity.
This is the way you fight
against a compromised CDN.
Someone's executing code on your
page that you never wanted to be
there.
SameSite cookies, this is a way
to fight forged requests done
invisibly by some phishing page
to your server.
You will know that because the
SameSite cookie won't be sent
when you're embedded and so you
don't accept the request.
It also happens against
speculative execution attacks
because if an evil page is
trying to pull in your resources
to be able to leverage an attack
against them, again, SameSite
cookies won't be sent and you
can deny the load.
Then we get into these new
technologies, the cross-origin
resource policy.
This is the way you can say that
images, scripts, and other
cross-origin loads, deny them, I
only want to load this on my
page.
And, finally, controlling
windows is making sure that that
handle goes away if someone else
opens your web content in their
own window.
These are fairly easy to adopt,
especially for you.
You know your sites, you know
your web content, you know your
apps, you know how they're
supposed to work.
If we would just turn this on by
default for all of you, it would
probably break a few things, so
you need to opt into this.
And by opting in means you
should check that the security
works-- you can try to pull off
an attack against your own
content, make sure that, yeah,
my content security policy is
defending me, good, and of
course test that the
functionality that should be
there is there.
We have a blog.
The WebKit project is an open
source project.
We have a blog where we talk
about these technologies and
other things.
This is where we'll update you
on those two last response
headers.
The cross-origin resource policy
and the cross-origin window
policy.
Because we're still discussing
those with the other browser
vendors, trying to make sure
that they're standard so that
the same response headers work
across all the browsers.
And so there might be slight
name changes or added attributes
that we still don't have here.
Also, it's so brand new that you
actually won't have access to
this until seed two or the
public seed.
We don't have full support for
these in the developer seed yet.
Quick shout out to these other
sessions.
Please come see us, including
me, at the Safari, WebKit, and
Password AutoFill Lab tomorrow
at 2:00.
You can come there and discuss
with me or my co-workers how to
deploy these technologies and
make them work the best for you.
And there's also a session on
Friday that's more general on
what's new in Safari and WebKit.
Thank you.
[ Applause ]