Hacker News new | past | comments | ask | show | jobs | submit login
Exploring the SameSite cookie attribute for preventing CSRF (simonwillison.net)
38 points by simonw 9 months ago | hide | past | favorite | 12 comments

> The trick is to only allow logins from users that are carrying at least one cookie which you have set in that way—since you know that those cookies could not have been sent if the user originated in a form on another site.

It's crazy to me that HTTP servers need to rely on tricks like this to understand the context of a request.

At a minimum, it would be nice if `Origin` was sent with all requests from browsers, not just cross-origin XHR requests.

This is s problem with stateless approach for HTTP protocol. When it was conceived it was not a problem at all.

Maybe we need a statefull protocol for web-apps -- where stateless is still good for web-pages.

Now we have statefull web-apps based on stateless protocol - what could go wrong?

Developers making mistakes, just like managed vs unmanaged memory.

It's not crazy and it's not a trick.

The Context: that's an app-layer concern, not a protocol layer concern.

As far as I can tell Origin: is also sent by regular HTTP POST requests these days.

I added a note about Origin to the post.

I was inspired to look into this by the OkCupid article from the other day: https://news.ycombinator.com/item?id=28039631

The Safari "bug" is a new setting that's turned on by default: "Prevent cross-site tracking". It treats all cookies as SameSite=Lax, even cookies with SameSite=None.

Source: Currently dealing with fallout from "Single Log Out" being "broken" on Safari because it depends on SameSite=None cookies being sent along with GET request for <img> tags. (Note: I warned them years ago this would happen eventually and that this was a bad way to manage session revocation across domains.)

Thanks, that's really useful - I added this to the post.

What would be the good way to do it?

Honestly there's only one proper way to do it cross domain: Your Single Sign-On mechanism needs to pass a session identifier. Whether that's via a claim on an OAuth2 token (or an OIDC ID token) or an attribute in a SAML assertion, it needs to represent a particular session your IdP holds with the user agent.

Applications leveraging the SSO solution must check that the session identifier is still valid via some sort of API call.

When a client logs out and hits your SLO process, the session ID is marked as revoked. Queries to the API for that session ID will reveal it is revoked and all other interested parties will now know that the session is no longer valid and can take action.

Practically, this usually means checking the API on every page render or in the case of an SPA, every time a request is made. If you are willing to accept a delay in the log out propagating to other domains, you can cut back to every X requests or a particular interval of time, say 5 minutes.

On the SP side, I frequently see extremely short session lengths as the simple (but annoying) alternative to checking if a session is revoked.

GitHub requires SAML re-auth every 24 hours. AWS defaults to 1 hour but customizable. Do many SP’s even support SLO in a standardized manner? I believe there is a spec/standard for it, but I could be mistaken.

There is no good spec. There are several conventions that are almost always IdP specific.

That said, you hit on the main point: The best way to handle Single Log Out is to not handle single log out. If I log out of a federated AWS session, I am not logged out of Okta. If I log out of Okta, I am not logged out AWS.

Unfortunately, someone saw SLO was a feature and ordered us to enable it and provide support to the SPs to implement it against my recommendations to do otherwise and here we are.

> Since it’s common for subdomains to host other applications that may have their own security concerns, ditching CSRF tokens for Lax cookies may not be a wise step!

This is a really fantastic point, and it applies to CORS as well.

It's common to ditch CSRF tokens when CORS is configured, which is perfectly legitimate. But reflecting the Origin in Access-Control-Allow-Origin is dangerous if you have subdomains hosted by a third party AND are using `credentials: "include"`.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact