 Yeah, and I've got me notes. Got me notes. Got me notes. So I don't get it wrong, although hopefully I won't need them. I love my notes, mate. I know. This might be a really long episode. Oh dear. Shall we do this? What? This voice comes from? No, if the episode is really long, just play it faster. It's way faster. I mean, I don't want to play it all the time. I want to play it fast. And I want to play it fast. I want to play it fast. I want to play it fast. And I want to play it fast. I want to play it fast. I want to play it fast. OK. I want to talk about cross-origin fetches. Oh, God, I'm bored already. I know. I know. I deleted a lot of these slides because they were really boring. So hoping what's left is not. But these are the things we're going to look at. Cookie surf course, corp, corp, corp. Yep. Well done, actually. If you're playing this in fast motion, you'll miss that a lot. Do they do this on purpose? Well, how they use four letter C words for the worst things. Yes, I think that probably is intentional. So chorus is a four letter word. Yes, it is. These are all C bombs. Cookie isn't. But why is this one never mind? Never mind. That's what I say. We're going to go back in time. This is 1993. This happened. Oh, this guy, this was a new thing. This was a new thing at that point. Yes, this is in Mosaic. The image tag arrives. And I think. I hadn't touched a computer at this point. Well, I was nine. So I had, but not on the internet. I wasn't allowed on the internet at that point. Also, no one in Colorado where I grew up knew what the internet was. This was a community that found tinfoil to be too technologically advanced. Anyway, image tag arrives in Mosaic. And I think I've done so much research into this. And I'm still not confident. But I'm going to say it anyway. I'm just going to go full confidence. This was the first sub-resource the web ever had. Like as if the camera would correct it like Jacob. I was waiting for someone to crawl out of the camera and go, um, well, actually. There was this weird SGML anyway. There probably was. Yes, first sub-resource. That landed. And also interestingly, oh, look at that. It can be cross-origin. What's the concept of an origin even established? Nope. So at the time when they would have said different domain, I guess. So if Facebook existed, they would be leaking? Yeah. Well, we'll get onto that. We will get onto that because they weren't leaking a lot at the time because cookies hadn't been invented yet because they came along in 1994. This is Netscape 0.9 beta that arrived. Look at that research number. I know. I didn't even look at the notes for that. What? Do you know what motivated cookies? State. State and HTTP. So things like login, because it was entirely stateless before that, but it wanted some way to know that to the user. Except cookies are sent every time. It's still stateless. Is that not state? I mean, the protocol is stateless. You send state with the stateless protocol, but so that the protocol doesn't have to hold it. Fine. Fine. OK, I would count that as state. Shut up. Right. Next year, 1995, look what lands. Look at all these sub-resources. All these sub-resources, but importantly, script. So this is Netscape Navigator 2. How many people would notice this is frame and not iframe? Yeah, it's a frame, not an iframe. I've not used a frame for so long. That was the only thing I ever used. Like, when I was a kid, playing with HTML, loved it, always had the sidebar, the sidenaf, in a frame because you could drag it. And it would stay there. Yeah. Yeah, it was perfect. And then your URL at the top never changed, which was useless, but never mind. Something bad had happened at this point. One of probably. You started saying yo? Yeah. It was actually because if I had more. You're going to see some more code coming down here. And so I needed something short to put in there. So that's why that is. But the web made a huge mistake here. Probably one of the biggest mistakes in the design of the web we ever made. And it's right here. And it's that no matter what site is containing these, the cookies, for example, dot com, will be sent with these requests. Right. And that was a big problem. And it was a problem that we continued to make for a series of other elements as well. I see, here's your problem. Yeah, there you go. One more letter in that overflow. Why wasn't it a mistake, Jake? We'll get onto that. Oh, OK. But it wasn't just a mistake for sub-resources. It was also for some kinds of navigation as well, because this would be sent with the cookies as well. Now, that I can see as a mistake, because I can send someone to a random form and suddenly delete their bank account or some crap. That doesn't seem good. That seems bad, doesn't it? It does seem bad. But this is how all of this stuff was built. Right. Big mistake. And we'll go through some examples of the horrible things that can happen. But I do want to acknowledge that things were starting to go right at this point as well. So we had these frame objects, right? And these frames would tell you about the images on the page, the forms on the page, the links on the page. So the basic JavaScript we had back in 1995. But they decided that you would only be able to access those properties if you were on the same origin as the parent site or whatever. And the origin was decided to be scheme, host, port number. There we go. So things were starting to become good. They were thinking of the projections that they should have thought of back at the start. Look at this. I have never written these lines, but I have. ActiveX I remember as being the source of many evils. This is XML HTTP request. This is the first version of it. This is what it looked like. It started as an ActiveX object. Oh, yes. Yeah, you used to have this horrible try catch thing just to find the exact, the correct string of that that you needed. Because there were multiple versions of this anyway, whatever. It was horrible. But yeah, it did eventually get standardized. And it took a long time, never nine years, before we started to get cross origin of these. And so this was the change. We had XHR and other browsers long before that, but this was the cross origin one. With cookies, without cookies? Wow. Wow. So I'm going to fast forward to modern code. Yeah, because it all worked the same. Look, it's nice. That's nice. And they decided that for this to work, it would have to be an opt-in system. They don't want you to just be able to opt-in by the site providing the data, not by me, the person who writes the code. Yes, because they didn't want you to just be able to go and grab someone's emails or whatever, the same problem with the frame stuff. So you needed this to be an opt-in system, and that opt-in became cause. And what it involved is the other side sending this back, that header. And there you go, you can now access the data. So they're saying everyone is allowed to read this resource. Yes, exactly. But like you picked up on before, the request would be sent without credentials, which is cookies, right? Cookies and some clients that serve it. Can the site opt-in to also allow with credentials? Yes, it can. So you would do something like this, do the same existed on XHR, but you would need this access control, credentials true, and your access control allow origin. You couldn't you start? Can't you start for this? It has to be the origin. But sometimes, so this is obviously headers in the response, which means the request has already been sent, processed, and a response has been sent, which could already have done damage. So these are the slides. You're not talking about the slides I deleted from this, because I thought they were boring. No, no, but you're right. So the way it was decided when this was invented is like, we don't need to worry about the request if it's already a kind of request that the browser can already send. Right. So this, like a requested there with credentials, it's an image tag. You can already do it. That's true. A post request, you can do that for the form. And there's also rules around the kinds of headers you can use. So for content type, the content type can be for the body of the post. It can be URL encoded, the X URL. I can't remember it off the top of my head. The thing, the long thing. But you can do that with forms, for multi-part. I just remember once you deviate, you go into the whole pre-flight request thing. We're not going to talk about it, I'm guessing. Content, you know. So yeah, if you deviate, there's a pre-flight where it has to go and ask first, can I make this request? Yeah, absolutely. Interestingly, you can do a post request with the content type text plane. And that's fine, because you can already do that with the form element. Oh, they can. Yes. No. Yes, this is like, I always forget about this. The encoding for form data text plane is. That's how I used to send emails to myself. It's just like value equals or key equals. Which is almost entirely useless, because if you have it, because of the line break separated, but your form values can have line breaks, so it's impossible to parse. True. Yeah. So, but it exists. On my pages back in the day, I would have a contact me form where you send emails to me, and I would use that. Yeah, then a CGI script to do it. Yes, absolutely. But the point I want to make about this is, yeah, you have to. CGI script, mail, too. Oh, with the body of. Yes, fine. You have to send the origin back. The exact origin, not star. You can't do star if you're doing credentials. Interesting. So how would you get this? Because how do you get this taken? From the request, right? From the request. Now, at the time, we had the referre header. Infamously misspelled referre header. The misspelled referre header, but also the often absent referre header. True. Because internet safety software. Actually, I'm not even going to do that, because this is actually a good piece of safety. Like, leaking the path of where you were on the previous site is actually quite privacy invasive. Or could. Yeah, it could contain. Because it could have your user names, account number, user numbers, all of that sort of stuff. True. So a lot of this software would just remove the referre. Yeah. But then that means it's useless for this. True. So we invented a new header origin. And that's sent with the request. Right. So it doesn't have all of the path data that would be leaky. It just says the origin came from. Was this header invented as a response to this problem? Yes. That's interesting. Yeah, it is exactly that. So that exists on cause requests. And that's how that works. I think it exists on pretty much any request now. We'll get onto that. So the point I want to make about this, I want it to get here a lot quicker than we have. But here we are, is that adding this is almost always safe. Almost always. And yet almost nobody does it. Yes, more the pity. So when these requests are sent without cookies and stuff, the question we get a lot is, well, why do we need an opt-in if it's sent without cookies? Yeah. And the problem is, intranets, because they're not protected with cookies. True. IoT devices all around your house. A lot of people will run dev servers that have seek. Ah, yeah. Right, and so you don't want visiting a site for me to just be able to go to 127001. Yeah, go to my router's web interface and do shenanigans with it. Exactly, yeah. So this is almost always safe. Except when it isn't. So the rule is, I would say the rule is, go to the URL in a incognito tab. So there's no cookies there, and look at it. And if you are happy with the world seeing that. From your phone on mobile internet, really. Well, from whatever connection that you can access it from. So if you access your router and it says your name on it in an incognito tab, then you're like, I'm going to have you with that. So it shouldn't have this header. But if you're happy with the content and the source, you can put that header on it. It's the vast majority of the web. But nobody's following that guidance, Jake. Because we're trying. That's why I'm saying it right now. Like, I'm hoping that everyone's going to go, oh, I'm going to add it to all my stuff, you know? Nobody is. Let's be real. Right, let's get back to these. So I was saying that this is a huge mistake for the web. Yo. Yo. Yo, what up? This up? Am I cool? Am I cool now? Oh, man. If you weren't already white, it would be so much whiter, right? Impossible. I feel like I'm going red. I'm embarrassed. Right. So we've got this problem here, that you've got a URL that gets the current user's avatar. Now, I can, through a load event, detail if this loads. And by that, I can determine you are logged into example.com. Bad. Oh, yeah. OK, I see where you're going. So this is a sort of convention. Dasho. Dasho. Hello. Dasho. That's my rap name. So yeah, we've got Dasho. The original avatar the user uploaded. But then from that, I can get the width and height, and now that's user-identifiable data. Potentially. Because that's more likely to be unique than the other stuff if it's the original version they uploaded. This is all leaking of data that shouldn't really happen. But it does, thanks to these bad mistakes that were made. And we're only recently starting to fix some of these. I mean, it's a hard problem because backwards compatibility is like one of the uppermost goals on the web. Absolutely. So just breaking that will probably break or changing that will break a good amount of existing sites. Oh, will it? Oh, will it? So this is one of the fixes you put in your cookie. So this is how the site would deal your login cookie. So you got a session ID or whatever. Look at this. Lacks. Same site lacks. And what this means is only send this cookie if the request came from my site. OK. So that means it would not be sent with this. If this is on evil.com or whatever, the session cookie would not go along with this. So this would always fail to load. Or you'd get generic avatars. But now that site has been broken, which is something. Well, only if it expected to be able to display avatars on other sites. Which was reasonable to expect, right? Some, maybe. But then, well, I would say not, right? You don't want a single URL to deal out your avatar because you're logged in. Because it's an information leak. There are cases where you want that. In which case you need to do something else. And you probably need to change your code right now. Because Chrome 80 made a change. Oh, yeah. We decided that if this says nothing about same site cookies, we are going to assume same site lacks. Yeah. Actually, no. We filmed this episode a month ago. And a lot has changed in the world since then. This cookie change that we're talking about actually broke a few important sites, like government sites and shopping sites. And we felt like now, especially, is a bad time to be doing that. So we've actually rolled the change back. We're still going to be doing it eventually, but we've rolled it back for now. Check out the link in the description for more details on that. And in the meantime, back to the episode. So that means, yeah, if you have one of the service where you want people to be able to look, it's not going to work unless you go in and say same site. Doesn't lack a sense for relaxed, like the. Yes, it does. So there is also an even stricter version. There is a stricter version. The stricter version works for navigations as well. So even if you navigate from site A to site B, it will not send site B's cookies. Interesting. That's strict. So if I have a link, like here, go to GitHub and you press the link. You'll be logged out if they use same site strict. Interesting. Which is why lacks is really the simplest one to use unless you want to go above and beyond for some certain bits and pieces. So yeah, Chrome made this change Firefox as well. But same site cookies in general, well supported across all of the browsers. And it also solves this problem, which you mentioned earlier on as well, where I can have a form and I can submit it. But even though this is a full navigation, it won't send those cookies even if this lacks. It's fine. But what if you can't do that for some reason? What if you can't change your cookies or whatever? How can you protect yourself from this? This is surf. Yes, with C surf tokens and stuff. So you can use the tokens. It's hard. It's annoying. There is a way you can do it in modern browsers, I mean, for quite a while now. There's much easier ways. Another thing you sort of alluded to, this header. This header was originally designed for calls, but we've started adding it. Well, we've since added it to lots of other requests. I don't think I've ever seen one without it, to be honest. Get request. The first navigation. And all get requests. If a cause get request will have it, all of the get requests won't. Interesting. The reason is, backwards compatibility, there was enough servers out there that were using the presence of this to decide it was a cause request. Of course it did. OK, sure. Yeah, sure. Exactly. So it's added to post requests and all of that. It's just non-cause get requests don't have this header. Right. But it doesn't matter because it was a post. You're fine. So you can just check to see that this is the origin on the code for your post handler. You say, let's have the origin header. And if so, not doing it. Exactly. Yeah, makes sense. And that's a nice, easy way. You don't need all the tokens and all that kind of stuff. Nice, easy way. Another example. So again, I can use the load event to know that you work at example.com. You are in a position where you have access to the internet because the logo loaded, didn't it? It did. And this is not something that's typically solved with cookies. A lot of intranets assume they're safe just because they're on an internal network. They're not, but they do. So here I'm detecting quite a lot about you as a user. How do we solve this? This is core. So this is a header that you add onto the image thing that says it's going to be embedded same site. OK, so if you use this resource on anything but the same site, it will just. Felt load. OK. Yep, so you would look like you were not within corp.example.com that you just looked like you didn't have access to that. That makes sense. So there we go. Next problem. Now, this is a case where this wouldn't be solved by same site cookies. Obviously, you would never put a resource policy header on an HTML file? Well, you could. But you might have forgotten or something. I mean, many servers out there have not done this. Obviously, this is not going to load. But it is going to bring this HTML file into the process. Because image encoding is done in process. Yeah, never back in Spectraland. Spectraland meltdown.cpu bugs that will let you hammer away at certain things and start maybe trying to read some of the data. So this is a problem that is fixed by corp. There it is. Look at it. Yeah, well. It's beautiful. This is a cross-origin read blocking. It's a memorized X and you're going to get that wrong. So it's not a resource blocking. No, it's read blocking. Definitely read blocking. And how this works is as part of fetch before things enter the process, what it does is it looks at particular mind types. It looks to see if it has the no sniff header on and it can get it sorted then. But Chrome will also do things like if this looks like HTML and it's not a cause request, not letting it through. Also, it prevents it from ever getting to the process. But it has to be a header on the response. It's just a technology. A corp is just a corp, corp, corp, corp, corp. I feel like I'm going mad. Corp is just like a feature in Chrome. Yes. Well, yeah, it's not like corp a header or a cause. It's in the fetch spec. And in the fetch spec version, you have to do some, like you have to have no sniff on the response to say, like, don't look at this to see if it's an image or not. But you see, when it's got no sniff. So with those of you saying, I guarantee that I set the correct mind type on the content type header. Exactly. And then it just goes, HTML cannot be a sub-resource. Gone. Gotcha. I mean, if it's a cause request, it can. But this code isn't run for cause requests. So yet, what will happen is it will look at it and go, and Chrome will do extra sort of sniffing around it as well. And go, well, this looks a bit like HTML. I'm just not going to let this through. It does the same with JSON, does the same with XML. I wouldn't judge JSON through. Exactly. There you go. Final one. Here you go. Co-app. This is co-app. Co-app. I've heard it pronounced. Yeah. And so this is something that you would use on your HTML page. And co-app requires co-op. Yes, it does. Are you following along? You can't just be a test after this. Hope you're concentrating. And what you're saying here is you're making a declaration that everything on your page is either going to be cause or authorized by some of the means, like the site is going to opt into including it. And the opt-in would be using the co-op, but a specific opt-in to saying, this can be embedded cross-origin. OK, so this would then if, wait, but images still work if they had no sniffing the correct MIM type? Yes, but now if you've got this header on your page, they will start failing. Oh, except. Because you're saying, I am saying, I am opting into this stricter model. On a per-sub-resource basis. On a per-sub-resource basis. And the reason for that is to opt into more powerful features. Because we now know, once you've done this, you're in a position where you don't really have anything to specter meltdown. Right? So that's the point where we can go, oh, we can give you high-resolution timers. Oh, we can give you a shared array buffer. If we can guarantee that there's no sensitive data in your process. And this enforces that guarantee. So if I remember correctly, and I'm excited about this, not because it's so easy to understand, but because I think this is the headers that would allow us to bring shared array buffer spec. That is it for everyone. Is it exactly that? Yes. Yes, because that would mean. High-resolution timers, all of that stuff that we've had to take out because of meltdown specter, it can come back. Because if and when we get this, we'll also get threats for wisdom and all this stuff on mobile, on the other browsers. So for that, in that sense, yay. Yay. Excellent. In terms of understanding it, whew. And that is pretty much everything I wanted to talk about. Because we've gone on quite a lot. But I want to acknowledge that we looked at a certain class of problems here. And this is where one site is stealing stuff from another site or making the other site do things it didn't want to do. And that makes the user sad, because they lose data or they have their privacy invaded. There is a whole other class of problems where site A and site B totally fine with sharing data. But the user is sad about it. Oh, that's the tracking problem. This is cross-site tracking. This is not that. That's a separate problem. And I want to spend a whole episode on that at some point, because there's a lot of interesting things happening in that space. So that's a shout-forward to another episode, some of a time. Oh, so you tuned on that one. But that's enough for now. OK, bye. We've had a guest in the studio. He's about to arrive. There he comes. He's very, just to let you know, so everyone's very carefully dodging cameras and lighting equipment in order to do this. But look, look, this is the official show, dog. Look, look, look, this is Watson. And Watson is going to be very sad if you don't click subscribe right now. Why don't you then click the bell? What do you want, son? What do you want? What do you want? What do you want? What do you want? Just bark at your face right now. I'm just like, f*** off. Even the dog's yawning now. The dog's bored. He's very excited. I'm bored. Oh, goodbye.