-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Security][CSRF] Added CSRF CookieStorageInterface #33171
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
Conversation
0e386d2
to
9cf77c4
Compare
while you should always use https, server missconfiguration could allow cookies sent over http, which are then subject to MITM attacks and can be obtained by an attacker to enable CSRF by using the obtained cookie, even if the page redirects to https after. iirc the same was done for auth cookies in symfony.
the attack vector here was very narrow, but is available. an attacker basically adds own cookies with a specific subpath (matching the path where the form or endpoint is sent to). this does not remove the valid cookie on the root path, but the server does not see the valid, when processing a request on the subpath. i dont remember the exact attack process. iirc the randomized cookie name was also a step in preventing such attacks and the reason i parsed the cookie "by hand" (so i can see the path overwritten cookies). |
more on this "path attack vector": |
thanks for the clarification.i will update this PR according |
@jderusse i remember now why i had the dynamic cookie name and "manual" parsing. the dynamic cookie name was used in order to detect multiple (valid) cookies on the same path/domain (which should not happen and is possibly an attack attempt). in order to detect all cookies i need to read the cookies "by hand" (there wasnt an API to iterate over all cookies raw provided by http foundation when i created the original PR) see https://github.com/symfony/symfony/pull/18333/files#diff-9f740f95b00ee5e8fc34b6c078860081R190 |
73a0338
to
4968c7a
Compare
PR update to :
This is not needed as the tokenId is not the same with http/https since https://symfony.com/blog/cve-2017-16653-csrf-protection-does-not-use-different-tokens-for-http-and-https
After reading https://github.blog/2013-04-09-yummy-cookies-across-domains/ (and the conclusion)
and
|
d37c59f
to
be5eee5
Compare
Ready for review |
be5eee5
to
0a125fa
Compare
@michaelcullum may I ask you to have a look ? I think this is a sensitive piece of code |
I would like to challenge this approach. What I don't like here is that one needs to opt into session or cookie storage. That's a choice to make with non-obvious effects. The linked issue #13464 is about stateless CSRF protection. I'd add cacheability on top as a requirement for the perfect solution. This PR still requires the cookie to be set on the server-side, so that the page that sets the cookie can still not be served by e.g. Varnish. Maybe we don't need this at all but can live with a much simpler approach. When
|
I really like the behavior of cacheable form. It would help to removes many ESI. If one of those header is present, we can check it to validate the request. It's fine.
In some situation
What if both headers are empty?
My opinion: This will be a great feature (cacheable form) and is safe when rejecting empty option+referer. But this solution does not work for few end-users. Developers must be able to decide whether or not they activate that option. I suggest to add an option: framework:
csrf_protection:
storage: session|cookie|origin|app.my_service Last word about CSRF and security: many people think that CSRF is only about "authenticated user" and granting privileges. But Attacker may also use CSRF in signin form to log the Victim into the attacker's account, in order to let the victim registering a credit card, or buying things, uploading sensitive documents, ... |
Is CSRF still a thing? https://scotthelme.co.uk/csrf-is-really-dead/ |
In both mode, the website is still vulnerable to "trusted domain phishing" attack which I describe in my last paragraph and is better explained here https://stackoverflow.com/a/15350123 |
i think im generally happy with the proposed hybrid solution in #33171 (comment) regarding same-site-cookies
IIUC it's because for "login CSRF" there's no (session) cookie available we can check, right? So we still need some form of protection, e.g. header checking or this PR (double submit cookie).
Alternatively, what about doing this out-of-the-box when using the framework (we already know ESI is supported yes/no, and we have the /_fragement endpoint). |
that's a risk no? if there's a session we might need to assume a session CSRF token is the only possible valid entrance edit: wait, it becomes the intended fallback protection. So expected ... but perhaps one should opt-in/out with header checking 🤔 |
Big thank you @jderusse for working on this. From the discussion, it appears we are looking for a stateless and cacheable alternative to sessions. I think there should be a follow up of this discussion if anyone wants to sum it up in an RFC (or nobody does it, all is fine, that's OSS dynamics :) ) |
FTR, I'm experimenting on this topic in |
This PR provides a CookieTokenStorage to handle CSRF in a stateless context by implementing a double submit strategy documented by OWASP (see: https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.md#double-submit-cookie)
The documentation should highligth the statement (from the same doc)
List of security mechanisms:
Known security issue:
This PR is a followup for #18333 with few changes:
SessionTokenStorageFactory
and all theAbstractTokenStorageProxy
and Only KeepCookieTokenStorage
usage:
ping @backbone87