>>Uh, hi, I’m Joe Rozner. Um, I’m an engineer at Prevoty where I’ve been working on, uh, some mitigation techniques for CSRF and this is a kind of run through of some of the research we’ve been doing and how it all works. Um, this is kind of a deep dive into CSRF as an attack vector, how it works, um, the solutions that exist currently and, uh, some new ways we can basically help to avoid it in the future. Uh, and I know what you’re gonna say. It’s 2017. Why are we still talking about this? We know about CSRF. It’s nothing new. It’s this attack that we’ve known about for like ten years. Um, what could I possibly have to add to this that hasn’t been said already? All the modern frameworks take care of this. They do it for you. As long as you play within their- their rules you get it for free. But people still f**k it up and there’s- there’s lots and lots of apps out there that exist and they have vulnerabilities and they’re never going to get patched. Uh, so this is kind of a solution that you can use for those situations where you are unable to patch it and fix the underlying flaw or you need a remediation right now. So what is CSRF? At its most basic level, CSRF is when an attacker forces a victim to create a request on their behalf. Uh, so I, the attacker, forces your browser to initiate a request that does something on your behalf and that has some action that is probably bad for you. Uh, it comes from three different, uh, conditions that exist within HTTP and those three are- are, begin with, uh, the concept of safe and unsafe request types. Um, so safe methods are traditionally designed for accessing data so you make a- a get request or a head or an options and you’re asking the server for some kind of restful resource. And this is designed to have no side effects. It’s designed to, uh, basically have no impact on the data on the server. You’re just pulling it back down and- and getting a copy of something. Unsafe requests like post and, uh, put and delete these- these are designed for having some kind of impact where you want to create a new resource, you want to create a new object, um. And part of the problem is that these aren’t typically used correctly, especially in older, uh, like PHP apps and, uh, apps that don’t really have the concept of a router or any kind of, uh, way to distinguish between different request verbs. You’ll see a lot of times they will respond to whatever is sent to them. And that’s really bad and we’ll see why. Um, usually it’s due to laziness or just not understanding it or just a lot of legacy code that never took advantage of, uh, building out to the HTTP spec. The other, uh, main issue is- is cookies. Um, and- and these are kind of a work around for the concept of- of HTTP being a stateless protocol. Um, we- we get around this by having what’s called sessions. And- and sessions are some server side storage that can be trusted, uh, that you can basically say, uh, throughout every request for this user for this session I want to bring this data along with me. And you might store things in there like, uh, y’know, a session ID, a user ID, some information whether or not they’re logged in, uh, and so- and the way that you typically implement this is on the server when you initially log in or come to the page for the first time you generate a cookie. That cookie gets sent down and that cookie has some unique identifier. Every following request that cookie gets sent up with it and the server will look up that ID, pull the data out, and let you access it. Um, cookies are- are kind of this- this weird thing that, um, we- we depend on the browser to secure for us. Um, it has some concepts of security like- like locking it to a specific domain so the cookie will only be sent if the domain matches the domain that the request is for. So if my cookie is set for google dot com and I’m going to google dot com, that cookie will be sent. If I’m going somewhere else, that cookie won’t be sent. Um. And- and the cookies work across tabs and they work automatically across tabs. So if you have ten tabs open all to the same site, they’re all going to sa- share that same cookie even if they are being used at the same time. Um, they- they- they all share that information and they’re all going to update it accordingly. And- and each tab will always send the cookie as long as it matches the required domain and path. That’s always going to- to happen. So this is an example of- of what you might see in a cookie when you’re setting it from the response. Uh, in the headers you’ll just see the, uh, this- this cookie name, the value, uh, if there is a domain, it will be set. It’s not required. Um. Oh I’m sorry, it is required but it’s uh, uh, the rest are not. Uh, secure is used to say you only want the cookie to be sent over an HTTPS channel so if the secure flag is set and I’m connecting over HTTP, the cookie will not send and that’s a security mechanism that we’ll discuss a little bit later. HTTP only, uh, is also, uh, an idea that if you set that, the javascript on the page will not be able to access the cookie. Um, we need to make sure that this is always false. Uh, typically you’ll want this to be true because it’s a- it’s a really good security mechanism that helps you avoid, like, uh, theft of cookies. Um, but for this specific example it’s not going to matter so much in this case and it’s important that it not be set. The- the last is XSS and this isn’t strictly CSRF, but it- it enables it. Uh, CSRF or cross request, um, uh, cross site request, uh, is- is the idea that you have, y’know, a cross site to two different ones. Um, but you can also do the same kind of idea from within the site if you get XSS. And so you- you can inject payloads that will make requests and have the same sort of effect. Um, in the case of XSS, like, this is bad and you should feel bad if you have it. Like, it’s- it’s just- it’s a bad time. Um, no matter what you do, if- if you have XSS, you will never be able to stop CSRF. Uh, it is- once- once you have that, any mechanism that you add, uh, that is a countermeasure to that attack can be bypassed once you have sufficient code execution on the browser. And there’s- there’s basically nothing you can do about that. You just have to eliminate the XSS. So how does it work? There’s- there’s three distinct types that I’m gonna cover and this covers the vast majority of the kinds of requests that you might see. Um, the canonical one that you’ll- you’ll typically see demonstrated is resource inclusion. Um, and by this I mean tags that specifically allow for external resources, for instance image tags, audio tags, video tags, objects. Um, when you specify the source, when the browser loads that and- and renders it on page, it’s going to call out to whatever resource that is, and try to pull that resource down. Uh. And so, for the case where you’re not using, uh, get requests correctly and you’re not enforcing the safe and unsafe correctly, uh, these can be used to make get requests to arbitrary places. In the case of, like, an image, you’ll see it show up as a broken image but that request will still get made and so the damage will already be done. Um, this specific type is limited to, uh, only get requests so if you are doing the safe and unsafe correctly, um, this technique will most likely not be useable for you. Uh, an example of this is- is something like this. Um, we’ll be using a banking demo that I- that I built, uh, shortly, uh, and so this is how a trans- uh, transfer would occur. Um, it’s the get request. It has a two and an amount. Um, so if you were to put this into an image tab you would see, uh, the transaction went through. The next is form based and, uh, this is typically what you’ll see a lot of the time when you’re dealing with people who do do safe and unsafe correctly. Um, you’ll build like a form based template and on your attacker’s control website you’ll put this in. It will post back to whatever the, uh, the- the- whatever the page is that actually does the- the request and you’ll usually have some javascript in there so that it forces the user to click, uh, and it’ll be really quick. It’s common with phishing emails or other methods where you’ll direct the victim to a page, they’ll load it, and immediately the javascript will just force a click of the form and submit it and you’ll never even know you were there. You’ll wind up on the page wherever you were trying to go to, um, and this is a really good option if you have to bypass CORS. CORS is a- a cross origin request so, um, something really important is the- the “same origin policy,” which basically dictates that, um, if you’re making like an XHR request you can’t go to a different domain than where the origin was and one way around this was with CORS. Uh, it’s used sometimes, um, but it’s a good way to avoid this. Uh, and so an example of a really basic template you might see is a form like this. It basically just has a bunch of hidden elements. So you would go in when you’re creating it and you would put in all the values you want them to submit for you. Uh, and then the little, uh, script at the bottom just causes the form to submit and they’ll never know it happened. They’ll end up on the page where the- the action is here and it will just have been done. The last is XHR and this is, uh, pretty much only ever going to happen if you have XSS on the page. Um, the only other exception is if CORS is enabled for the endpoint and you can put some XHR code on a- an attacker controlled place and get the victim to go there, um, and utilize, uh, CORS for that. Uh, like I said, y’know, with XSS it doesn’t really matter because it’s game over anyways, um, but this is the other type you might see. Um, the cool thing about this is that no pe- page reload is required so when the victim does get hit, they’re not gonna know it. Basically the only way you’re going to see it is if you’re watching network traffic or you’re in, like, the web inspector tools and you see the- the request go by. Um, it’s really difficult to detect and, like, you’re probably not going to see it. There’s also all kinds of cool tricks you can do like hiding stuff, um, like, uh, in like a real page so it looks like they’re actually at a real site or something. Um, the cool for this is actually pretty simple. Um, this is all it is. This is a basic X- XHR request. Um, and that’s pretty much it. Uh, let me jump into a demo really quick and I’ll kind of show off, uh. This is a, uh, a demo banking app. Um, basically, it allows you to perform transactions, uh, to transfer money from an account to another account. Uh, so I’m just going to send myself some money. Uh, I’ll send myself a hundred bucks, a thousand dollars. Um, and so it just goes through and it will do the thing. Um, so this is an example of an image based one. Uh, you’ll see here, uh, it’s basically just the image tag that I used before. Uh, I’ll refresh the page and we’ll now see that the request went through. We- we forced the victim to go make this transaction. So if- if I, y’know, sent this over instant messenger or an email and got them to click on, y’know, a page that had that image, it would have the same effect on them if they were logged into, uh, this bank because they had their session active still. Next example is the, uh, the form based one. I’m gonna really quick go back and reset this. If I can find my mouse. Uh, and so we end up at the transfer page. This is the JSON that comes back and if we go back to this tab we’ll see, uh, the request has gone through. Well. And then the last one is XHR. Um, we’ll see this is the code I had in there. Um. I’m gonna go ahead and reset this. We’ll refresh the page and we can see in the network tab here, uh, the XHR request went through. It sent money from- um, to the attacker, a bunch of money. Uh, and it should be showing up here. C’mon mouse, you can do it. So there’s like a bunch of current solutions that exist and we- we see these all the time. Um, bas-basically you- you want to have a combination of at least two of these. Um, all three would be great. Uh, first is using safe verbs correctly. Uh, if you’re building your app, uh, make sure that get requests don’t have any kind of, uh, side effect. Don’t let it modify data. Just do it. It’s- it’s gonna make things so much easier. Uh, and- and I know that a- a lot of what I’ve been talking about it is around the idea of fixing this in applications we can’t go in and rewrite for whatever reason. Um. This is not one of those easy things to fix, but if you’re doing it from the beginning just go ahead and do this. It’s going to make things so much easier. Go use a router and- and - and let it be nice. Um, verifying the origin. Uh. This is useful if you’re doing CORs specifically, um, but it also is very helpful if you want to avoid, uh, attacker hosted pages that are coming into your site, uh, with form, uh, requests. If you’re already using the safe verbs correctly, you should only have to worry about unsafe which is why it would be the forms. Uh, the images, um, would be a little bit more complicated because if people are, like, hotlinking into your images on your website it might be a problem. Um, and the last is synchronizer tokens or crypto tokens. This is, like, kind of the industry standards and what everyone uses. If you are using any modern framework this is what it’s probably doing under the hood. It’s creating a token and then verifying it on the requests. And a little bit of a disclaimer before, uh, we- we go into the real, like, how the- the technique works. Um, this is a greatly simplified, um, walkthrough of the code. There’s a lot of very specific domain knowledge that goes into wherever you’re going to build this. Um. We’ve built it in- in java and dot net but like you could go and you could build this literally anywhere, uh, where you could intercept and modify HTTP requests and responses. Uh. But in doing this you’re trading a lot of complexity, uh, of the platform where you have to know a lot about that and work within this really, really complicated platform for solving the problem in your app and just like doing it, um, there and probably a simpler solution but requires, uh, potentially more work. Um, so this may or may not work out of the box for you but this will be all the information that you need in order to basically implement something like this to the needs that you have. Uh, and so why is this important? Like I’ve already said, um, if- if we can’t modify the application. Maybe it’s, y’know, a ten year old legacy application, twenty year old legacy application, and we can’t do anything about it. We don’t have the source code. The risk is too high. Um, this would be a good solution, um, as a mitigation if you have a problem you can’t fix right now. Um, for bulk support across applications, if you wanted to put this at the load balancer, or a proxy, or a WAF, um, this would be a good solution for that. There’s already some that exist out there in WAFs where they’ll, uh, rewrite the forms and the responses. Uh, that’s great. Uh, it doesn’t have the effect of working with XHR, uh, and some of the other request types that we’ve talked about so far. Um, and last, if you wanted to provide this to, like, your customers if you were, like, a hosting company and you wanted to say, “Hey. All you guys that have really insecure apps running on my host- hosted servers, like, here’s some security for you.” Um, this would also be like something you could offer them and it would probably solve a lot of their problems, uh, for like the low hanging fruit. So what are we looking for in a solution? Um, we needed something that can be easily added into apps, whether we’re doing it at the network level in an appliance or doing it in the application itself. We need it to work across browsers because one of the things about CSRF is that it’s a totally client side attack when you’re performing it. You’re- you’re attacking the- the victim brow- the victim’s browser, not the server. Uh. So we- we need good cross browser support. Um, and it needs to work for XHR, for forms, and resources. It needs to be low impact. Uh, it can’t uh, take down our, uh, our servers. It can’t, uh, reduce the throughput we can do. It needs to be something that is really, really efficient. Uh. And we can't do any additional requests because there are some solutions out there. They’ll make outside requests up to the server to pull down new tokens and then get them back and then do this whole verification, like, dance and we- we want to avoid that. We want something that fits in with the standard request response that you would normally see with your application. And that’s what we’re shooting for. Um. I’ve already talked about this. Just do it. It’s- it’s gonna be so much better for you. Um. There- there’s routers for basically every language out there. They basically will allow you to define a whole bunch of endpoints and then match it up with a, uh, a verb and then pass it off to the correct, uh, handler during dispatch. Just do it. It won’t solve your CSRF problem out of the box but it will make things easier. Uh, so the- verifying the refer the origin. Uh, this is used, like I said, to detect, uh, permitted CORS requests and to detect, uh, outside requests coming into the application. And this is done, uh, by looking at the- the origin and the refer. The- the refer is, uh, one of the headers that tells the server where you were coming from. So if I’m on, y’know, account dot php, uh, and then I go to transfer dot php, the refer is going to have the url of account dot php so it can track where I was before I got to this url and how I got there. Uh, the origin header is used mostly for cross origin requests and XHR. Uh, so you may or may not see it in all request but it- it could be there. These are both headers that are not supposed to be settable by javascript in the browser, so you can have a reasonable sense of se- of assurance that these values are, uh, safe. They are something that can be spoofed if you’re making a request. But in the case of CSRF, because it’s coming from the victim, the only way you’d ever have a spoofed value there is if the victim was attacking themselves. So the values should be trustworthy and you shouldn’t have to worry about the fact that it’s not always going to be, um, accurate. It is possible that you won’t see it and, in our case, we’ve found the best way to go forward with this is if it’s not there and you can’t validate it, uh, just fail open. Uh, you might have more strict requirements, um, but on the off chance that, like, there’s running a- a privacy plugin that strips it out of their requests, um, you don’t want, like, legitimate traffic to be stopped. Uh, and that’s one potential downside to, uh, fail enclosed in this situation. Um. This can be sufficient, uh, alone if you are using safe verbs correctly because doing that should eliminate the possibility of resource inclusion attacks. So as long as you don’t have XSS and as long as, uh, you are doing this, you should theoretically be able to block form based attacks from outside. Um, I wouldn’t bet on that. Um. There’s a really good write up, uh, from this company “Mix Max” that, uh, implemented something like this and, uh, they used just this technique, uh, for their CORS system, uh, and you should definitely go read it if you're, uh, interested in- in how that works. Um I- I’ll cover a little bit, but they have a much more in depth write up of it. Uh, and this is just a typical request. This is what you would see with origin, uh, refer. Uh, their actual form is a little bit different so a little bit of parsing is required in order to get the correct data out of it to- to figure out, uh, whether or not it’s valid. The code is pretty simple. Uh. This is essentially taking it straight out of the code that we use. And basically we just look for the presence of the origin header. If it’s there we parse it. If it’s not there we fall back to the refer and if it’s there we parse it and if it’s not, we’ll fail open. Um, and then we- we compare the authority, uh, which is the host and the port and- and then that’s basically the origin. Um, we compare that with what’s in the host, uh, which is another header that you would see and that is required as of HTTP 1 point 1 so basically, like, every server on the internet now pretty much. The last is tokens, um, and this is, like I said, the most common system you’ll see. Uh, the actual solution that we’re doing this is where- where we’re going to focus most of your time on. Um, just walking through the token implementation that I’ve built, how it works, and the benefits to it over a traditional approach that you might see, uh, in most of the frameworks. Uh, so these typically comes in t- two forms. You’ll have synchronizers tokens which are kind of just like a random value and those are typically stored in the sessions and- and used for a straight comparison. Uh, you’ll also have crypt tokens which are basically a random value that’s encrypted and then the server can, uh, decrypt that and verify it. Uh, this is cool because it’s stateless so it doesn’t require having, um, any kind of shared state across your app servers so if- if you have like, y’know, fifty app servers behind a load balancer you don’t have to worry about like, redis or sharing state or- or anything or sticky sessions. Um, the solution that I’ve built uses the best of both worlds. You should basically never use the crypto stuff. It’s usually slow even with A- AS acceleration and that’s probably what you're going to want because it’s a, um, preshared key that you can share across all your servers. Uh, instead we’ll rely on HMAC, uh, SHA2 um, but we get the stateless aspect of it, uh, as well, which is really nice. Um, and so tokens are designed to basically tie a action to a specific user, uh, at a specific time and enforce that they’re not going to be repeating these and that only this user is actually performing those actions. Um, and you’ll typically see these used mostly, uh, for logged in users because the idea is that if you’re not logged in there’s not much you can do that’s dangerous. That’s not always true. A lot of the time, like, I’ll see, uh, like, people won’t pay out bounties for, like, like a log out CSRF because who cares if you can force someone to log out? It’s not like a- a dangerous thing usually. Um, so cost an- uh, analysis there, whether or not it’s worth it, um, and, like, they can sometimes be used for stopping replays which is cool if you want to stop animation. Uh, its- um, you can work around that but it’s possible and it adds a little bit of- of nicity there. So the way that they’re composed, um, typically there- there's four pieces you need to have any successful token that- that’s safe, um, and you may not see all these in the token value itself. They might be taken care of, um, in other ways. So the first part is- is the random value or the nonce and in the traditional type of token when you’re using session storage, basically this gets stored in the session and then it's then compared against. Uh, the user ID, uh, this could be anything. It- it just needs to be a unique thing that is tied to a user and that no one else is going to have. Uh, in our case we go ahead and- and use the session identifier, uh, ‘cause no one- no two people should ever have the same session ID and not be the same person. Um, but you can use anything here. Uh, in- in the case of, like, a normal session system you would typically rely on the fact that the session is tied to the user and so you get that- um, that for free. You don’t have to, like, build any kind of, um, additional check for that. Uh, there’s usually an expiration time. Um, you want these to be relatively, like, short lived so that, if someone steals it, it’s not going to be good forever and they can just keep reusing it over and over again. Uh, this is usually tied to the session lifetime, so when the session expires, the user logs out, it’s not longer valid. And then authenticity verification, uh, like I said, we rely on HMAC-SHA2 with a preshared key, um. You could do a whole bunch of different things here. Typical session implementations rely on the fact that, uh, a user can’t typically modify session state directly, so if they can’t do it, then the data should be authentic because it hasn’t been modified other than by the server itself. If any one of these is missing, you severely compromised the, uh, security of the token. Um, if you don’t have an expiration time, it lasts forever. If you not verifkit- verifying authenticity, you could forge tokens potentially. Um, user ID, if you don’t scope it to a specific user, you could steal a token from any one user and use it for everyone else, or if you were a valid user on there too, you could grab a token for yourself, then use it for other users and just kind of like force it in. This is the typical life cycle you’ll see, uh, for a client in the server. You’ll make your initial get requests, um, this is usually unprotected and then this will send back a token. That token is then forwarded, uh, in the, uh, unsafe requests either in a header or in the, uh, request body depending on the implementation that you’re using. We use both. Uh, and then on the server side once it goes back up the server will verify the token. If it’s good, it let’s it go through. If it’s bad, it fails it, like with a 403 or something. Um, I’ve already kind of talked about this. You- you really don’t want to use crypto. It’s nice because it’s stateless but y- the performance is usually pretty s***ty and, uh, you just kind of don’t want to bother. There’s better ways to do it. The generation is pretty simple. Uh, this is the code that we used to handle it. Uh, you pass in user ID and a key, you wrap a random value. Uh, you should make sure to use a secure random value here so like, from, like, a good entropy source. Um, then you sign it. You can catenate it. Uh, one thing to note here is we use hyphens. Uh, this is one of those little gotchas but the colon is actually not a valid character in the value of a version one cookie, uh, so it will force an upgrade. Uh, if you’re gonna do this, don’t use a colon as a delimiter, uh, or you might have issues with com- project compatibility. Validation is also pretty simple. Uh, you just split it up based on your delimiter, uh, and you recompute the, uh, the- the hash or the- the- the mac from the parts, and then you make sure that it is not past the expiration time. You verify that the user is correct and everything is cool. Uh, that is a valid token. Uh, so the way that we handle, uh, putting the tokens into the- the- the client browser, um, basically we use middleware and various other, uh, systems whether- wherever you’re- you’re doing your interception. And you basically just look at the requests, you determine whether or not you have to generate a token, uh, and you add it in if you have, um, and the browsers take care of the rest. Uh. We’ll be appending a little bit of a- a JSON payload to the response that will handle putting that into further requests that need to be protected. Uh, and ther- there’s a lot involved here that you may not be aware of. Uh, there’s all kinds of, like, weird, uh, edge cases with regard to uh, like, dealing with the request coming in. It’s like typically it’s middleware if you’re gonna read the body of a request. Like, if you read it in, there’s no more data on the wire, so you have to buffer that and then expose it, and, like, on the java side it’s a huge pain in the a**, um, everything with it is different and this is like that complexity thing I mentioned about you have to trade off a lot of domain knowledge here to make sure you do things right and you don’t break the app downstream, um, giving it something it doesn’t expect. Sending tokens back. This is like the real innovation and, like, where, like, the bulk of the work went into was building something that could take the tokens out of the cookie that we sent down and send it back up in a secure way that allowed us to put it into basically any kind of request tha- that needs to be protected. Uh, we’ll be talking about two different forms which are, uh, form based and XHR. Um, I’m not going to touch resource inclusion because there’s not really, like, a good way to do it. You can use some weird techniques and I’m happy to talk about it later, um, but it’s going to be kind of error prone and very dependant on your site. If you’re using safe and unsafe verbs correctly this shouldn't be a problem for you. Uh, and I did a ton of browser testing across all this work, uh, and I’ll show the matrix. It basically works back to, like, ancient browsers so this should be pretty good. Uh, and you could probably get it back farther even, um, if you wanted. Um, so the way that it works for forms is basically on document we’re going to attach a- an event listener and we’re doing it on document and not on the form itself because the form may not be rendered yet on the page and we have to ensure that, uh, we can get to it at any point in time. So we- we delegate from documents and so whenever the event fires it will bubble up and bubble up and bubble up and eventually we’ll just say “Is this the right thing? Do I have to fire on this thing?” and it will do whatever it needs to do and we can walk through the code for that right now. Uh, so this is what you would see in your, uh, your click handler and it’s important that you use click and not on submit because submit does not bubble but click does. So if you were to, uh, try to attach it to document for submit you’ll never see your event fire. Uh, and this was tested across browsers and we didn’t see bubbling in any of them as far as I remember. Uh, so basically we- we set our target and the target is the, uh, the element that was clicked on. So this is the HTML element that the event was fired for. And what we’re going to do is we’re going to walk up t- the dom trying to find one of the, uh, elements that we care about, uh, delegating to. And we do this because you might click on a span that is, y’know, three levels deep in the dom of a submit button or an A-tag or a button and so the event is going to fire on that span but not the actual thing you care about that’s gonna do the submission. So we need to walk up until we find it. And it’s possible that we won’t find it. We may get all the way up the dom to the very top and we’ll see nothing and in that case we just don’t have to worry about it. We’re not inside of, uh, a form or anything and so it’s not something we have to worry about. From here, we’re gonna look at the type, um, if it’s a- if it’s an input we have to make sure that it’s a submit and not like a- uh, like a text input or something. Uh, this is just a bunch of edge case code that basically finds out whether or not it’s something we care about. Uh, from here, we know we’re in an element we care about but we then need to go look up the form. We have to go find the form that we’re in. You might have more than one form on a page but luckily we’re in a tree so we just continue to walk up and we’ll either hit the top- we’ll either hit a form or we’re gonna hit, uh, the top of the dom and then we know we can just stop wo- worrying about it. If we’re in the form we’re good. From here we’re gonna determine if a token already exists in the form. Um, we’re gonna look it up by the thing that we’re inserting. If we find it, we’re gonna verify that the value of that token is valid. It’s the one that’s in our cookie. If it’s not we’re going to update it. Uh. And if it’s not there then we’re just going to go and we’re just going to append it into the, uh, into the form. And so then when they’re actual request happens the form data will be sent with that token. For XHR it’s a little bit different. We’re basically gonna be monkeypatching, uh, XHR to rewrite the open send, uh, methods and add some additional code that we wrap. Uh, and this allows us to have some additional functionality like adding in the token value into the headers. Uh, this is specifically, uh, bottlenecked at IE8. Um, most other browsers are basically supported back to anything anyone would use. Uh, IE8 is specifically the bottleneck because before IE8, uh, it used, uh, activeX controls to do XHR and so because of that, uh, we can’t monkeypatch a code. Technically in 7 was, uh, where they moved over to XHR, like the normals standards compliant version, but you can’t, uh, use prototype in 7 so we don’t have the ability to monkeypatch any of it. Uh, you might be able to- to simulate some of this with activeX controls. I don’t know. I didn’t try that. But if it's, like, a real use case you have that might be an option. Um, this is essentially the code we- were writing. Uh, it's important that this runs early on so you want this code to execute. And basically we’re gonna save a- a copy of the original send and open and we’re going to just overwrite it with our own that goes in and grabs the token and then inserts it into the header. Uh, and this is a header that is, uh, valid to write to as javascript. And then we just call the original, uh, value. Oh, the original function. Uh, the special toggles you might care about. One is the Secure flag if you want to make sure HPS is- is all chill. Uh, protecting safe verbs, if this is something you have to do, you’ll have to enable this and you do this by basically creating an exclusion list. And this list is safe URLs you can go to. So, like, initial page loads you can hit where you can get a valid token ‘cause otherwise all your requests will fail as an invalid, uh, token because it won’t be there. Uh, and then whether or not you want to allow cross origin requests and what those permitted origins are going to be. And this gets layered on top of your CORS config. This is the browser support matrix. Like I said, IE8 is the bottleneck, but, like, you can see here like everything is supported. I mean, like- and in some of these cases it might be that some of the older ones are supported. I just couldn't find older browsers in some of these versions so it might work. Jump back to, uh, the browser. Uh, this is like a demo site that I put together. And it basically walks through a whole bunch of different use cases where, uh, you might need to see whether or not this would work. So in this case, this is like a normal form submission, um, and the javascript is just gonna insert the token here and do it’s thing so we’ll see, like, all of these requests go through, um, and it’s- oh, my token’s expired. It refreshed this. And so it succeeded now. So it- it did the check and it failed because, uh, my token’s like over an hour old at this point. Um, and so, like, this is, uh, it’s like mock validation with bubbling off. So if I was gonna, y'know, wanted to do some javacript validation on the client side, but I wanted to stop bubbling, making sure that our javascript will still run after the callback that they registered fires. So all these different weird edge cases. Just making sure that it works. Um, this is all going to get released so you can use this to verify whether or not your solution is functioning. Um, same idea but this has bubbling on. Um, preventing defaults. So what- making sure that our stuff’s still gonna fire. Um, this is non form based XHR. Um, this is a button submitting a form. So you click the button. The button has a callback. It then hits submit on the form rather than using a real traditional input element. Um, this is inserting a form. So making sure that the form isn’t rendered on page on page load so that we do actually delegate to document and we’re not firing on something that was there from the beginning. Um, and this is an anchor tag. So being able to overload the behavior of a link and make that do something else. Um, so just a whole bunch of different edge cases that you might run into. And verifying this actually does behave in the way you expect it to and that you can actually insert these tokens and have it verify for, um, everything. Make it back over to here. I'm’ running kinda short on time, um, so let’s get into the future. Um, there’s this really awesome spec out right now called “Same Site.” Um, this is coming very shortly and it is basically, um, what we’re approaching as possibly the final nail in the coffin for CSRF. Uh, and this is an extension to cookies. It basically allows you to specify, um, an origin in your cookie, um, or it uses your origin and will only send it if it matches. So there’s two different ways you can do it: lax and- and strict. You probably only ever want to use lax because strict will probably fail a lot for you. The difference being that, uh, strict will fail on safe requests where lax will not. So if you're say, going to a page that requires a cookie being there and it’s a get request, so like I’m going to the initial, y'know, google- or gmail dot com and I’m already logged in, that request would fail because my cookies wouldn’t be sent with it, uh, because I was coming from a different origin to that page because froming- coming from my empty tab or another tab and going to there, the origin didn’t match from where I was going. Uh, and you’d have to do, like, a page reload or you’d have to do, like, a redirect to make it all happy. So lax is probably what you want. Um, it’s fully client side which is the coolest thing. There’s no tokens required. It basically does what you’d get out of this, um, by securing the session data itself rather than, um, relying on a token to make sure that, uh, it’s coming from a trusted origin. Um, so we can see here, this working. We- we send our initial page request in, um, and it comes back. We make some requests and it’s all good. Um. So look, this is like an example of a phishing attack where, uh, we might get something, uh, a link. We go to that link. It dr- spawns and that sends us out. Um, here you would normally see the cookie go across but it’s- it’s not gonna happen, um. And then this is the browser support matrix, uh, for Same Site. As you can see, it basically is supported on nothing right now. If you’re using Chrome, you’re- you’re cool but uh, nothing else really supports it. Um. So the- the one issue with this is that is doesn’t support CORS so if you have CORS as a use case, uh, you probably won’t be able to use Same Site. I talked to the authors of the spec and they didn’t really have a good answer for me. Uh, so it probably is not going to happen and there’s going to be, um, nothing that happens to make that solved. It just doesn’t really work with,uh, this type of system. Uh, so that’s it. Um, this is the solution that, uh, we’ve been working on for the last year or so. Um. The code will be up or some aspect of it. Uh, and I’ll be posting the slides. Um, this is a pretty good solution. It- it hits most use cases if- if this is the kind of issue you have or you have a lot of sites you need to just add protect for but you can’t go modify it, um. Like I said, ideally, best case scenario you go fix the app or you use a framework that supports it for you. Do your safe unsafe correctly. Uh, you’ll be really happy you did. It will make things so much easier. Uh, and check out Same Site. It- it might be a- a valid solution in the the future. Uh, it is backwards compatible so if you wanted to start using it newer, uh, older browsers that don’t support it will just ignore it like it doesn’t exist. Newer browsers it should work. Um, I've tested it in- in Chrome and got good results, uh, but, like, if it doesn’t get supported by anything it’s not gonna really matter. Uh. Cool. Thank you. [applause]