 Hi, I'm Joe Rosner. Um, I'm an engineer at Privatee where I've been working on, um, some mitigation techniques for C-Surf 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 C-Surf as an attack vector, how it works, um, that solutions 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 C-Surf, it's nothing new, it's this attack that we've known about for like 10 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. Uh, but people still fuck it up and there's, there's lots and lots of apps out there that, that exist and they have vulnerabilities and they're never gonna 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 underlying flaw, but you need remediation right now. So what is C-Surf? At its most basic level, C-Surf is when an attacker forces a victim to create a request on their behalf. Uh, so I the attacker force 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, 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 option and you're asking the server for some kind of restful resource. And this isn't 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 are designed for having some kind of impact where you wanna create a new resource, you wanna create new objects. Um, and, and part of the problem is that these aren't typically used correctly. Especially in, in older uh, like PHP apps and, and uh, apps that don't really have the concept of a router or any kind of uh, way to distinguish between the different request verbs, you'll see a lot of time they'll 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 um, 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 wanna bring this data along with me. And you might store things in there like uh, you know a session ID, a user ID, some information about whether or not they're logged in. Um, and so 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, you know, my cookie is set for google.com and I'm going to google.com, that cookie will be sent. If I'm going somewhere else, that cookie won't be sent. Um, and, and the cookies work cross tabs and they work automatically across tabs. So if you have 10 tabs open all to the same site, they're all going to share that same cookie. Even if they're being sent at the same time, uh, 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 see the, uh, the cookie name, the value. Uh, if there is a domain, it will be set. It's not required. Um, sorry, sorry, it is required but it's, uh, uh, the rest are not. Uh, secure is used to say that you only want the cookie to be sent over an HTTPS channel. So if the secure flag is set and I'm connecting over HTTPS, the cookie will not be sent 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. Uh, 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 the specific example, uh, 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 C-surf but it enables it. Uh, you know, C-surf or cross request, um, uh, cross set request, uh, is, is the idea that you have, you know, across sites 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, it's a bad time. Um, no matter what you do, if, if you have XSS, you will never be able to stop C-surf. Uh, it is, once, once you have that, any mechanism that you add, uh, that is a counter measure 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 going to 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 that resource 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 usable 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 to get requests that has a two and an amount. Um, so if you were to put this into an image tag, 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. Uh, you'll build like a form-based template and on your attackers control website, you'll put this in, it will post back to whatever the, uh, whatever the page is, it 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 will be really quick. It's common with phishing emails or other methods where you'll direct a 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 cores. Cores is 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 is with cores. It's, 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, stripped 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. Uh, the only other exception is if cores is enabled for the endpoint and you can put some XHR code on an attacker controlled place and get the victim to go there, um, and utilize, uh, cores for that. Uh, like I said, you know, with XSS it doesn't really matter because it's game over anyway. Um, but this is the other type you might see. Um, the cool thing about this is that no page reload is required. So when the victim does get hit, they're not going to know it, but 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 requests 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, the code 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, 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 sell myself 100 bucks, 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 had, you know, sent this over to an instant messenger or an email and got them to click on, you 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. The next example is the, uh, the form based one. I'm going to 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 as well. And then the last one is the XHR. Uh, we'll see, this is the code I had in there. Um, I'm going to go ahead and reset this and we'll refresh the page and we can see in the network tab here, uh, the XHR request went through. It sent for money from, uh, to the attacker a bunch of money. Uh, and it should be showing up here. Come on mouse, you can do it. So there's a bunch of current solutions that exist and we, we see these all the time. Um, basically, 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 going to make things so much easier. Uh, and I know that a lot of what I've been talking about 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, verify the origin. Uh, this is useful if you're doing cores specifically. Um, but it also is very helpful if you want to avoid, uh, attack or hosted pages that are coming into your site, uh, with format, uh, requests. Uh, if you're already using the safe verbs correctly, you should only have to worry about unsafe, which is why we do the forms, uh, the images. Um, maybe a little more complicated because if people are like hot linking into 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 standard and what everyone uses. If you're 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 can intercept and modify HTTP requests and responses. Um, 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 it requires, um, 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, you know, a 10 year old legacy application, 20 year 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 set 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, uh, probably solve a lot of their problems, um, for like a low hanging fruit. So what are we looking for in a solution? Um, we need this thing that can be easily added into apps, whether we're doing it at the network level in an appliance or we're doing it in the application itself. We need it to work across browsers because one of the things about C-Surf is that it's a totally client side attack when you're performing it. You're, you're attacking the, the victim, the victim's browser, not the server. Uh, so we, we need good, uh, 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's 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 your 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. Uh, 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 C-surf problem out of the box, but it will make things easier. Uh, so verifying the refer and the origin, uh, this is used, like I said, to detect, uh, permitted cores 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, you know, account.php, uh, and then I go to transfer.php, the refer is gonna have the URL of account.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 requests, but it, it could be there. These are both headers that are not supposed to be set up by JavaScript in the browser. So you can have a reasonable sense of, 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 C-surf, 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 value 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 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, you know, they're 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 the 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're 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 Mixmax that, uh, implemented something like this and, uh, they used just this technique, uh, for their core system. Uh, and you should definitely go read it if you're, uh, interested in how that works. Um, I'll cover a little bit but they have a much more in depth, uh, write up on it. Uh, and this is just a typical request. This is what I 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 straight out of, uh, 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. If it's not we'll fail open. Um, and then we, we compare the authority, uh, which is the, the host in the port and, and 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.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 what we're going to focus most of our time on. Um, is 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 come in, in two forms. You'll have synchronizer tokens which are kind of just like a, a random value and those are typically stored in the session and used for a straight comparison. Um, you'll also have, have crypto 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 you have like, you know, 50 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 AES acceleration and that's probably what you're gonna want because it's a, um, pre-shared key that you can share across all your servers. Uh, instead we'll rely on HMAC, uh, shot to, 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 gonna repeat 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 you'll go see, um, like people won't pay out bounties for like, I don't log out CSERF because like who cares if you can force someone to log out. It's not like a, a dangerous thing usually. Um, so, cost them, 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 automation, um, it's, you can work around that but it's, it's possible and it adds a little bit of, of nicety 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 of 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 knots and in the traditional type of token when you're using session storage, basically this gets stored in the session and it's then compared against. Uh, the user ID, uh, this could be anything. 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 use the session identifier, um, and because no one should have, 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 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. Uh, 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, user logs out, it's no longer valid. And then authenticity verification. Um, like I said, we rely on HMAC SHA-2 with a pre-shared 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 compromise the, uh, security of the token. Um, if you don't have an expiration time, it lasts forever. If you are not verifying authenticity, you can forge tokens potentially. Um, user ID, if you don't scope it to a specific user, you can 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 and 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 and 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 lets 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 really don't want to use crypto. It's nice because it's stateless, but the performance is usually pretty shitty 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 a user ID and a key. You grab 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 concatenate it. Uh, one thing to note here is we use hyphens. Um, 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 going to do this, don't use a colon as a delimiter. Uh, or you might have issues with Roger 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 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 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 request, you determine whether or not you have to generate a token. Uh, and you add it in if you have. Um, and the browser should take care of the rest. Uh, we'll be appending a little bit of a, a JSON payload to the response that we'll handle putting that into further requests that need to be protected. Uh, and 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 as middleware, if you're going to 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 job side of the huge pain in the ass, um, everything 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. So the token is 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 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 dependent 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 can 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 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 document and so whenever the event fires it'll bubble up and bubble up and bubble up and eventually we'll just say, is this the right thing? Do I have to fire it on this thing and we'll 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 to 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 gonna do is we're gonna walk up, uh, 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, you know, three levels deep in the DOM of a submit button or an A tag or a, um, a button and so the event's gonna 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, uh, 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 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 look, find the form that we're in. It 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 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 gonna update it, uh, and if it's not there then we're just gonna go and we're gonna append it into the, uh, into the form. And so when, when the 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 monkey patching, 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 IE 8. Uh, most other browsers are basically supported all the way back to anything anyone would use. Uh, IE 8 is specifically the bottleneck because before IE 8, uh, it used, uh, active X controls to do XHR and so because of that, uh, we can't monkey patch the code. Technically in 7 was, uh, where they moved over to XHR like the normal standard compliant version but you can't, uh, use prototype in 7 so we don't have the ability to monkey patch any of it. Uh, you might be able to, to simulate some of this with active X controls. I don't know. Uh, I didn't try that but if it's a real use case you have, it might be an option. Um, this is essentially the code we're, we're 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. It 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, uh, the original function. Uh, there's 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, 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 because 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 cores 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 older ones are supported. I just couldn't find older browsers in some of these versions. So it might work. Jump back to 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 job is just going to insert the token here and do its thing. So we'll see like all of these requests go through. Um, and it's, oh, my token's expired. Refresh this. And so it succeeded now. So 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 going to, you know, want to do some JavaScript validation on the client side, but I wanted to stop bubbling, making sure that our JavaScript code 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 going to 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 that 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. Let me get back over to here. Running kinda short on time. Um, so let's just get into the future. Um, there's this really awesome spec out right now called SameSite. Um, this is coming very shortly and it is basically, um, what we're approaching as possibly the final nail in the coffin for C-Surf. Uh, and this is an extension to cookie use. 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 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, you know, Google or gmail.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 forming, coming from like my empty tab or another tab and going to there, the origin didn't match from where I was going. I needed to do a, a page reload or you'd have to do like a, 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 like, this is like an example of a phishing attack where, uh, we might get something, uh, a link, we go to that link, it 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, um, 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 one issue with this is that it doesn't support cores. So if you have cores 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 probably it's 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, uh, or some aspect of it, uh, and I'll be posting the slides. Um, this is a pretty good solution. It hits most use cases. If, if this is the kind of issue you have or you have a lot of site changes, uh, add protection for, but you can't go modify it. Um, like I said, ideally, best case scenario, you go fix the app or use a framework that supports it for you. Do you're safe, unsafe, correctly? Uh, you'll be really happy you did. It will make things so much easier. Uh, and check out the same site. It, it might be, uh, a valid solution in the future. Uh, it is backwards compatible, so if you want to start using it, newer, uh, older browsers don't support it. We'll just ignore it. Like it doesn't exist. Newer browsers, it should work. Um, I've tested it in, in Chrome and, and got good results. Uh, but like, if it doesn't get supported by anything, it's not going to really matter. Uh, cool. Thank you.