Check out a free preview of the full Web Security, v2 course
The "Implementing a CSRF Attack" Lesson is part of the full, Web Security, v2 course featured in this preview video. Here's what you'd learn in this lesson:
Steve demonstrates how a malicious user can exploit an application by sending a link that triggers a form submission and transfers money without the user's consent. He then explains different strategies for protecting against such attacks, including the use of same-site cookies and the distinction between sites and origins.
Transcript from the "Implementing a CSRF Attack" Lesson
[00:00:00]
>> Steve Kinney: So let's go ahead and let's try it out. So I got another example in here. I'll do npm start again. And this time, we're gonna go into the sea-surf-bank. And we'll open that one up.
>> Steve Kinney: I just do my, let's put my Chrome tools back. And let's go to localhost:6000.
[00:00:29]
All right, so yeah, obviously, that login form looks shockingly similar. It's almost like the same person built all these little example apps. Okay, so this one, for reasons that I hate myself for now in 2020 hindsight. Nope, that's the cookie-jar one. Let's see what our users are. I wrote this one while my son was watching Adventure Time.
[00:00:51]
So they are Adventure Time themed logins, which I regret in 2020 hindsight, when I could have just did user, password for all of these. But here we are. All right, so we'll be finnthehuman. And we'll go in, and this password is adventure.
>> Steve Kinney: Great, as you can see, finnthehuman has an account balance of $1,000, awesome.
[00:01:17]
And you could choose to transfer. This is basically a very naive version of the INJ example that we saw earlier, right? And they can choose to send $10 to princessbubblegum, right? Transfer successful, they now have an account balance of 990, right? Great, that's neat. That's intended code, right?
[00:01:46]
They're logged in, they're doing their thing, they're coding, and then they realize that somebody sent them a link to a dank meme. And when I'm working, I enjoy the occasional meme being sent to me. And they will go, it would theoretically be on a different domain, but it doesn't actually have to be.
[00:02:05]
And so it's to /evil. Now, if I look at evil, I'm like, okay, whatever, like it's actually malicious, it's the template. It's got a meme, it's got an image, it's got a form in there. I don't see that. And a lot of times, part of the trick is to try to intercept the request so that you don't see it.
[00:02:27]
This one is going to submit the form fully. And so I clicked on it, I don't see the meme at all, right? But I see accepted, that's weird. And I go back, my account balance is 740, right? What happened? And if we look, this could be hosted on a totally different site.
[00:02:48]
There's a form id take-the-money-and-run, and it's submitting a form, transferring the money, and then submitting the POST request from my browser. And the browser is following the browser security model, right? It's like, hey, that's a POST request. All right, let me go make it. I'll send the cookie cuz even I'll send the cookie that goes along with that domain.
[00:03:13]
Sounds good, right? And the request goes off and the thing happens, right? Now, this is where some of that SameSite cookie stuff can theoretically help us, as well as a few other techniques. And if the answer is which one should I use, you are asking the wrong question.
[00:03:29]
Cuz the answer to which strategy you use to protect your customers, the answer is all of them. In case you have a booboo or someone finds next one nobody knew about, or something along those lines. One of the reasons why companies have bug bounties is the ones that are obvious don't get a lot of money.
[00:03:50]
The ones that are $10,000 are really like, right? And you don't have enough money for bug bounties currently. Someone just took 250 from your account. So one way that we can solve this is going back to looking at the cookies. And we kinda talked about this a little bit before, but let's do it a little bit more now.
[00:04:09]
We've got SameSite=None, which is just always send the cookie, right? So this was the case, well, actually, see the time one second, in browsers up until very recently, this was the default, right? And as you can see, it allows attacks like that to happen, which isn't great. Now, you have to opt in to SameSite=None.
[00:04:33]
You're like, who would opt in to SameSite=None? Ad trackers. [LAUGH] If you're wondering, who wants to set a session and have it follow you around, sending a request from all over the Internet, it's ad trackers. So theoretically, you're like, why isn't this locked down more? It's almost like the people who make browsers also sell ads, I don't know.
[00:04:56]
And so then now they default to SameSite=Lax if you don't put anything in there. You can opt for SameSite=None, which it might happen on this slide, we'll see. But then it will only work on HTTPS. So at least if they're getting sent all around, they have to be encrypted, right, which did break a lot of ad trackers.
[00:05:18]
SameSite=Lax is now the default. So it allows cookies to be sent with top-level navigations and if the request method is safe. Now, pay attention to that cuz safe is a relative term. It means that the POST stuff won't work if you have SameSite=Lax cookies, but GETs will. So that Twitter one and the Netflix one, still on the table.
[00:05:41]
And there's some nuance to what a top-level navigation is, stuff along those lines. But let's assume that a top-level navigation is the user typing in a URL. Anything where you see the URL change in the nav bar, that is a top-level navigation. If it's a AJAX request or a website or, honestly, even in cases like an image or something along those lines.
[00:06:07]
Then in that case, no, right? So it's a pretty happy medium. And then SameSite=Strict is only if it's literally on the page for that site. But that also includes, if I was to send you a link to, let's say, Facebook does not have it set to strict, right?
[00:06:27]
Almost no social media site does for the reasons I'm about to explain, but your bank might. SameSite=Strict is even if I send you a link in iMessage or WhatsApp or Signal, whatever, and you clicked on that link and it wasn't from you navigating from one page on the site to another, right?
[00:06:44]
Your cookie would not be sent and you would get the login screen, right? And so now someone wants to send you something on Facebook Marketplace. And even though you're logged in cuz you look at your doomscrolling, you get a login page again, right? Not a great experience, and this is, of all the things, the safest option.
[00:07:02]
And maybe if it is a bank site or the company dashboard or something important, yeah, I don't care if you have to log in 7,000 times, right, from a whole bunch of edge cases, deal with it, right? But if it is like, I would like people to use my app and not hate me, Lax is probably a decent option and None is irresponsible.
[00:07:27]
But this now gets into the difference between a site and an origin. And this is why the web is weird, right? Cuz cookies, I think, predate the same origin policy by a year, right? And so a site and an origin is different. You're like, aren't they just based on the URL?
[00:07:47]
Yes, so we kinda mentioned this before when we're talking about SameSite cookies. A site was previously, you could have schemeless ones, at which point it was only the top level domain, com, net, jp, what have you, io, plus one more level. And if those two things match, then you're the same site, which means all subdomains are fair game, so on and so forth, right?
[00:08:16]
Recently, you could have a schemeless one, where the HTTP versus HTTPS didn't matter, which is a great way to trick someone to go to HTTP version, right, and send them a cookie unencrypted. Nowadays, browsers did make a breaking change, right? And the schema is included regardless, which is different than an origin, which we said before was that host protocol port tuple, right?
[00:08:43]
So the origin is all of these things. The site is a subset, which means if something is a cross-origin request, it is also not the same site, but you could have something that is a different origin. Yeah, it's like things could be different origins with the same site, but if it's different sites, then it's different origins, right?
[00:09:05]
And so that tiny nuance, cuz a lot of times our heuristic is like, you all, if I can't set local source in the same place, right, then clearly, my cookies must follow the same rules. And it's kinda almost, most of the time, except for when they don't. And those are the areas in which they're kind of just following the rules that we've been told about how the Internet should work can hurt us in some cases.
[00:09:28]
Like we said before, top-level navigation is anytime the URL changes. And so those are fair game with the Lax settings, safe operations as well.
>> Steve Kinney: Not AJAX request, basically, the user had to do something. And actually we'll see headers later on where on the server side. Nowadays, modern browsers, there is part of the HTTP spec that gives you a lot more information about what is making the request, right?
[00:10:01]
So for instance, nowadays, the browsers have all agreed on them. This is not part of the tech, HTTP, it's a specification of standardization. There are things where you're like, are they looking for an image to the web worker? You can get a little more nuanced and you can write your own kind of like filtering logic server side that the browsers will, all of them, between Firefox, Safari, Chrome.
[00:10:26]
And, let's be honest, Edge and Brave versus Chrome, and on iOS, Chrome and Safari, it's hard. But you can get these known headers that we'll take a look at later that will give you more information as well. But generally speaking, the browser won't even try to send them if it's an iframe or an AJAX request if you don't have those things properly set.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops