It seems to me like the underlying issue was ignoring HTTP semantics and making a state-changing link like a logout link a plain <a> (HTTP GET) and not something like a form submission (HTTP POST).
Having intuition for the foundational layers of our tools saves so much time and future headaches.
There was no form submission, I'm not sure where you got that. There was also no POST. Though yes, I agree that in the core HTTP semantic, you wouldn't want to change state on a GET and that should include not calling `Set-Cookie`. And yet the reality is that that nearly every application - and many popular libraries like auth0 - do in fact set and clear cookies on `GET`.
The issue here was that the `Link` component in NextJs
- does preloading by default (which is a bad idea exactly for the above reason of reality being different from theory)
- doesn't do preloading by default when running on the dev server (so you don't see the error until its deployed)
- because it does preloading directly in javascript, it can't possibly follow the HTTP semantic of not actually applying cookies until later when the cached route is used
Everything else was the wild goose chase bits.
Also I asked claude to criticize the article as a web forum might before publishing, and this is definitely the tone it gave :D
Oh, also, I'm pretty sure I got the part wrong where i was talking about the preload attribute in HTML, but so far no one's noticed. I should correct that.
"because it does preloading directly in javascript, it can't possibly follow the HTTP semantic of not actually applying cookies until later when the cached route is used"
I may be wrong, but I don't think using JavaScript vs using the standard HTML <link> element to prefetch makes a difference here. I don't see anything in the HTML specs about preload or prefetch delaying cookie setting to sometime after the resource is actually loaded (although admittedly I find this bit of the spec somewhat hard to read, as it's dense with references to other parts of the spec). I tried it out, and, both Firefox and Chrome set the cookies for preloaded and prefetched links when the resource is loaded, even if the resource is never actually used.
(TLDW: allow buttons to make HTTP requests; allow buttons & forms to issue PUT, PATCH & DELETE; allow buttons, forms & links to target elements in the DOM by id instead of only iframes)
would improve the web platform. You could have a stand-alone logout button that issues a DELETE to /session or whatever. Nice and clean.
Genuine question: How do you believe one should learn these semantics? This is more something I've been pondering myself recently, because I agree with you that the foundational knowledge for our work in any tech stack is usually the most important for understanding higher abstractions. But with so much to know it feels impossible to 'know it all' so to speak especially if you wear more than one specialized hat. Then beyond that even if you're only trying to learn just the foundations how do you know what those foundations are if you're not already inundated in that stack?
This is mostly just my personal ramblings, but I'd be curious other peoples viewpoints on this.
And so the Google web crawler had come across this page and happily visited each and every one of those links.
That’s when I learned about the importance of using forms with POST requests for certain actions instead of using links that send GET requests.
And then some years later someone told me about this thing called HATEOAS and about RESTful APIs and that actually there are different HTTP verbs you can use other than just GET and POST. Like for example
DELETE /path/to/file
As for your question about how someone is supposed to learn that these days?
Ideally whatever web development tutorials or courses or books they are using would at some point tell them about the different HTTP verbs that exists, and of how and when to use each of them, and crucially to tell them about bad consequences of using GET for anything that has side-effects like logging out a session or deleting a file.
This can be complex sometimes, but in case of HTTP methods specifically, it's hard to imagine how one can't know about this.
You learn HTML (and see a mention of "POST" method); or read HTTP primer (and see reference to methods) or open browser inspection window and see prominent "Method" column, or see the reference in some other place. You get interested and want to look it up - say wikipedia is often a good start [0] for generic part. And the second sentence of description says it all:
> GET: The GET method requests that the target resource transfer a representation of its state. GET requests should only retrieve data and should have no other effect.
IMO it's very understandable to not know about this sort of thing starting out. Everybody was new once, and it's much easier to get motivated to build cool stuff than to read about all the fine details of all of the technologies we're using. I say, go ahead and take the shortcuts and build some cool things in a maybe sloppy way as long as the traffic and stakes aren't too high. Then, once you've got something cool built, take some time every now and then to seek out and read about more of the details of some of the systems and tools you're using.
While it may not be quite the same answer you're looking for, I'd suggest the OWASP, and at least their top 10 for sure. Learning about SSRF may not have stopped this behavior (it's coming from the authenticated browser), but if you're doing CSRF checks you won't get logged out by random links on other peoples sites, and that whatever logged you out was a legitimate action.
To be fair, <a> tags can't send out non-GET requests. Which yes, can be interpreted as "logout controls should be buttons in forms, not links", but I would really like native htmx-like attributes for intractable html elements.
togakangaroo|1 year ago
There was no form submission, I'm not sure where you got that. There was also no POST. Though yes, I agree that in the core HTTP semantic, you wouldn't want to change state on a GET and that should include not calling `Set-Cookie`. And yet the reality is that that nearly every application - and many popular libraries like auth0 - do in fact set and clear cookies on `GET`.
The issue here was that the `Link` component in NextJs
- does preloading by default (which is a bad idea exactly for the above reason of reality being different from theory)
- doesn't do preloading by default when running on the dev server (so you don't see the error until its deployed)
- because it does preloading directly in javascript, it can't possibly follow the HTTP semantic of not actually applying cookies until later when the cached route is used
Everything else was the wild goose chase bits.
Also I asked claude to criticize the article as a web forum might before publishing, and this is definitely the tone it gave :D
Oh, also, I'm pretty sure I got the part wrong where i was talking about the preload attribute in HTML, but so far no one's noticed. I should correct that.
thedanbob|1 year ago
OP was saying the logout function should have been behind a form submission / POST.
culturedsystems|1 year ago
I may be wrong, but I don't think using JavaScript vs using the standard HTML <link> element to prefetch makes a difference here. I don't see anything in the HTML specs about preload or prefetch delaying cookie setting to sometime after the resource is actually loaded (although admittedly I find this bit of the spec somewhat hard to read, as it's dense with references to other parts of the spec). I tried it out, and, both Firefox and Chrome set the cookies for preloaded and prefetched links when the resource is loaded, even if the resource is never actually used.
keybored|1 year ago
Come on.
recursivedoubts|1 year ago
https://www.youtube.com/watch?v=inRB6ull5WQ
(TLDW: allow buttons to make HTTP requests; allow buttons & forms to issue PUT, PATCH & DELETE; allow buttons, forms & links to target elements in the DOM by id instead of only iframes)
would improve the web platform. You could have a stand-alone logout button that issues a DELETE to /session or whatever. Nice and clean.
williamdclt|1 year ago
Ethee|1 year ago
This is mostly just my personal ramblings, but I'd be curious other peoples viewpoints on this.
codetrotter|1 year ago
One of those magazines told a story about a web site that had lost a lot of data. What had happened? Well, somehow they had this page that
1. Required no authentication at all, and
2. Was using links like
And so the Google web crawler had come across this page and happily visited each and every one of those links.That’s when I learned about the importance of using forms with POST requests for certain actions instead of using links that send GET requests.
And then some years later someone told me about this thing called HATEOAS and about RESTful APIs and that actually there are different HTTP verbs you can use other than just GET and POST. Like for example
As for your question about how someone is supposed to learn that these days?Ideally whatever web development tutorials or courses or books they are using would at some point tell them about the different HTTP verbs that exists, and of how and when to use each of them, and crucially to tell them about bad consequences of using GET for anything that has side-effects like logging out a session or deleting a file.
theamk|1 year ago
You learn HTML (and see a mention of "POST" method); or read HTTP primer (and see reference to methods) or open browser inspection window and see prominent "Method" column, or see the reference in some other place. You get interested and want to look it up - say wikipedia is often a good start [0] for generic part. And the second sentence of description says it all:
> GET: The GET method requests that the target resource transfer a representation of its state. GET requests should only retrieve data and should have no other effect.
[0] https://en.wikipedia.org/wiki/HTTP#Request_methods
kaoD|1 year ago
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods
Also the many HTTP RFCs, this one in particular covers semantics:
https://www.rfc-editor.org/rfc/rfc9110.html
As the age old wisdom says... RTFM :P
HTTP is awesome, I'm in love with it. Beautiful piece of work.
ufmace|1 year ago
pixl97|1 year ago
boruto|1 year ago
That was where I "learnt" side effects of not using verbs properly. It stuck to me from then.
https://news.ycombinator.com/item?id=16964907
2OEH8eoCRo0|1 year ago
_a_a_a_|1 year ago
ori_b|1 year ago
throw156754228|1 year ago
graypegg|1 year ago
zbentley|1 year ago