 My name's Ron, and I want to chat to you about cookies. Like most delicious things, cookies are great in moderation, but too many of them are messing up the recipe. That's bad news. Okay, so what are we going to chat about? Two bits. First, a good HTTP cookie recipe for all occasions. And second, how to work out when your cookies are going wrong. Debugging, essentially. Because discovering bugs in cookies? Gross. We'll worry about that later, though. First, let's get the recipe right. We're going to start with a base that comes from myQuest, who's really one of the head chefs of the cookie world. This cookie recipe should be your starting point. Everything else we do is going to be a variation on this. So let's take a look at it. It's a lot, I know, but it's mostly static. If you set this up as your default configuration, so it's just added automatically, your code still remains as clean as set a cookie with this name and this value. And all of these attributes or ingredients come with benefits. So let's step through them. First, that host prefix. Now, that's actually going to set up a few rules for us. It's enforcing these first two attributes, secure and path equal slash. Secure means that this cookie will only be set or sent over HTTPS connections. If you haven't fully migrated your site to HTTPS, now is really the time to make that a priority. Browsers are getting more and more functionality behind HTTPS and being more explicit in communicating to users that plain HTTP is insecure. Now, path equal slash is interesting, and we need to look at that along with another attribute that host is enforcing. But in this case, enforcing that it is not included. And that's domain. No domain means that the cookie uses the current document origin and does not include subdomains. And path equal slash means that it's sent for all requests to that origin. So if I set a host cookie for example.com, it will go on every request to example.com, but not to images.example.com. There you go. That was 3-in-1. Host prefix gives you secure, top-level path, and no domain. Next up is the HTTP only attribute. This means that the cookie will only be sent in request headers and is not available to JavaScript via document.cookie. To clarify, you can trigger requests from JavaScript like fetch or XML HTTP request. And if you've specified including credentials, cookies, including HTTP only cookies, will be sent. They're just not visible to those client-side scripts in any way. So in the event that any of those scripts on your site have been compromised or malicious, you've at least limited their access to potentially sensitive cookie data. Finally, a personal favorite, it's same site. Specifically, same site equals lax. And what same site equals lax does is restrict the cookie to only be sent on requests that match the current browsing context. In other words, the top-level site the user is currently visiting and is right there in their location bar. Putting that all together, we get a nicely contained first-party cookie. This is an ideal cookie for controlling your user session set by your server-side framework. And let's talk about why. What this gives you is some pretty reasonable protection against cross-site request forgery. The attack works like this. Let's say you have a block where users need to be signed in to post content, and that content submission is just a form submission or an API call. If one of those signed-in users visits a malicious site, it can trigger a request to that content posting endpoint with some kind of spammy or abusive content. If the cookies aren't protected, the browser may well send them. And when the blog server receives that request, it's going to look like it came from the signed-in user, and it's going to post that content with their name attached. But not with our cookie recipe they can. Same site equals lax is what's protecting us against this attack. The malicious site can make the request, but because the user isn't actually on the blogging site, the sites don't match and therefore no cookie. There are some other benefits too. The secure attribute means that we're going over HTTPS, so other people lurking on the same network can't steal our cookie. Look up Firesheep if you want to see how someone created an extension to demo just how easy this kind of session hijacking over HTTP was. Next up, HTV-only. Like we said, that means the cookie can't be stolen by malicious client-side JavaScript, like a third-party dependency getting hacked and then included on your site. Now let's talk about tweaking this recipe for your own taste. If the host prefix is too restrictive, like maybe you have a new site and you've set it up with subdomains for each topic, like finance dot and politics dot, but you still want one session across all of those. For that, you could use the secure prefix instead and specified domain. So far, these examples don't have any kind of expiry date set on them. That means they expire when the browser session ends, which sounds short, but in reality, a lot of people leave their browser open for a long time. Or I have a session restoring feature that also brings back all those cookies. Now, there isn't a default right answer here. It's down to your use case. But what I would say is if it's something short-term, like a token for a form submission, then use max age, since you just specified the number of seconds until it expires, nice and simple. If it's something more permanent, like a theme preference, then use expires and set it maybe a year in the future. I wouldn't use it for anything short-term because it's a date format, so you have to think about time zones, clock changes, incorrect clocks. It's a nightmare. I'm not even going to show you that one. Remember, you can always reset that expiry date on future requests. But then, if the user doesn't visit your site for ages, you can also ensure the browser cleans that for you. And that just seems polite. No one wants to stay on cookies. We can also use the same site attribute to lock things down a bit more, but it's really for quite specific situations. We talked about same site equals lax, which allows cookies to be sent on top-level navigations. For example, I want my session to be sent when I first visit the site because I want to see my sign-in experience. Same site can also be set strict, which means I really have to be on the site already or the cookie won't be sent. This is useful for protecting form submission. So that blog posting example, if you set up a same site equals strict cookie, pretty much the same as your session, but you treat it like a token for right permission and validate that it's included on that form submission, then you can be pretty sure it came from the user submitting the form actually on your site. Sometimes you do need that cross-site data, though. Now, by the long-term goal is to stop supporting cross-site cookies and bringing better mechanisms for enabling that functionality, we can still do some interim work to clean up those cookies right now. The really important thing is that you make the intent to send that cross-site data totally explicit. For that, we can turn the same-site dial the other way with same-site equals none. That tells the browser that there are no same-site restrictions and it can send the cookie whenever. It does require secure as well, though. No restrictions on site doesn't mean no restrictions at all. Now, even if you don't like the default recipe, I strongly recommend you move to setting an explicit same-site value on your cookies. Chrome is moving to treat cookies as same-site equals lax by default for Chrome version 80 and up with the release of Chrome 84 stable. That's around July 14th, two weeks from this initial broadcast date if you're watching this on the Premiere, or even sooner if you're already watching this in the future or in the past. Anyway, the important thing is cookies without a same-site attribute will be treated as same-site equals lax. In other words, first-party by default. If you need cross-site or third-party cookies, they must be set with same-site equals none and secure. Okay, now that's all simple enough for me to say, but I know a lot of you are maintaining legacy or complex sites where, to be honest, you don't always know how or why those cookies are being set. Told you we're going to talk about debugging, so let's do it. First, let's get our environment set up, starting with browser. Cookies are persistent, meaning that you've probably got a lot hanging around in your browser. On top of that, browser settings and extensions can also affect their behavior. Because of that, I strongly recommend testing with a clean slate. That means either setting up a new profile, use a separate Chrome channel like Beta or Canary, or using Cognito mode. Across all of those, though, make sure that you don't have any extensions installed and check your user settings to ensure you aren't blocking third-party cookies or just blocking cookies in general. Now, we can make sure the browser is enforcing the new behavior. I'm going to pop in Chrome flags here, and what I'm going to do is search for cookies. Now, the two that I want to ensure are enabled are same site by default cookies here, and cookies without same site must be secure here. There are a couple other messages in here, a couple other flags that you can set. So if you look through, you can also see this one, enable experimental cookie features. Now, what this will do is turn on all of the upcoming changes. So this is actually great for general testing if you just want to check that your site is going to behave well in the future. But when you are trying to isolate individual bugs, you can use the individual flags to toggle that behavior on and off. Now, when you've changed a flag, you are going to have to restart your browser here so that those flags take effect. Now, I already have restarted and I have a test site set up on same site sandbox.glitch.me and if you've got all the flags enabled, when you go there, you should see all this nice soothing green. Any red or orange Xs in there, go back, check your cookie settings, check your flags. With all of that configured, I'm going to walk you through this excellent debugging guide which comes from Lily Chen, one of the engineers working on same site. So don't worry if you don't catch everything I do in this video, it's all written down in there and there's a link in the info. I'm going to keep using the same site sandbox for testing. The code is all on glitch. If you expand the info again, you can find a link. Feel free to remix this if you want to run your own version or try some different combinations of cookies and so on. Let's open up DevTools and start poking around. I'm going to start on the console tab and you'll probably see some warnings but we're going to be cleaning those up. So what you actually want to look for if you're on a recent enough version of Chrome like A4 and onwards is the issues tab here. So the warnings are going to show you the same information that the issues tab does but the issues tab is much clearer, much more actionable. Sam's got a video where he goes through the full tour on that so I'm going to go through this pretty quick but let's take a look. Let's tap on go to issues. Now the first thing it tells us is that we want to reload the page to get that full capture. So let's take that advice and reload. Now you can see I've got some issues that have come up. Let's take a look. Now the first one we've got is mark cross site cookies as secure. Let's expand that and see what's going on inside. So you can see that this one is telling me that I've got a cookie that's marked with same site equals none but it's missing the secure attribute. If I scroll down a bit more I can also see I've got some effective resources so I can expand that out and that is going to show me exactly the cookie that's affected. If I click on that cookie here and see it takes me through to the network tab up here I can expand that so we can see a bit of what's going on and it's using this filter entry to basically filter that down too so you can see it's filtered it specifically to the cookie name that has the problem so it's showing me all the requests that include that specific cookie. We'll come back to the network tab in a minute so hold on to that I want to take a look at the other issue first. So back in here let's scroll down again and expand that the second issue is telling me that I have some cookies that don't specify a same site attribute at all so the browser just doesn't know what to do with that cookie maybe we're okay with it being first party but we haven't told anyone so let's take a look at the cookies that are affected in there so I'm going to expand this again and you can see I've got two cookies affected right now we know where the problems are let's go over to network tab to take a look in detail this is a pretty simple site so there aren't that many requests in reality you've probably got far more to wait through so let's look at some ways that you can filter that down what I'm going to do is right click in here and go to header options where I can enable cookies and also set cookies so this is going to show me each of the requests and how many cookies they are sending and how many cookies are being set by the set cookie header in the response the other part of the puzzle then is this has blocked cookies toggle up here now if I turn that on you can see one of our requests is disappearing so when I have this on it's filtering out all the requests that are not being altered in any way so we got a pretty good idea that it's these two that are responsible for the issues back on the table let's look at the request for the page first so tap on there and on the cookies tab over here I can see that I have one of my response cookies highlighted so I'm going to hover over there and that info bar is telling us that this is the cookie that's got the same site none but is missing the secure flag so I've got the name I've got the value hopefully that's enough for you to track it down in the back end and get that secure flag for set okay but we had another issue that was listed as well so let's take a look at the second request that's cookies.json now this one looks fairly quiet so the thing we want to do here is enable this show filtered out request cookies suddenly there's a lot more going on here now what this is showing us is all the cookies that could have been included on that request but were restricted for some reason now some of them are for the right reasons so you can see here we've got a cookie that has same site equals strict that's not included on the cross site request got one that says same site equals lax same deal we don't want it on the cross site request but then we've got these two where they've got a blank same site value now that means that the browser is treating them as same site lax and therefore restricting them this might be because you didn't specify a same site value but it might also be because you've got an invalid value in there so get into your code and look for those same site attributes and check the spelling to make sure there are no typos in there as well now dev tools is great for this kind of interactive exploration but we can also export the data for a whole series of requests this is helpful if you need to grab the data for a particular situation like maybe it's one user with a particular account type who has been able to reproduce this problem and you can't necessarily sit down with them at their machine for a good debugging session together for this we're going to capture a network log so open up a new tab and go to chrome net-export if you've been doing a whole bunch of these then you may need to click start over on there and what we want to make sure of in the options is that we say include cookies and credentials because that's what we're trying to test but just be mindful that including all of this means that you may be logging some sensitive user data so treat it in exactly the same way that you would with any other make sure that you have the consent to log it make sure that you're controlling access to that log and delete it when you're done debugging the issue okay press start logging to disk and i'm just going to save that in my downloads directory okay now do not close this tab because this is what's doing the recording but we are going to switch back over to our test site and i'm just going to reload the page to capture that behavior now in reality what you want to do is capture the entire user journey that you're trying to debug at a minimum it's got to be the section that is causing a problem but often you should probably try and start maybe from like user sign-in or wherever the cookies are being set because you probably want to capture that interaction as well okay once you're done we're going to switch back over to network tab and we're going to say stop logging now you can say like show file here and you can see there's just a json file in this directory you can take a look at it it is pretty big and it's pretty verbose so what we want to do is make use of the netlog viewer tool which is linked from this page so i'm gonna go there and i'm going to go to the hosted version here now i choose my file which is just there chrome.export.log and there we go you can see that i've got a whole bunch of information about the logging that i've just done you can see my chrome version you can see the os info what you can also see is if you dive into this where it's you've got features here you can see all the flags that i've got enabled i've been playing with quite a few of them but there's also cookies without same site must be secure embedded in there the stuff we're looking for though related to the cookies is over in the events section so i'm gonna go over here and as you can see i've got 200 events to deal with so this is pretty verbose this is all of the requests the chrome is sending kind of all of the network related events including extensions including other tabs so let's filter this down to something a bit more useful i want to type and it is url underscore request make sure there's no space after that column and there you go that's a bit more manageable you can see that there's a bunch of other things going on in there but i can see my same site sandbox requests these are the ones that i'm interested in let's find that cookies.json1 and inside of here it's this string that i'm interested in cookie inclusion status now what that's telling me is basically why a cookie was or wasn't including in the request and if i look through there you can see each of the different ones so i've got let's see what we've got in here cookie inclusion status is exclude because that same site strict that's one of the ones that we wanted excluded we've got one up here that's ck03 that is excluded because same site was unspecified so it was treated as lax this search over here lets you do quite a bit so if i want to find where a particular cookie is set for example let's say ck02 i can actually just search for that header value so set cookie and ck02 there it is and then if i just control f in here as well for set cookie there you go you can see all of the response cookies and if i look at that that's my ck02 one same site none that's missing a secure attribute on there and that's it so now you know how to debug your cookie issues and when you find them you've got the recipe to put them right remember it's all about being explicit on where you want that cookie sent we've got more on this theme you can watch age's video talking you through some of the other resources you can isolate with coop and co-op and you can also come back to see me and mod have more header related fun so thanks for watching