00:00:10.480
yeah Char Sima hi everyone I'm really glad to see you all here today in Saro
00:00:15.519
and I hope you had a great day today hope you had a great morning and I really hope you tried
00:00:22.279
to well you had a chance to try out the local Cuisine but I really sure hope you
00:00:28.279
haven't tried or would serum because if not uh good luck trying
00:00:35.040
anyway we have a topic to discuss today which is going to be a security related
00:00:42.120
one do you remember what the internet looked like 15 years ago oh and I think
00:00:48.559
that screen is not working properly
00:00:55.760
anyways o yeah anyway yeah already existed 15 years ago Myspace was
00:01:03.359
still relevant and it also let us edit our own CSS and HTML as well we didn't have Discord telegram Viber for any s
00:01:11.119
Community Management surely we did have IRC of some sorts but that's not the same thing is it what we did have was a
00:01:18.680
lot of forums so if we had a fom we probably had a forum if we had a web uh
00:01:24.320
game server we probably had a form and if we had some hooby club we also so had
00:01:30.439
aend them the when lscape was really full of smaller scale web pages portals
00:01:37.960
forums it still is kind of full of them but we have to understand that we've
00:01:43.840
really moved a lot of traffic to centralized platforms and the difference here is that unlike centralized
00:01:50.320
platforms smaller scale websites do not have multi-million dollar web teams and
00:01:55.759
they cannot really allocate a lot of time work on security and so it wasn't
00:02:02.439
really uncommon to see a deface website back then like in some cases you would
00:02:09.319
be able to see a website deface because the owners somehow lost their access to
00:02:14.680
the FTP but sometimes and those are the
00:02:19.720
vulnerabilities that I abused in the past sometimes we actually had a way to inject the scripts into the page
00:02:28.000
and just imagine you're visiting a forum you see that the introduction section
00:02:35.200
has a new message you try to open it and there's a guy named eigor who's introducing
00:02:41.800
himself and that's actually what is happening right now because we're on a forum and I am
00:02:48.599
eager so hi everyone I'm eager I came here all the way from Belgrade it was a
00:02:55.640
5H hour ride it was the toughest part was crossing the border actually uh I'm a
00:03:03.000
software developer linguist I sale I what do I do I sometimes I ride
00:03:10.239
bikes sometimes I pedal board sometimes I ski and feel free to approach me to talk
00:03:16.680
about Linguistics TR be software architectures software engineering in general or processes or just basically
00:03:24.200
anything you feel comfortable with I'm somewhat shy so I might not talk back
00:03:30.080
too much I'm going to talk back but yeah back to our forms you read my
00:03:37.879
introduction and decide to reply but once you pray the reply button what you
00:03:43.120
see is that the
00:03:49.720
click so instead of replying you get reced how did that happen you might ask
00:03:55.799
and the answer is as kinding as I am I managed to inject the script into the
00:04:01.840
page which just decided to override the onclick Handler and redirect to you to
00:04:08.400
the specific video on YouTube and you know recra isn't really
00:04:13.760
the worst thing that can happen to you during those breaches because people might try to steal your session they
00:04:19.959
might try to steal your data they might want to act on your behalf and you know
00:04:25.479
there are a lot of security expertise in the field and so it's generally not something that we
00:04:32.199
do like we don't really let people insert arbitrary code into our
00:04:38.680
pages and so today it's really significantly more difficult to
00:04:44.199
find such such a page that would let you pawn it like that and here's what changed firstly we moved to more
00:04:51.639
centralized platforms those platforms have a lot of
00:04:57.320
money they have a lot of people they have a lot of expertise back then stack Overflow wasn't even popular it did
00:05:04.400
exist it was gaining popular popularity but we cannot say that we had as many developers working with
00:05:11.320
it then we as developers have better tools like back then we like we can
00:05:19.360
argue that people didn't use Frameworks as much Frameworks might not have been popular people sometimes they no better
00:05:26.560
and so to sanitize the data it it had to be an explicit decision made by
00:05:32.120
developers right now it's pretty much the default so better tools
00:05:37.600
and and those tools actually got better themselves at sanitizing the data so and
00:05:43.840
the last important piece of that security is that the browsers got better
00:05:48.880
right now we cannot really see a lot of HTTP sites on secur HTTP sites we have
00:05:56.639
course which is not really giving me a pleasant experience
00:06:02.720
usually and those Technologies are what brings me here
00:06:08.440
today my tech is not going to be my talk is not going to be about Nostalgia it's going to be about one of those
00:06:14.280
Technologies which is contain security policy that's the standard which helps us limit the damage which occurs when
00:06:21.280
Bad actors actually manage to inject some something into the page and to
00:06:27.759
really understand how it works we got to take a quick look into the way browser Pages work
00:06:34.039
and we have to look into the way browsers actually load the pages and the
00:06:41.319
most important thing is that the browser when it returns a page it does the server does not return the images it
00:06:48.599
does not return the fonts Styles whatever what what really happens is that the browsers read the document and
00:06:57.280
then they go and fetch it and usually it happens indiscriminately but with CSP we
00:07:05.440
actually have a way to control which sources are going to be loaded and to illustrate that that idea
00:07:14.039
let's imagine that we have a landing page with user testimony
00:07:19.280
so here's the question where would the images come from what are the valid
00:07:24.840
sources for Logos user pictures
00:07:29.879
other images on the page and usually we will have a couple of
00:07:36.160
CDN they will be accessible through certain domains and that's pretty much
00:07:41.240
all we're going to have that's going to be valid and since we know that we will
00:07:46.360
only host images on those few sources we can probably say that any other domain
00:07:52.280
is invalid so we can tell the browser to reject it because we know it cannot be
00:07:58.280
our content so to do that all we have to do is add a
00:08:04.759
special header to the server response which specifies that valid image sources
00:08:10.599
are the ones that we want so and if you would to write to add
00:08:16.639
any other kind of image something that doesn't match that policy the browser's
00:08:22.199
not going to load it and it's just going to reject it the same principle applies to fonts
00:08:28.120
images workers manifests like media styles a
00:08:34.200
lot of a lot of kind of contents if the server returns a policy
00:08:40.039
which defines which sources to respect for that kind of content the browser
00:08:46.399
will well it will respect that policy that technology is available in
00:08:51.839
pretty much every modern browser I'm looking at you Safari and it's really
00:08:57.240
becoming a part of like secure certifications and really becoming a part of our everyday lives and so it's
00:09:04.079
only natural that we will hear about it more and that we'll see about it way
00:09:09.120
more frequently more way more like in volume and we will also see it in our
00:09:15.399
tools like if you've started a new rails project in the past three to four years
00:09:23.160
you have probably seen a new initializer which gives which suggests a policy and
00:09:28.760
the same goes for R it has a plug-in for Content security policy and it
00:09:35.560
suggests a policy which is a bit stricter than the one that rails
00:09:40.959
has and when I'm talking about strict I have to really specify what strict means
00:09:49.399
and the thing is strictness is spectrum because it's really difficult to somehow defined precisely because like we have a
00:09:57.079
lot of different factors we have a lot of different viewpoints but we can probably say that
00:10:03.959
a less strict policy only blocks blatantly bad content and stricter
00:10:10.839
policies will be difficult to overcome and will require attackers to attack
00:10:16.839
other parts of your infrastructure and get there we can have an an analogy that is
00:10:23.000
somewhat useful not precisely technically correct in ways
00:10:29.160
but that helpful in some ways so imagine that we have a house with a garden
00:10:34.200
really close to a forest a lovely Place good neighbors you don't don't really need a fence to secure yourself from the
00:10:42.240
from anyone but then you realize that's there are hikers in the area
00:10:48.000
there are some animals Critters and you get annoy that they just walk from the
00:10:53.880
forest and go through your yard so that's like
00:10:59.760
not having CSP at all then you have an option to just put a fence on the farest
00:11:06.880
spot for this place of your plot and so that will deter some of them that will
00:11:12.800
actually stop some of them from going surely people can still walk around it
00:11:18.360
people can still hop over the fence but it still reduces the amount of how many
00:11:24.800
of them will go through like the most plant way to
00:11:29.920
walk is going to be closed then you then you have an option to extend defense up
00:11:36.519
to your front yard surely people can still walk around it but it will make them walk through
00:11:44.600
the most populated area of your plot that's the area where you spend a lot of
00:11:49.639
time in and well you have a higher chance seeing that something is going
00:11:55.560
wrong here and you can probably stop them that's like limiting the
00:12:04.000
domains and surely there is the next step you can just fence the whole plot and make sure that everyone who goes in
00:12:11.680
requires your explicit permission to enter and that's the strictest level of CSP that there is that is the same level
00:12:19.880
of CSP that is in the talk and that is the same level of CSP which caused me around four months of really intensive
00:12:27.480
work and a lot of emotional support from my fellow colleagues and that's probably what
00:12:34.959
we're going to talk about next and here's confession
00:12:42.320
time we've come really close to the N part with a lot of code and not a lot of
00:12:48.000
memes and on top of that the second part of the talk is usually my weakest spot in some ways so I brought you something
00:12:54.560
that will make it worth your while hopefully now you can use your laptops
00:13:00.720
to feel what precisely I'm going to be talking about I actually built a website
00:13:05.880
where you can check out various kinds of csps I've created a couple of small attacks so to speak you can test them
00:13:14.720
again for kinds of policies the you will be able to review the attack before it happens and you will choose how
00:13:21.639
precisely you're going to expose yourself to it and yeah you
00:13:27.240
are free to add your own attacks to test to test them out you can just have some fun and I'm going to take the website
00:13:34.959
down in two weeks you can actually have a little fun to we can actually have a
00:13:40.399
little fun to demonstrate um
00:13:45.440
basically let's do the recra so we can see the policy that we currently have in
00:13:51.120
the browser we can have the code that's going to be injected and we can see it
00:13:56.399
with different kinds of o we can see them with the console the
00:14:04.480
console is where it's at so when we see when we launch it in dynamic
00:14:11.720
dynamic why does it there is a filter
00:14:16.839
yeah and then security policy of your site block some
00:14:23.759
resources so yeah that's what happened we didn't load jQuery which
00:14:29.720
realistically but then if we have no CSP what's going to happen is that I click
00:14:35.440
anywhere in the page and it redirects me to YouTube so yeah that's how it works you can feel
00:14:43.360
free to and now I decided to play the music on my laptop uh
00:14:52.079
right oh no thank you that that's not going to be needed
00:14:57.199
right that's that's the link feel free to open it and I'm going to take a
00:15:10.160
sip yeah right back to our
00:15:15.240
policies our goal today is to introduce the strictest policy to an existing
00:15:22.000
project I'm talking about existing projects because that's probably what we are working with usually because when
00:15:28.440
the project has the requirement to add CSP usually been living in the wild for
00:15:34.319
a few years we can also say that it has acquired some kind of like see it has
00:15:42.680
acquired some tech debt and so it's not going to be as easy as
00:15:48.639
interaction in Greenfield projects so we can start with default ra rails
00:15:56.800
policy it produces a fairly permissive policy but still blocks some kind of
00:16:02.199
content so let's go ahead and see what exactly it will
00:16:07.560
block when we're dealing with complexities of CSP we are usually more interested in scripts and styles and not
00:16:14.399
in other kinds of content usually when and I emphasize when talking about
00:16:23.839
complexities that is because other kinds of content is
00:16:29.319
usually somewhat straightforward there are not too many ways to include other kinds of content
00:16:35.920
and there are a lot of ways to include scripts and styles and a lot of variations a lot of security
00:16:42.720
considerations too because those are the probably the most powerful tools that we have on the pages
00:16:50.279
so that policy that policy blocks inline CSS
00:16:59.279
an inline JavaScript so if we had just something sitting in the
00:17:06.360
attributes it's going to be blocked so yeah yeah if we yeah if we had scripts
00:17:13.720
in the attributes they're going to be blocked if we had inline Styles they're
00:17:19.360
going to be blocked in the attributes too then what's not going to work is
00:17:27.400
eval it's been while since I lo since I saw a new JavaScript library which uses
00:17:34.120
eval for anything but Source Maps but they're still there in the wild they might have been added back when the
00:17:42.039
project started like five six more years ago and so that's going to be blocked
00:17:50.520
too then we will lose access to regular inline
00:17:57.360
JavaScript but only only if they come without a NS or if they come with the NS which doesn't match the one provided in
00:18:04.679
the header and when we're talking about nonis we have
00:18:13.159
to understand the N along with the hash is basically the way for us to say that
00:18:21.280
that script is definitely eded by us so the NS means that the script is added by
00:18:28.280
us the proper NS only the server Returns the policy and it specifies which NS is
00:18:35.360
valid for the page well and so the thus the every non send page must
00:18:42.919
match the one sent by the server and otherwise the browsers will
00:18:48.240
reject it and I can see the screen is rejecting
00:18:53.520
my talk right now so we'll probably wait a little bit until that part is resolved
00:19:01.720
because it's really like you know how chess Grand Masters can play chess in
00:19:07.880
their minds it's not only Grand Masters but people who are proficient in chess I have my utmost respect for
00:19:15.960
them and yeah I don't really expect you all to do the chess into your head
00:19:21.799
especially with rubby code especially with all of the layers of complexity that there are
00:19:29.960
so yeah that's probably that's going to
00:19:36.679
happen next
00:19:41.880
so back to our sheep so the header
00:19:47.000
returns a NS the same NS has to appear in the
00:19:52.080
same in the script so if the script is not accompanied by nons or accomp is
00:19:57.720
accompanied by the one which doesn't match the contents is going to be
00:20:03.640
rejected uh if an inline script or style contains to non switch matches the
00:20:10.159
header is going to be valid I usually recommend using built-in helpers in the
00:20:16.799
rails because they just sport that out of the box so this policy is really fine for
00:20:25.559
new projects but it will break some thing for older
00:20:30.840
ones and let's work on that what we're going to do to make our
00:20:36.120
lives easier is to run our testing straight on
00:20:41.440
production it usually sounds scary but we have a nice way to do so and is here
00:20:49.360
you can see the last line changed so that's the thing which we can do with
00:20:54.600
content security policy is that we can run it into in the report Port only mode
00:20:59.640
so it will pretend like it's a proper policy but it will the browser will not reject any well it will not reject
00:21:08.159
anything so if we combine it with the functionality of reporting we will get a
00:21:13.840
lot of valuable insights we will see what exactly is broken in our platform without anyone
00:21:21.559
noticing that something is wrong so we have a lot of monitoring tools we have generic ones like data do Sentry r
00:21:29.159
and then we have CSP specific ones like report your I Casper I think it's
00:21:35.679
pronounced what what to choose is up to you but please consider that those CSP
00:21:42.039
related tools also give you tools to improve the policies so there are two
00:21:48.840
separate things you might do with them so once we've implemented that we will
00:21:55.919
have to wait a few hours or a few days to collect F data because yeah that's
00:22:01.279
just we need to get the real user load to see where exactly the problems
00:22:06.880
are and then we will play the game of wamo I found an image which doesn't
00:22:12.200
really look like a mole it's more like a French Bulldog but that's whack all the
00:22:18.000
the game they pop up and then you hear them so what will you probably find the
00:22:26.320
first one is sometimes we use HTTP instead of https that we'll have we're
00:22:31.840
going to have to fix that then we will see that Safari images loads images from
00:22:38.240
blob which is weird but that's what Safari does so we will have to extend
00:22:43.760
our policy to allow for that weird use case EV else won't work so we'll have to
00:22:49.520
rewrite we have inline JavaScript and the attributes and the links we actually
00:22:55.279
have a way to allow that to add an except to the policy but we can just
00:23:00.679
rewrite those then we will see some dependencies that are broken some of in
00:23:06.600
line inline scripts are going to be broken so we'll have to update them in some way or we're going to have to
00:23:12.960
replace that and we're going to have to do a few iterations of that and those that's going to take some
00:23:20.679
some time that's going to take well because well practically it is a game of
00:23:26.120
wacka after all so the new issues are going to be popping up new weird issues are going to be popping up and we are
00:23:32.960
going to have to fix them that's pretty challenging but that's probably not rocket science the
00:23:40.919
process itself is not rocket science but sometimes the fixes are not that far from it so once we've done that we will
00:23:48.840
be safe from that kind of fre roll because we are not allowing any inline
00:23:54.600
scripts but you might have noticed that we allow any script from from
00:24:00.080
https so where should we go
00:24:05.400
next we basically have two options we can either constrain by domain or we can
00:24:10.960
go all the way towards stre
00:24:16.039
Dynamic when we constrain the domain we have multiple benefits well the first
00:24:21.679
all we have to do is to collect all the domains that are going to be listed in our apps Local Host
00:24:29.080
stagings Docker um CDN and we have to just put the list
00:24:36.919
together and inserve them we need to also match some kind of security but
00:24:44.080
that really provides adequate level of security because as long as those domains are within our
00:24:49.360
possession we will probably be fine then the fun thing is that the monitoring
00:24:55.440
Services the the CSP specific ones they can generate the list for us they can
00:25:00.919
generate the policy by observing the reports and it's really quick to
00:25:06.520
implement but the thing is it's not really so simple because we need to make
00:25:12.320
sure that we cannot load scripts from the same domain that we upload files to
00:25:18.399
we need to make sure that those domains are either are under control or are trusted by us then it might we have to
00:25:26.440
deal with third party script scps we need to somehow make ways not to forget
00:25:32.799
and then we need to make sure that we don't have some unsafe Technologies and with strict Dynamic the scripts will not
00:25:40.880
load unless explicitly Allowed by nons any script any script is not going to be
00:25:47.360
loaded that's kind of transitive because like we might have we might have a
00:25:52.880
question so I have a script it loads some other scripts how do I pass the NS to them and the answer is you don't have
00:25:59.600
to the browsers deal with that and I think at least was or I think
00:26:09.799
reasonably the proper way to overcome that kind of policy is to do man and
00:26:17.120
middle attack which is rather bad for you so like either way
00:26:22.919
it's going to be have attack so and it might be easier in the long
00:26:30.360
term but it requires us to add scripts in a very specific way it also requires
00:26:35.919
a lot of Labor to address all the single script in our application because we
00:26:41.919
have to Target the place where it's being added then it might be problematic with
00:26:48.279
hot wire there is there are a few issues with turbo specifically and it really is
00:26:56.120
extremely difficult with static pages when and when I'm talking about adding scripts in a certain way we just have to
00:27:02.440
make sure that everyone uses the same way to add scripts which is usually the
00:27:09.240
rails helpers and they have to remember to put in the
00:27:15.480
parameter it doesn't have to be this way a while ago I submitted a proposal
00:27:21.320
to do that to fix that so that like if we have strict Dynamic the answers
00:27:27.200
should probably be edit automatically I don't really have the energy to pursue that endeavor but if
00:27:34.600
you would like to join or you would like my help with that just ping me
00:27:40.039
and we'll do it so one of the last things about the real
00:27:48.840
complexities we have scripts on static pages when we have a static page we have a static HTML we don't have a server
00:27:55.799
which generates the HTML for every single response so in this case we can
00:28:02.200
probably say that we cannot add any nonsense to the scripts so what shall we
00:28:07.600
do one of our options is to calculate a hash of the script that's tricky if you
00:28:13.760
do not control the scripts or if those are bundled or like that that requires a
00:28:19.519
lot of heavy machinery and especially if you add external scripts that's not going to be viable so
00:28:27.480
there's one weird standard solution is to take all of the scripts or take some
00:28:33.200
of the scripts on the page group them together by URLs and
00:28:39.039
like parameters and then write another script that will add them to the page that's weird kind of but that
00:28:48.399
really works that really works really well in some cases until it
00:28:54.480
doesn't that's actually the reason I spent 2 and a half months implementing
00:28:59.600
the policy because we were using xjs and it uses server side generation and so we
00:29:06.880
have static pages and so we have to deal with that in theory with react is going
00:29:12.279
to be easy because you have virtual Dom you can do all sorts of rewrites but in reality it's really really
00:29:20.399
heavy so the alternative to that solution is to just
00:29:27.360
add another level proxy because if you have a CDN you usually have Edge functions if you don't have a CDN but
00:29:32.559
have proxy like traffic you can have a plug-in that rewrites the contents and so you
00:29:40.120
can put some kind of placeholder and replace it and you'll have to do that in both
00:29:47.240
header and the body but the risk here is that it might
00:29:54.840
be a vulnerability potentially if someone learns about your specific
00:30:00.440
placeholder so yeah you have to think about
00:30:06.640
it so there are a lot of things I can say about CSP but not a whole lot I can
00:30:12.360
say in an interesting fashion and while also meeting the time limits that we
00:30:17.440
have so let's wrap this up and see what we've achieved well firstly the overall
00:30:27.080
idea is that c helps us against cross- scripting and all sorts of injections data injections like image
00:30:34.960
injections and it the way it does it is it limits what kind of content can be
00:30:42.320
successfully injected if you want to introduce CSP to
00:30:49.039
your project you can start with rails default policy and itate from that just run it in the report only mode and
00:30:58.320
use report URI to get the insights into what's going wrong with the project and
00:31:03.760
then you will have to fix a lot of issues and it's going to take some time and it's going to take some effort and
00:31:09.639
you're going to get exhausted at some at some part of that
00:31:16.000
journey and then when you have to go further you have two options either go
00:31:21.720
to limit the domains or you can go towards strict Dynamic and allowing a
00:31:28.000
every single script explicitly and when doing that make sure you waited the pros
00:31:33.679
and cons of each approach like generally it might be easier to go for the mains
00:31:39.440
because if you have an Spas that's then adding stct Dynamic
00:31:46.159
might be way too much effort and if you're using rails for front and there are issues with Hotwire that you will
00:31:52.000
have to fix yourself and once you've done that that
00:31:59.279
make sure to enjoy your time here in Sara and that's it yeah thank you