hi everyone thank you for joining me uh
today we're going to talk about csp
where it is broken what can you do to
fix it um or just demystify
some of the aspects of csp so
once again thank you for joining me for
this this talk
okay my name is amir shakad i lead the
engineering and research at parameter x
um private rex we're a cyber security
company
doing multiple apsec products
and uh i'm a lifelong hacker and i love
building things with good people and
seeing them use the
to help people in any aspect especially
protecting from
bad actors okay
so let's begin um we'll start with the
story the story of
i wanted to enable csp on my own website
i went on and i read and understood the
meaning of all the directives
and all the different options and
configurations uh exist the
documentation was pretty straightforward
um i added the csp header with the
report only
option to see all the potential
traffic coming out of my website i
analyzed it
about day later i marked all the
resources that i really think are
related to our
website and configured the csp properly
rolled out block mode and had zero
issues with the with my uh
infra everything kept on working
properly
um so that's my story uh and
i think no one ever said such a story
because it doesn't work
never happened in such a way um for
multiple reasons and we're gonna
see examples of some of those reasons um
today
a different story that happened
later that year this one is a real story
unfortunately um came from
a customer of ours
they got a call from the credit card
company
and telling them that a lot of credit
cards were
stolen via their website
working with them trying to analyze the
details they brought in a security
consultant they found a third-party
vendor that was used
and was responsible and the third-party
script was breached their source code
was bridged
and that that snippet started sending
additional information
collected from the page to an external
domain say malicious.com but any
external
domain and that's how the credit card
information was
stolen from the website and one of the
things
that was brought up and was a question
of how can it be
because csp was supposed to do exactly
that
protect the client side in terms of what
types of communications are allowed
and where can the data be pushed over to
and and the sad story is that the csp
was there but it wasn't there because of
a lot of
gaps that can happen while you're
configuring it
either it's missing some key directives
or
[Music]
setting a connect source only
or from where you can pull script
but the attacker just bypassed that with
some image tags
and adding the information as um as the
request parameters
and we're going to touch on some key
examples uh later on
in the in this talk
okay
so what is csp
csp is um
[Music]
first is short for content security
policy it's an added layer
uh primarily focused are trying to
protect um
from different types of attacks on the
client side mostly cross-site scripting
or data injections
and those attacks are mostly used for
different kinds of data theft
or phishing um defacement potentially
though that's less common it's mostly uh
the those exercises are mostly for
uh data theft and um
either directly or indirectly via
phishing forms trying to extract extra
information
additional information from the user the
standard itself originally
named content restrictions actually that
was proposed uh
back in 2004 by robert hansen
and it was first implemented in firefox
4
actually later on the first
wc3c draft became public in 2012
with the latest version 2 which is the
most common in the
one used today in practice we had the
final version in 2016
and the version 3
which adds a lot of additional layers
but
again sadly not enough that's still in
draft mode
and still open for uh comments
so how does it work what's the big
promise and
the idea behind csp essentially there
are two types of headers
uh it's an http header where there are
two of those one
is for uh report only they both have the
same policy
but they behave differently there is the
report only policy
whereas the browser will behave as if
it is going to do the um
the policy enforcement but it will only
send information
on what would have happened should the
policy have been enforced and the other
is active blocking basically enforcing
the policy
and having the option to report what was
blocked
so let's look at this example we have um
three directives uh the default source
and um scripts also report your arri
what we basically have is
here is any default source self says
anything from the the website's domain
can be loaded um javascript code can be
loaded either from the domain website or
from cdnjs.net
and if there is any violation that's
going to be reported to
our domain slash csp logging
now if you look at the example we have
an image loaded from a local website and
a scripts
loaded from the cdn whitelisted domain
that's gonna be
valid and gonna work and if for some
reason
we have an additional um
request coming from our website um that
will not
work and you can see it will not work
because the domain is a bit differently
uh it's
common
[Music]
okay
so it looks like a a great
story of uh how a policy standard can
help us protect the
client side um but the problem with
uh specifications like any specification
is the gaps that it have and here is
where the story starts
uh going down to the rabbit hole first
it's not fully defined
uh things like what a report holds when
to report leading to inconsistency when
you're trying to actually analyze
information those metrics or logs being
reported by the browsers
the implementation itself may be lacking
um just search
csp in the cve database and there are
always items being found and it's very
usage dependent because it's policy
based and that can be abused and we're
going to cover examples on all of these
gaps in the specification
so let's start with numbers um
is it actually being used you know it's
a great looks like a great technology
security technology but
is it actually being used out there by
uh
web developers or devsecops
administrating websites this data
is based on the http archive scans from
the past few years it's an amazing
database uh it's my first go-to when
trying to do analysis
on how different web technologies are
being used
uh well it can always have gaps it's
just an amazing data source each month
they scan
around 4 million websites and store all
the information
in the http archives database anybody
can access and use it for research
so what do we see here what we have here
is the use of
actual security headers over time in the
past few years and then
you can see it relative to the amount of
scan domains so it's relative
information
and what we see is actually very
interesting we see
that first of all the csp adoption grows
while slowly but it is growing at about
10 of the sites today
um and if we will look
at the actual um actual items
we'll see that the first uh
the top one is mostly that's all the
security headers by the way
uh as you can see not just csp so we see
a growing usage of two headers that are
actually deprecated
and were replaced by different
directives in csp
and we do see an increase in overall
security
options in http but they're mostly
around making sure the traffic is
secured by tls that's what we can see
here
so it looks like a positive trend we see
more and more websites
using this uh security uh technologies
but if you actually look at those uh 700
000 websites
um using csp and trying to understand
what they're actually using we'll see
that they're
basically uh these directives are the
most common ones
and they're basically uh just replacing
the
um the obsolete ones
with the new version of those so it's
not a real adoption of the more
um complicated and uh
interesting directives it's mostly just
the tls
um what we have here brief explanation
so the top one
uh frame ancestors that directive
states uh if our website is allowed to
be embedded within a page
should the browser allowed our website
to be embedded within a page
uh that's the most common one the next
to
the operating secure moves all the
traffic to https
and block mixed content states that no
traffic should be without http without
https so
do not allow both secure and insecure
connections for you within the page
just in case somebody made a mistake in
the programming
all the fetch directives uh default
source script source etc
those are the ones actually controlling
the domains that can be communicated
from the website
so these are the interesting ones we
want to focus on and you can see that
the adoption here is
still pretty low compared to the amount
of websites out there
so it looks like a positive trend but
there is still a gap here
and
you want to be mindful when you're
talking about a policy
uh some of the examples i saw when i
started to dive into all those
uh thousands of uh
actual users in the wild and we see
cases where
a very insecure usage like default
source which allows
any unsafe eval or unsafe inline code
essentially allowing anything to be run
on the page protecting nothing
versus um a very restrictive mode
like the script source with the nonce
stating that any inline code should
match one of these
signatures so somebody can even
manipulate your own inline code
unless they actually control the server
obviously and can change everything
but outside the website they can't
control it
we saw a lot of examples of just pool
usage uh
when i was looking at the directives i
saw over 700 of those
uh where there should be only about 30.
uh i gave some examples here
uh the last one uh i would say the
funniest for me uh it's been around
for a while go for it i really have no
idea what they were trying to accomplish
with that policy
but a lot of mistakes um from different
kinds
when actually trying to implement uh csp
uh spelling errors uh replacing the
header
key with the header content
and the issue is with that whenever the
policy is invalid it's just
not doing anything and there is also no
reporting so uh
you can really have no idea that nothing
is actually working
so i really invite everybody who's
trying to use it to use the
csp evaluator uh by google uh it's an
amazing one that shows
it's the best evaluator i've seen to
date to make sure the policy is actually
accurate
okay so let's talk about actually
reading the reports
this is an interesting case when you
actually have an installation in place
with the reporting on different
violations and you're trying to
understand what you're seeing you see
that
data isn't normalized it really is full
of
stuff that's not relevant anything that
an extension
on the browser that adds code to the
page will actually create
violations that you have nothing to to
do with
ads can create that noise web proxies
that load the
website can create it bots as well and
the issue is that
um all that nonsense of information
is really creating a lot of problems and
trying to analyze
if there is a problem with the policy
that you created do do your users
experience any kind of problems or not
let's take extensions for example this
is an interesting case
by design an extension within a chrome
browser
can bypass the website's csp policy
um and can ignore it completely
so it's not protecting from stuff that
can come from within the
machine itself like an extension
installed on the browser
but if the extension is doing something
within the page uh
in a certain way you will still get the
violation reports from that extension
and you have nothing to do with it
because uh they will still work
um the last one here has some the github
here uh some really interesting examples
of uh trying to explain
and a lot of unexplained cases as well
um different
um reports that
[Music]
this security analyst have seen over
time
and then we have the browser
misalignments actually like we said the
actual data
isn't it's not defined within the spec
when and how the information should be
sent and you can see a few examples here
which are actually very interesting
let's start with chrome
in chrome if a block was actually
and the resource was actually blocked
then we will get the report
um once um and only once for that
first block even if the resource is
being called again and again and again
um on firefox for example you will get
uh the reports for every time the
resource is trying to be called
so that's one big difference on its own
and then safari at least and the
[Music]
version that we analyzed at the time
um would only report
the block uri for example and it would
truncate that to the top level domain it
will give you
the full uri so these kind of
misalignments create a lot of
noise and but also create some
guidelines or tricks that you can use to
get
better value out of the reports that
you're getting
and last but not least i haven't seen a
lot of cases of this but
log spamming where the client side by
design cannot be verified and the
reporting can be abused
uh especially if you have some machine
learning model trying to learn
what domains should be whitelisted by
volume for example
so either it's creating a dos
on your sock group or just trying to do
adversarial machine learning
uh the fact that there is no validation
on the reports
can be an attempt to abuse the concept
and
and put domains into the white list
okay so we talked a lot about the first
item in the agenda let's talk briefly
about the second items
um just looking at the cvs over time and
we see there are implementation gaps
and i don't blame the browser developers
it's a
complicated policy uh complicated
standard
it's and and it's not easy to create a
full
a safe system to fully implement the
policy
but do you see gaps over time
overall and specific in the specific
browsers over time
gaps in the implementation are found i
want to
give an example of one such cve that we
found and published last year and
it's pretty straightforward to explain
it so
using the following directives say
object source
should be none child source none and
script source only
from yourself the following code should
be blocked and it is blocked when you're
just trying to create an element and add
a
url coming from an external
domain but if we do a little trick
creating the element as an iframe
with the javascript source in it
that will work now this was patched
already and it was resolved but
it's an example of how attackers can
really try to find the
slightest gaps in the implementation to
bypass
um the way the
model actually works within browsers so
here is an example of such a case
obviously already mitigated by chrome
and the last one um is the story i like
best because
it really takes all the concept of
having a policy
and break it apart um
and show how it can go completely wrong
and the idea here
came from the research concept here was
straightforward so looking at all the
websites and all the domains that are
whitelisted and how they're actually
using csp
um the question came to mind was okay
let's look at the most common allowed
targets
um for this traffic
from the website what are those actually
being used
by websites and we can see that if we
look from march 2020 to june 2021
and the most common one was
and still is just increasing numbers
google analytics
and this is just the top level domains
you can see here the example of all
kinds of subdomains
uh it's in june 2021 as well just lower
numbers
but just taking the top one without even
the
following domains uh google analytics is
the most common
allowed domain in csp policies
when they're actually trying to to limit
with the with the fetch directive and
not just have the
high level tls protections
and if this was live i would
ask what would you do with it uh we'll
jump to the answer
and the answer is let's try to abuse it
if they're whitelisting google analytics
can we use it to extract information
obviously the answer is yes that's
pretty simple
there are no built-in protections around
that so we just add a piece of code
to the let's say we've reached a third
party script bridge the supply chain
in some way and it's important to
remember
bridging supply chain is it is a very
common techniques
was and still is even just a few weeks
ago
there was a um it was an actual breach
but it was a risk published
on uh on cloth rose cdn
gs where a potential
actor malicious actor could change code
being served by the cdn so that's an
open risk and it can happen
from anywhere can happen at the cdn
level and it can happen
on a small company without the proper
security measures being bridged but
their
sensor is used in our application
because that's how you build modern
applications today
so let's say you try to protect yourself
with xss you put the csp
and control the domains somebody can
still abuse the
safe list by adding a few lines of code
assuming your white listing google
analytics
most do and just send the bitcoin
on the data collected on the page uh the
code is pretty simple
and straightforward and then we go into
their google analytics page
we have the information extracted report
base64 and there we have it uh username
and
password being collected and um
all the protections that we try to build
collapse under the fact that we just
whitelisted
[Music]
google analytics
so trying to protect that the next
question that comes to mind is
let's put some query parameter
protection would it be nice if we just
you know protect and say a specific
account
tid let's let's limit it to specific
values
and then for actually pretty obvious
reasons
um performance mostly uh questions
this is a quote from the spec um you you
can't
protect query string uh parameters uh
it's not evaluated within the expression
only the top level domain is part of the
policy nothing beyond that so that won't
work
um and the interesting thing is um the
flow was
so this is a theory somebody might be
able to do it uh
because that's the most common one we
published the article about the method
as theoretical idea
and then just a few days later uh there
were reports by different security
vendors stating that they actually
found the this method being used in the
wild by skimmers
uh digital schemers abusing the
concept of google analytics by csp
so the flow here was interesting
we looked at what is the most common how
can we abuse it
we looked at it as a story and then the
fact is that this
is actually being used in the wild by
attackers
means that it's a very real risk that
attackers have found and are already
abusing
and there is no mitigation around this
this is important and it's not just
unique to google analytics as well
um and here is where it went wrong if
you want to look at it and managing a
policy
it just doesn't holds in today's modern
web apps
and and it's not just google analytics
they're not unique
if you look at the concept of trying to
whitelist domains
um when you're constantly adding third
parties first party
um all the time and and
you're trying to manage uh different
succox names of
who can add code and where
it becomes impossible to limit the
domains that are actually being used but
even when you try to limit them
the most common ones that are actually
being used as you've seen from the data
itself from
what um suckups teams are actually doing
all of those are websites that in by
potential
can be used the same way that google
analytics was used you know anything
from
either if it's free accounts where you
can create on
youtube or twitter on all of those
or even if it's paid accounts on some
vendor
it would still be very cheap to create
an account and then
use the domain to send information now
in order to protect
here we need help from both ends
these services they can help
if they will define the i would say the
destination id as part of the sub domain
and not just part of the query parameter
and
won't allow it also as part of the post
data or even if the post data is being
sent they will validate that the sub
domain matches
think of it if all they do is google
analytics and
other vendors big vendors like that will
add
the option to use a subdomain
then the csp would work and it would be
a hit
but most of them don't allow that so
that's one gap
and the other is from our side
limiting those destinations and also
removing these resources if we don't
have to have them in specific parts of
the
of the site so even if we do use google
analytics
maybe we can remove it from sensitive
pages
where there is sensitive information
that somebody can
try and use try and steal from us and
for malicious intent
so
let's talk about what we can do to make
the best of it
um
one thing i haven't mentioned um going
back to the first item
is how we can differentiate if a report
is coming from one user or the other
and the most common practice here is to
create some
uh either random value
in one way or another on the report url
as a request forum
so you add an identifier and then when
the report comes back
from the browser if there was a
violation
you can use those requests for arms in
order to understand
which user or how many users were
actually affected with that
report
say you have a session id being set by
the
your javascript code the server can take
that into
the report and and bring it back as part
of the header
so we'll be able to differentiate
between different users and understand
how many users you're
seeing versus how many ips you're seeing
with reports second is to filter the
reports
the best practice that i recommend here
is to focus on the
most common browsers you see on your
website whether it's chrome safari or
um whatever um and just focus on those
if you have a problem with your policy
they will pop up on a common one and
it's really no point on
um trying to focus on all the
isotheric cases um
there is the option to a b test the
policy which is actually pretty cool
you can take a subset of the traffic use
a report only
policy on that do it even in a very
very strict limit everything and then
you can play with which domains you're
unloading and disabling
to make sure that the policy is up to
date and accurate and that you're not
leaving domains that are invalid or
irrelevant
uh one example i've seen uh is
on websites that whitelist domains
just because they did a poc with some
startup then they dropped it
and then later on the startup was closed
they still white is the domain
somebody can just buy the domain and use
that as a drop point
so also something you want to make sure
that your list
is up to date with relevant domains and
not something you added before
and that's because there is no report on
what is actually being used it's only
proportional violation one of again
a gap in how a policy
um can be used
but the nice thing here is you can use
that your advantage and a b test the
policy and make sure it's always up to
date
and limited
i would also recommend adding more
layers of security such as lancers and
hashes on only inline code
[Music]
if you can do it it will protect you as
well
and last thing like i said being context
aware different policies for different
sections of the website also very
important
in order to better protect um
[Music]
and limit the in
the built-in gaps that there is within
csp so i'm saying a lot of
um a lot about gaps here
and the concept but it still is a good
concept it's not like you have an
alternative
to csp that is fully proof
and bulletproof so i would still
recommend to use it but be aware of the
issues and definitely have ideas as
security researchers especially
to come up to csp3 with comments
and sure there are ways we can
improve the standards that's it
thanks for listening um
[Music]
i'm open to q a
i'm happy to answer any questions that
you have