- 00:00:00 hi if you're a web developer of course
- 00:00:02 you have to build secure
- 00:00:03 web applications and cross-site
- 00:00:06 scripting attacks are one of the biggest
- 00:00:08 threats to modern web applications
- 00:00:10 and therefore it's important that you
- 00:00:12 write code that's not
- 00:00:13 prone to cross-site scripting attacks
- 00:00:15 and that you in general
- 00:00:16 understand what cross-site scripting
- 00:00:18 attacks are
- 00:00:20 and where potential security holes could
- 00:00:23 be found in your application
- 00:00:24 this is exactly what we'll have a very
- 00:00:26 close look at in this video
- 00:00:31 so what is a cross-site scripting attack
- 00:00:33 here is a very simple application
- 00:00:35 you'll find a link to the source code
- 00:00:37 below the video but it is a simple
- 00:00:39 application with just free files
- 00:00:41 this application actually also runs only
- 00:00:44 in the browser
- 00:00:46 for a cross-site scripting attack you
- 00:00:48 would also need a server but i can show
- 00:00:50 how to launch
- 00:00:51 one with this example as well which is
- 00:00:53 why i'm using the simple example
- 00:00:56 here we can send messages with some text
- 00:00:58 and an image
- 00:00:59 and we can have multiple messages here
- 00:01:03 which are then simply rendered below
- 00:01:04 each other and of course it would be
- 00:01:06 easy to imagine that this is not
- 00:01:08 just a dummy application where we can
- 00:01:11 work in our browser only
- 00:01:13 but that those messages and the image
- 00:01:15 urls
- 00:01:16 are sent to a server and then there
- 00:01:19 they're stored in a database
- 00:01:21 right that is how the vast majority of
- 00:01:23 websites work
- 00:01:25 users are able to buy a product which
- 00:01:28 leads to a request being sent to a
- 00:01:29 server to store information about that
- 00:01:32 purchase there
- 00:01:33 or you have a blog website where you
- 00:01:36 write a blog post
- 00:01:37 you save it it's stored in a database
- 00:01:39 and users visiting your website can see
- 00:01:42 those blog posts
- 00:01:43 or you have a public forum a public
- 00:01:45 board where users can discuss
- 00:01:48 everyone who contributes and sends a
- 00:01:50 message sends that message to a server
- 00:01:52 where it's stored in a database and then
- 00:01:54 other users can follow that discussion
- 00:01:57 by loading those messages and seeing
- 00:01:59 them
- 00:01:59 on their screen on their device when
- 00:02:02 they visit the website
- 00:02:04 that is how the web works right and this
- 00:02:06 application could be exactly the same
- 00:02:08 those messages could be stored in a
- 00:02:10 database on a server
- 00:02:11 and how could we now launch a cross-site
- 00:02:13 scripting attack what is a cross-site
- 00:02:15 scripting attack about
- 00:02:17 it's about executing javascript code on
- 00:02:20 our users devices
- 00:02:23 and one potential trivial attack pattern
- 00:02:26 you could think of
- 00:02:27 would be that you add script tags here
- 00:02:30 in your message
- 00:02:32 and you then have some malicious code
- 00:02:34 here
- 00:02:35 in this example just an alert where i
- 00:02:37 say hacked
- 00:02:39 and you hope that this website is built
- 00:02:42 such that
- 00:02:42 this content is rendered in a way that
- 00:02:45 this code
- 00:02:46 executes and you actually don't have to
- 00:02:48 hope for that
- 00:02:49 since it's javascript code you can
- 00:02:51 simply inspect the website
- 00:02:53 go to the sources tab of the browser
- 00:02:56 and there you can simply see the
- 00:02:59 javascript code that powers this website
- 00:03:02 on some sites it might be minified and a
- 00:03:04 bit harder to read
- 00:03:05 but ultimately you can always read
- 00:03:07 javascript code
- 00:03:09 more on that by the way also in another
- 00:03:11 video and article which you find below
- 00:03:13 this video
- 00:03:14 so here i can see how this website works
- 00:03:16 and of course that's exactly the code
- 00:03:18 you see here in the app.js file
- 00:03:20 and in the end you see that the messages
- 00:03:23 which are sent by the user
- 00:03:24 are validated then added to a user
- 00:03:28 messages array
- 00:03:29 and in reality they would then probably
- 00:03:31 be sent to a server and stored in a
- 00:03:33 database and be
- 00:03:34 fetched when the website is loaded and
- 00:03:36 whenever we have messages
- 00:03:38 no matter if it's like here in this
- 00:03:40 dummy application or
- 00:03:41 if we fetch them from a server we do
- 00:03:44 render them at some point
- 00:03:45 and here rendering the messages simply
- 00:03:47 means that i loop
- 00:03:49 through all the loaded messages and i
- 00:03:51 build a long string
- 00:03:53 full of list items which is then added
- 00:03:55 with inner html
- 00:03:57 to our user messages list to that
- 00:04:00 unordered list
- 00:04:01 we find here in the html code
- 00:04:04 that is how messages are rendered here
- 00:04:06 with inner html in the end
- 00:04:08 and therefore innerhtml of course
- 00:04:11 interprets everything here as
- 00:04:12 html so adding a html script tag
- 00:04:16 might work so if i now try this again
- 00:04:20 and i sent this message you see well it
- 00:04:22 doesn't entirely work
- 00:04:24 nothing was rendered here no text but i
- 00:04:28 also didn't get this hacked alert
- 00:04:31 if we inspect this in the browser here
- 00:04:33 we see
- 00:04:34 that inside of this paragraph indeed the
- 00:04:37 script was rendered as html though
- 00:04:40 but modern browsers know this potential
- 00:04:43 attack pattern
- 00:04:44 and defend against it scripts added like
- 00:04:47 this
- 00:04:48 with inner html are not executed
- 00:04:51 i'll show you another way a successful
- 00:04:54 way of adding
- 00:04:55 script code in a second though so just
- 00:04:58 because
- 00:04:58 this specific pattern is not possible
- 00:05:01 does not mean
- 00:05:02 that script execution like this is not
- 00:05:05 possible at
- 00:05:05 all now what's the problem with such
- 00:05:08 injected scripts though
- 00:05:10 if this would work for example well then
- 00:05:12 of course the problem would be that
- 00:05:14 in this dummy application we can only
- 00:05:16 hack ourselves
- 00:05:17 because this is a pure client-side
- 00:05:19 application nothing is stored
- 00:05:21 on a server but if that message would be
- 00:05:24 stored in a database and
- 00:05:25 other users would load and render it as
- 00:05:28 well
- 00:05:28 the script code which i injected here if
- 00:05:31 it would be executed
- 00:05:32 would be executed on other users devices
- 00:05:35 as well
- 00:05:36 and then this script code which is
- 00:05:38 rendered here could do
- 00:05:40 all kinds of bad things we could read
- 00:05:42 the local storage or the cookies of
- 00:05:44 those users
- 00:05:45 we could send that stolen data to our
- 00:05:48 own server
- 00:05:49 or we could send requests behind the
- 00:05:52 scenes http requests
- 00:05:54 on behalf of those other users we could
- 00:05:56 send a request
- 00:05:57 to buy a product with the authentication
- 00:06:00 data stored on another user's browser
- 00:06:03 without those users recognizing it
- 00:06:05 that's the danger potential
- 00:06:07 by the way i have another article and
- 00:06:09 video on
- 00:06:11 storing data in local storage versus
- 00:06:13 cookies which is also related to
- 00:06:15 cross-site scripting attacks
- 00:06:16 which you absolutely also should check
- 00:06:19 out to defend
- 00:06:20 against that you'll find a link to that
- 00:06:22 below this video as well but that's just
- 00:06:23 an extra note
- 00:06:25 so that's the problem here we could do
- 00:06:27 bad things but of course this
- 00:06:29 specific example didn't work well here's
- 00:06:32 an example that will work we have some
- 00:06:34 message
- 00:06:35 but now what about the image url this is
- 00:06:38 also output with innerhtml
- 00:06:40 and i use whatever user enters as an
- 00:06:42 image in the end here as a source
- 00:06:45 now this is just a string here this is
- 00:06:47 all a string
- 00:06:48 but in the end this string is handed off
- 00:06:50 to inner html to be
- 00:06:52 interpreted as html what if we would
- 00:06:55 manipulate the image
- 00:06:56 url such that we change this
- 00:07:00 element a little bit for example what we
- 00:07:02 could do is
- 00:07:04 we could start with an invalid image url
- 00:07:07 some page.com
- 00:07:12 no image.jpg so this url doesn't exist
- 00:07:17 but now i do something special i add a
- 00:07:19 double quote here
- 00:07:20 effectively closing off the source
- 00:07:23 attribute
- 00:07:24 right i'm just adding this double quote
- 00:07:26 here and hence the source attribute is
- 00:07:28 now
- 00:07:28 done now we can add a new attribute and
- 00:07:31 since this all will be interpreted as
- 00:07:33 html
- 00:07:34 this will be one way of attacking this
- 00:07:37 and on an image element
- 00:07:38 we can add a very special attribute
- 00:07:40 which is officially supported
- 00:07:42 and that's the on error attribute
- 00:07:45 on error wants script code it wants
- 00:07:49 javascript code which executes whenever
- 00:07:51 loading the image fails
- 00:07:53 so by using a invalid url here i of
- 00:07:57 course can force
- 00:07:58 that this loading process fails and then
- 00:08:01 here i could add my javascript code
- 00:08:04 without script text just the code itself
- 00:08:07 and this will now work if i now send
- 00:08:09 this message you see
- 00:08:11 this hacked alert and here it's just a
- 00:08:13 stupid alert because i want to show this
- 00:08:15 example
- 00:08:16 in reality we could of course do way
- 00:08:18 more dangerous things
- 00:08:20 and this is now a successful cross-site
- 00:08:22 scripting attack
- 00:08:23 again here we're just hacking ourselves
- 00:08:26 but this data could be stored in a
- 00:08:28 database and could run on other users
- 00:08:30 devices as well
- 00:08:32 so that is how a cross-site scripting
- 00:08:34 attack works and how you can launch one
- 00:08:36 finding such a vulnerability isn't
- 00:08:38 difficult and all of a sudden you have
- 00:08:41 huge
- 00:08:41 problems so how can you defend against
- 00:08:44 it if you are
- 00:08:45 a developer building a website well
- 00:08:48 there are
- 00:08:49 a couple of things you can and should do
- 00:08:52 you should of course avoid code like
- 00:08:54 this maybe
- 00:08:55 maybe you want to set the source of the
- 00:08:57 image differently
- 00:08:58 not like this in a string which is then
- 00:09:01 interpreted as html
- 00:09:02 but maybe instead the idea is that you
- 00:09:06 don't set the source and don't set the
- 00:09:08 alt code like that
- 00:09:09 but you simply select the image element
- 00:09:12 after it was
- 00:09:13 rendered anything like that so maybe you
- 00:09:15 can avoid
- 00:09:16 this approach but in addition and more
- 00:09:19 important than that
- 00:09:20 there is another step you should do you
- 00:09:22 should sanitize
- 00:09:23 all user input you're getting and if you
- 00:09:26 for example have a backend build with
- 00:09:28 node.js
- 00:09:29 you can search for node sanitize of
- 00:09:32 course similar packages exist for php
- 00:09:35 and whatever you use
- 00:09:36 and you will find packages there which
- 00:09:38 in the end allow you to sanitize
- 00:09:41 incoming content for example with
- 00:09:44 libraries like this one which allow you
- 00:09:46 to run code on your server to sanitize
- 00:09:49 incoming user input
- 00:09:51 and sanitizing simply means that the
- 00:09:53 content is
- 00:09:54 checked for certain patterns for certain
- 00:09:57 code
- 00:09:58 and it will then remove such malicious
- 00:10:00 code
- 00:10:01 from the user input so that you only
- 00:10:03 store
- 00:10:04 clean content in your database
- 00:10:07 now you'll find different packages and
- 00:10:09 you want to have a close look at all the
- 00:10:11 available
- 00:10:12 packages to find out which one really is
- 00:10:14 best for you
- 00:10:15 for example the first package i showed
- 00:10:17 here hasn't been
- 00:10:18 updated for over two years so maybe this
- 00:10:21 package is more
- 00:10:22 suitable this specific package here
- 00:10:24 could be used on the browser side but
- 00:10:26 also recommended on node.js side and for
- 00:10:30 example it detects exactly the attack
- 00:10:32 pattern i
- 00:10:32 showed you so sanitizing user input is
- 00:10:36 really important
- 00:10:37 you should have some process that parses
- 00:10:39 all user input
- 00:10:41 before it's stored in a database so that
- 00:10:44 you only store
- 00:10:45 save content in a database and therefore
- 00:10:47 even if a user does
- 00:10:49 submit code as i just showed to you even
- 00:10:52 then that code doesn't end up in a
- 00:10:54 database
- 00:10:54 and doesn't get rendered for other users
- 00:10:57 sanitizing is key
- 00:10:59 whenever you're working with user input
- 00:11:01 in addition to that sanitization
- 00:11:03 you also of course can protect on the
- 00:11:06 client side
- 00:11:07 and for example if you are using
- 00:11:09 frameworks or libraries like react
- 00:11:11 angular or vue those frameworks already
- 00:11:14 have built-in
- 00:11:16 client-side html escaping which simply
- 00:11:19 means
- 00:11:20 whenever you output user content on the
- 00:11:22 client side with those frameworks it's
- 00:11:24 automatically escaped
- 00:11:26 so that you are protected against this
- 00:11:28 as well this still doesn't mean that you
- 00:11:30 shouldn't sanitize on the server it's
- 00:11:31 just an extra layer of security
- 00:11:34 and with that you can protect against
- 00:11:36 malicious user input
- 00:11:38 there is another potential attack path
- 00:11:42 though and that's the more tricky one
- 00:11:45 this is a simple application with just
- 00:11:47 vanilla javascript
- 00:11:48 but we all know the reality in reality
- 00:11:51 we build
- 00:11:52 real bigger projects with tons of
- 00:11:55 packages
- 00:11:56 tons of third-party libraries which we
- 00:11:59 add to our front-end
- 00:12:01 react react router maybe a forum's
- 00:12:04 library maybe some
- 00:12:06 component library whatever it is we have
- 00:12:08 tons of
- 00:12:09 third-party libraries and it's important
- 00:12:12 to recognize that
- 00:12:13 all those libraries simply add new
- 00:12:15 javascript code that is executed as part
- 00:12:18 of your entire application
- 00:12:19 now what if such a library or framework
- 00:12:22 would now have malicious code
- 00:12:24 inside of it it would run as part of
- 00:12:26 your code
- 00:12:27 and therefore it would not be sanitized
- 00:12:29 or escaped
- 00:12:30 that means if you include a library that
- 00:12:34 has been compromised
- 00:12:35 that has been attacked where malicious
- 00:12:38 code is baked into the third-party
- 00:12:40 library code
- 00:12:41 then you're in great danger that's why
- 00:12:44 npm has this
- 00:12:45 audit feature which allows you to audit
- 00:12:48 your
- 00:12:48 third-party libraries that are part of
- 00:12:50 your project for known vulnerabilities
- 00:12:53 now that still of course means that
- 00:12:55 unknown ones could still affect you
- 00:12:58 thankfully a lot of projects like
- 00:12:59 angular are open source
- 00:13:01 and therefore you could of course look
- 00:13:03 into all the code which is eventually
- 00:13:04 going to run as part of your
- 00:13:06 project but in reality we probably don't
- 00:13:08 do that
- 00:13:09 now angular of course is absolutely safe
- 00:13:12 to use it's
- 00:13:13 by google they have no plans on
- 00:13:14 attacking us i would guess
- 00:13:16 but if you're using a smaller library a
- 00:13:18 smaller package it could be compromised
- 00:13:20 maybe not even because the owner of the
- 00:13:23 library is a bad guy
- 00:13:24 but maybe because he or she merged a
- 00:13:27 pull request
- 00:13:28 that added malicious code without
- 00:13:31 knowing it or without
- 00:13:32 recognizing it so third-party libraries
- 00:13:35 are potential security
- 00:13:37 issues now that still doesn't mean you
- 00:13:39 shouldn't use them but you should be
- 00:13:40 aware of that
- 00:13:41 you should use trusted ones maybe
- 00:13:45 rethink if you really need that extra
- 00:13:47 library with the animated tooltip
- 00:13:50 maybe you don't need that maybe you can
- 00:13:52 shrink the number of third-party
- 00:13:54 libraries
- 00:13:55 your code relies on as a positive side
- 00:13:58 effect you would also ship
- 00:14:00 less code to your users which also
- 00:14:02 speeds up your website
- 00:14:04 and that's really the key takeaway you
- 00:14:06 should be aware of this fact
- 00:14:08 now the bigger the popular third-party
- 00:14:11 libraries and frameworks of course
- 00:14:13 should be very very very secure
- 00:14:15 but you never have 100 security you
- 00:14:18 should absolutely defend against the
- 00:14:20 other attack pattern which i showed
- 00:14:21 earlier though
- 00:14:22 by sanitizing user input you should
- 00:14:24 absolutely do that
- 00:14:26 but in addition also reconsider your
- 00:14:28 third-party library usage and be aware
- 00:14:31 of the potential risk
- 00:14:32 you could face there and that's it about
- 00:14:35 cross-site scripting attacks
- 00:14:36 that is what cross-site scripting
- 00:14:38 attacks are why they can be bad how to
- 00:14:40 launch one
- 00:14:41 and where potential security holes could
- 00:14:44 be found
- 00:14:45 again below the video you find server
- 00:14:47 articles and videos
- 00:14:48 on that topic specifically on local
- 00:14:51 storage versus cookies for
- 00:14:53 authentication data storage
- 00:14:55 and with that i could hopefully help you
- 00:14:58 build
- 00:14:58 a bit more secure web applications