SameSite cookies and CSRF vulnerabilities

Back then, besides SQL injection and XSS, the big web vulnerability was CSRF (Cross-Site Request Forgery). As an illustration if a bank at bank.example.com uses a form to transfer money, let's say at /transfer, then a third-party site, evil.example, can also POST to bank.example.com/transfer and since the browser automatically attaches the cookies set for the domain the attack will go through. I remember defenses against it such as generating a CSRF token for the form itself that was validated on submit as that value is something an attacker can't know.

Then the SameSite attribute for cookies appeared (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#samesitesamesite-value) and got supported by all browsers and I thought that CSRF is something of the past. There are some footguns (I'm in the process of writing an article about it) but if set up correctly, even a Lax cookie won't be sent when evil.example submits a form to bank.example.com. No session cookie => no authenticated user => no transfer.

Then today I read this article: https://jub0bs.com/posts/2021-01-29-great-samesite-confusion/

I'm still thinking about the implications and how it changes what I think of as best practices for the future.

The problem is that cookie security is SameSite. Usually, when thinking about web security, we're thinking about origins: Same-Origin Policy, Cross-Origin Resource Sharing (the infamous CORS), and so on. But site is more relaxed than origin.

Origin is the full hostname (also with the port, but that's not that important), such as example.com and sub.example.com.

Whereas site is just the registrable domain (plus the scheme, but that's also not important). The registrable domain is something you can buy: there is a "public suffix", such as .com, .hu, but can be longer, such as .co.uk, and one part before that. So example.com is a site, example.hu is another site, but sub.example.com is the same site as example.com.

The implication for this is that sub.bank.example.com can submit a form to bank.example.com where all the SameSite cookies will be sent. And in my experience subdomains are not that protected: example.com is the production environment, test.example.com is staging, dev.example.com is develop. With this setup if any of the environment is compromised then an attacker can send SameSite cookies to the production environment.

So on one hand the SameSite cookies are way better than what we had before as bypassing them needs some type of subdomain compromise. On the other hand subdomains are not that protected that I'd be happy to leave CSRF protection on not having a flaw there.

Currently, I'm looking at the sec-fetch-site header (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-Fetch-Site) that might be useful to prevent these cross-origin same-site attacks. I'm not perfectly happy with it as I think this should be something configured in the cookie itself and also it needs to configure the backend.

Originally published on LinkedIn.

June 24, 2024
In this article