-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update: CSRF prevention cheat sheet to offer more detail on SameSite cookie limitations #1101
Comments
To my knowledge:
|
Feature | Code Example | Cookies sent when SameSite value is |
---|---|---|
link (with user action) | <a href="…"> |
None , Lax |
prerender (with user action) | <link rel="prerender" href="…"> |
None , Lax |
form GET (with user action) |
<form method="get" action="…"> |
None , Lax |
form POST (with user action) |
<form method="post" action="…"> |
None |
iframe (initialized with page load) | <iframe src="…"> |
None |
XHR (initialized with page load) | fetch('…') |
None |
image (initialized with page load) | <img src="…"> |
None |
Therefore, SameSite=Lax
by itself provides insufficient security against CSRF attacks.
SameSite=Strict
According to a Google paper by Artur Janc (page 6), using SameSite=Strict
prevents many CSRF attacks, since the cookie (session cookie with credentials) will only be sent on same-site requests [1. This is great as an additional defence mechanism for websites that require high security, such as banks.
However, this approach requires the browser to recognize and correctly implement the attribute (1), which at this day of writing (4/2023) is approximately 95% of all active browsers.
Entirely bypassing SameSite
The SameSite
cookie attribute can create a false sense of security. While it offers some CSRF protection with Lax
and Strict
, the attribute itself can be entirely bypassed(1 | 2) with:
- The website (
a.com
) is vulnerable to XSS or HTML Injection. - A website's sub-/sibling domain is vulnerable to XSS or HTML Injection. For example:
- Subdomain:
a.com
andvulnerable.a.com
- Sibling:
a.a.com
andvulnerable.a.com
- Subdomain:
- A subdomain takeover (SDTO) attack
- A Man-in-the-middle attack, gaining full control of the cookie(known as Session Hijacking.)
Thanks for your detailed answer @advename ! I still have two questions, though:
(1) I'm not following how you arrived at your conclusion. Are you worried about CSRF attacks against GET endpoints? Isn't the correct mitigation for such a vulnerability to change side-effect endpoints to POST/PUT/etc instead of GET?
(2) My understanding was that if you have these vulnerabilities in your site then an attacker can circumvent any CSRF control, so this consideration should be out of scope. Is that not true? Regardless, given your answer I think the cheat sheet should be updated to reflect your information. Notably:
Do you agree? |
Exactly. On paper, the correct mitigation is to not allow any state-changing actions with Ask yourself: can you say with 100% confidence that all
Anyone correct me if I'm wrong, but I don't think so. In Session Hijacking, the attacker can force connections to
|
As one of the cheatsheet leads I am following this comversation with great interest and tend to agree with madelson so far.
- Manicode
|
This is true, although in my experience implementing a mitigation like the recommended Synchronizer Token Pattern is also generally opt-in (a developer must take some action to add the token to their AJAX request, for example), so unless you take the hardline stance of disallowing any GET request without an antiforgery token it will still be reliant on junior devs knowing that they should do this when it matters. Furthermore, I'll note that, at least on the platform I'm using, the built-in "validate by default" approach already omits GET requests, so if you're set up this way devs still have to know not to create vulnerable GETs. But really, this comment touches on my original motivation for looking into these techniques and asking about SameSite limitations. The appeal of the SameSite=Lax + Referer/Origin validation controls is that I can centralize them in one small part of the system and developers don't even have to be aware/opt in. In contrast, the recommended primary mitigations require more setup, overhead, and developer diligence to implement correctly.
I think I don't fully understand this scenario. It makes sense that an attacker can't create their own valid CSRF token, but can't they generate a valid one simply by using the session cookie to issue a request that will generate one (e.g. using the mechanism suggested for AJAX antiforgery here)? Also, does this attack rely on your site accepting HTTP traffic? |
Not entirely. Client side XMLHttpRequest libraries such as axios allow you to manage these things automatically with interceptors. With interceptors, you can narrow it down to a set of HTTP methods that attach the CSRF token. I see this in two ways:
Again, this entirely depends on the CSRF token implementation. Some techniques require you to remember it every time, like with the Synchronizer pattern where you have to include it in a hidden Moreover, as nice as your approach sound, I don't think the technology is mature enough for it (yet).
First, the attacker can't simply change the I have no experience with ASP.NET, but from your link it seems that Razor renders the CSRF in the response body (in the HTML) as a hidden |
I also have to correct something. Gaining access to the session value, e.g. from the session cookie, is called "Session Hijacking". Setting a predefined session value, e.g. setting or overwriting the session cookie, is called "Session Fixation". My bad. |
Agreed this seems like the way to go. I still can't force devs to use axios over alternatives like fetch, but if everyone gets onboard with axios it is easier to centralize this sort of behavior.
What are techniques that don't require remembering it every time? The two mentioned in the cheat sheet (STP and double submit) both seem to require a request parameter which (axios aside) I think you do need to remember.
Seems like the only applicable cases for non-GET requests are load balancers / proxies / anti-virus / etc which are intentionally stripping this header. If you were to require either a valid Referer header or a valid Origin header, I suppose you lose out on some percentage of users with these setups. However, I wonder if there is still a security hole in that case?
Ah ok I was imagining a stolen session cookie or XSS attack where you could simply ask the server for a valid token. Session Fixation feels related (equivalent?) to login CSRF, which I agree that a SameSite cookie cannot protect from since you don't have the session cookie yet. |
Axios is far from perfect. But the interceptors allow centralizing a bunch of things.
My bad, this was a badly formulated answer. Synchronizer token is stateful, e.g. you store the token server side and send in some request to the client in the body making it vulnerable to BREACH attacks.
Load balancers, proxies, WAF,... many web hosting services use these by default, without your knowledge. Moving from one to another may open for a new attack vector. |
Very interesting; I hadn't heard of this type of attack against a CSRF token. However, from reading the article and from your comment it seems like the vulnerability is more related to putting the token value in the form vs. a request header, right? My understanding was that both double submit and STP do this, e.g. per the cheat sheet "The site then requires that every transaction request includes this pseudorandom value as a hidden form value (or as a request parameter/header)". What am I missing?
I my site requires either an origin or a referer header and rejects requests missing both, then what is the "new attack vector"? I would think that the downside of this approach is that some users would be unable to access the site because of their configurations, or that my site might reject all users if something in my own environment is doing this. But neither of those would be a vulnerability. |
The BREACH attack exists on the HTTP body (
Well, the client (e.g. a web browser) is solely responsible for setting the Origin header. There are cases, where the browser sends I have not enough experience with checking Referer/Origin headers. It seems like the OWASP doc sees Referrer/Origin headers check as a mitigation technique, but still lists them under "Defense in depth" (≠ full mitigation), maybe because it's not widely supported yet? (Need help) Also:
This sounds like bad UX, blocking genuine users because we don't know better? (Need help) @jmanico or somebody else, can anybody come with some information to those questions marked with |
@madelson, I believe this may also be of interest data-govt-nz/ckanext-security#23 (comment) |
@madelson, some pages also have an interest in disabling the Referer header completely: https://www.sjoerdlangkemper.nl/2017/06/21/bypass-csrf-check-using-referrer-policy/ |
Works for me! However, I'd suggest that others join the discussion. Currently, it's mostly been ping-ponging between me and @madelson. |
Alright - I've been digging now through several Origin/Referer resources + specifications and can confidentially say this: 1.My previous statement was erroneous:
This seems to be incorrect. The 50% coverage exists as there's a lot of unknown data to confidently determine the coverage. However, CORS which is built on the 2.
|
I recently found an additional method to bypass the Sources:
|
@advename this still relies on sensitive, state-changing
@mackowski I think there's lots to improve/clarify here. As a starting point:
|
@madelson correct
I agree. It's easy to overlook or ignore the |
Agree on that we should improve that. But keep in mind that this is cheatsheet and CSRF is already longer that we want. Anyway SameSite needs clarification. I like how you summarised this discussion in the two last comments: #1101 (comment) and #1101 (comment). @advename you are already doing changes to CSRF cheatsheet do you want to improve this part as well? |
I definitely agree. Personally, you can feel that the CSRF cheat sheet has been "Dumped" with a lot of information and it lacks a more clear, global, structure. Excuse me for my French. But maybe it's time to archive the current CSRF cheat sheet and create a new one. |
Hi @jmanico glad that you asked! There is no incorrect information. The CSRF Cheat Sheet is a great and extensive resource. But hear me out. Let's look at a common DX:
The Cheat Sheet became the main linked resource regarding CSRF and highlights all the important CSRF cases. However, a novice has a hard time understanding the whys, while, the Cheat Sheet has to stay short because, it is, a Cheat sheet. "Archiving the current CSRF cheat sheet and create a new one" doesn't seem to be the right choice. After some thoughts, if the Cheat Sheet website supports this, how about using Collapsible Sections? |
I am totally ok with collapsible sections, major edits and
clarifications. I just do not want to start over. Too much work has gone
into it so far.
Can you consider a few PR's and edits? I'll respond quickly.
- Jim
|
I agree. It was a late night hasty thought, my bad! I have little time to spare due to a fulltime job and am already looking into #1143. I might be able to do so at a later time. |
All good, we want your help!
And here you go, this should help!
https://gist.github.com/pierrejoubert73/902cc94d79424356a8d20be2b382e1ab
|
@jmanico I linked to the same gist in my previous comment:
The question is, does the website support this? |
What is missing or needs to be updated?
With regards to SameSite cookies, the cheat sheet says this:
The 2 ways to bypass described in the linked document are:
However, other commentary I've found (e.g. this SO post) suggests that those bypass approaches might be dated and/or limited in scope.
How should this be resolved?
It would be nice if the cheat sheet addressed these limitations in more detail. Can SameSite be a first-class mitigation mechanism under certain scenarios (e.g. no domain sharing, no mutating GET requests)? What attacks are still possible?
The text was updated successfully, but these errors were encountered: