How SameSite, Same-Origin, and CORS Partially
Block XSS and CSRF Attacks
I’ve read many articles on XSS, CSRF, CORS, and SameSite cookies before, but they were often presented separately, which sometimes left me feeling all mixed up. Therefore, I’ve compiled this overview.
If you don’t have prior knowledge of these topics, you might find this article super confusing LOL, so it’s best to refer to the relevant standalone articles for a clearer understanding.
Samesite
SameSite decides whether you can bring cookies automatically in cross-site requests.
Strict
: You ain't getting my cookies with CSRFSet-Cookie: <cK>=<cV>; SameSite=Strict
Lax
: You can get cookies under certain conditionsSet-Cookie: <cK>=<cV>; SameSite=Lax
- top-level navigation
- HTTP GET method. Flip side, to avoid CSRF risks with lax, just try to avoid using GET
None
:Set-Cookie: <cK>=<cV>; SameSite=None; Secure
Limited in preventing XSS, but you can mitigate one XSS method by setting Set-Cookie: <cookieK>=<cookieV>; HttpOnly
, as it'll stop the browser from reading document.cookies. But this is just for cookies. If they use malicious scripts, you've got way more to worry about.
Keep it simple: can prevent XSS from stealing cookies, but can't stop other XSS plays.
Can greatly prevent CSRF, but only moderately mitigates XSS.
Same-Origin Policy
Cross-origin malicious scripts under SOP can execute, but cannot access cross-origin cookies.
Same-origin malicious scripts can execute and can access same-origin cookies, unless those cookies are marked as HttpOnly.
Can partially prevent XSS but doesn't do much like preventing CSRF. CSRF's goal is "sending", not the reading.
Content Security Policy
Content-Security-Policy: script-src 'self' https://trustedsite.com;
then you can only execute scripts from yours or trustedsite.com’s
Cross Origin Resource Sharing (CORS)
Does enabling CORS mitigate XSS or CSRF?
CSRF
Partially, CORS can just check the origin list (whitelist) if you have the right to go through, but cannot check if you're... JUST you.
CORS only knows that where you're coming from is legitimate, but it doesn't mean that someone coming from a certain place is completely harmless.
Also, even if the request does go through (simple request doesn’t need preflight), the CORS can still prevent you from reading the response.
XSS
As for XSS, unless it makes a cross-origin request and gets caught by header checks, XSS itself can't be eliminated just because CORS mechanisms exist.
Still, CORS can't stop other XSS plays
CSRF
Me, as a Forgery, my main goal is to fake sending requests, not reading your secrets. So, I don’t care about your Same-Origin Policy.
How to fight with CSRF?
- backend generates a csrf token and frontend keep it.
- backend sets sameSite cookie policy, and frontend (as browser) apply it.
- origin? referer (longer than origin)?
- etc
XSS
Well, if you don't have XSS defense mechanisms and an XSS script succeeds, it can execute CSRF, and even sniff out CSRF-related checks like origin, referer, and even csrf token. Then you're screwed.
Thoughts
Prioritize solving XSS, otherwise even amount of CSRF checking methods will do no good.
But actually, since JWT tokens are commonly used now, there’s not much need to worry about cookies if the frontend and backend communicate with tokens.
Table
mechanism | fight XSS? | fight CSRF? |
Set-Cookie: …;SameSite={Lax,Strict} | prevent XSS getting cookies, but cannot stop XSS | Mostly ⭕ |
Same Origin Policy (browser’s built-in mechanism) | tell browser to execute scripts from whitelist ⭕ | - |
CSP (Content Security Policy) | using origin whitelist to preventing XSS execution ⭕ | - |
Set-Cookie: ...; HttpOnly | prevent XSS getting cookies ⭕ | nothing to stop CSRF from using cookies |
CSRF Tokens | - | Mostly ⭕ [tag1] |
tag1
If the website does not have XSS protection, an attacker can steal the CSRF token through an XSS attack, thereby bypassing the CSRF protection mechanism.