Web Security Challenge: 5: Solution
Transcript from the "Challenge: 5: Solution" Lesson
>> Mike North: So we're going to go through the process of adding CSRF protection to this app. And to do so, we're going to use a library that's already been installed called CSURF. It is maintained by the Express team, right. So that's the same people that make the framework. It's already installed, I'm just going through the process of adding it.
[00:00:22] The first thing you're gonna do is import the library. Again, it's been installed. So when you've got all the dependencies, you got this.
>> Mike North: So there's the library, the second thing we end up doing here is, if we go down, we're going to basically create this thing here, it is a CSRF Protection middleware.
>> Mike North: So we're gonna put that in here and I'll just leave that there. And at this point we can use this in both of the routes of interest here. We can add it to this get request and that is what's generating the form. And we can use it here as well, this is what's actually causing the funds transfer to take place.
[00:01:14] At this point now if we look at this documentation, we have the ability to get this value off of the request object, req.csrfToken. So we want to have that available inside our template. So essentially we come down here. This is not using the same. This is handlebar style but we're able to basically place the csrfToken in a hidden input.
[00:01:37] So that it becomes part of the form post data that we receive when the funds transfer takes place. You can only see this if your code that's running inside this frame, and we can pull that, right? So we will look down here. This is where the title and the accounts and all that are passed to the template and we can do the same thing here, basically passing the CSRF token along for the ride.
[00:02:06] Over here in the template for this form, we can now go all the way up at the top just so it's easy to find, just inside the form tag here. We're gonna add an input that is hidden, and it's name, I'm just gonna follow their exact example actually.
[00:02:25] Just to ensure that their library sees what it expects to see. Instead of this, we're just gonnareplace it with the equivalent in our EJS thing, EJS view library. So now when I render this form, and it's not started. When I render the form I should see an additional field added, and we should be able to kinda inspect element and see that we've done has had some sort of an effect.
[00:02:57] What are you complaining about? CSRF is not defined. Maybe it's because I called this csurf. And down here, there's a little spelling error. And there's a disk error, but when I refresh it will be fine. There we go. Okay, so now if we go to this transfers page and we inspect element on this form and go right up to the top, right under the form open tag.
[00:03:28] We should be able to see something new and there it is. This is our unpredictably changing non-reusable token. And if I refresh again, starts with vSW right now and now it's starts with LEO. It's a new value every single time. So we can go back here and now actually, let's see what we have to do for processing and protection.
[00:03:53] And maybe that it just kinda works, let's see. In process, looks like we're only allowed in in the event that the CSRF token is there. Can anyone think of how I might test to make sure that this is effective, short of going to our JS Bin? What if I just messed this up?
[00:04:13] Delete a big chunk of it, Save. Try to send $99 to that account. That's getting a little low. Transfer funds. Invalid csrf token. So now we're sort of insulated against that type of attack. Let me go back and make sure so. I hope to fix this login issue soon, but let me go back to our JS Bin for example, and I think it was this one here.
[00:04:45] Yep, and now when we basically try to run it, we should see an error of some sort.
>> Mike North: Run.
>> Mike North: Let me just make sure I'm getting the right, yep. This is the runner. I just wanna see the right errors here. There we go. So our cross-site scripting attack, sorry our CSRF attack no longer works.
[00:05:16] If we look at the actual response that the user gets from this, it's the same. This is still not a great response, by the way. You're showing a stack trace where it's telling people a lot about the internals of our system here. So you would want to basically, the best way to handle this kind of thing, especially for a CSRF token issue, Is to send the user to a page that says, basically, your page is broken.
[00:05:44] Something something, you abused the back button, please do a hard refresh and you'll begin a new request to our server and you'll get a new CSRF token. So anytime you've hit the back button and things have broken, it's probably because of an approach like this. Simply because sometimes your browser caches that old HTML, including that old CSRF token.
[00:06:05] And if you used a post request to get from one page to another page to another, that's a situation where that token doesn't work anymore, it's already been used. For a single page app the way you might use a CSRF token is to serve it up with the initial page and then every time you send a request that mutates data, when you get a response in the response header, the CSRF token is there.
[00:06:29] And you basically get that and store it in memory, so you can do the same exact thing, but. Just know that the idea of a CSRF token has nothing to do with a hidden form input or a meta tag. It is just this concept of incrementing this value over and over and over again.
[00:06:46] So whatever pattern you follow, you should be able to do the same thing regardless of which kinda app you're working with.