-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
CSRF Protection without starting session #13464
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
Comments
This would kind of defeat the purpose of a csrf token, since the attacker would only need to make sure that both cookie and request tokens match. |
I agree. There must be some stateful connection between the requests in order to set, and check the csrf tokens. I'm really curious how many anonymous requests are done? Google doesn't do many request on a single site, so quite possible you have issues in cleaning up old session-files? Other options might be to store sessions inside a database or persistent memory storage like redis? |
Giving it a bit more thought, it could be actually possible to implement by replacing session storage with some other kind of storage (like a database). Cookie could be used to carry user's identifier (like a session identifier, but without sessions heh). The identifier can then be used to fetch and refresh the token (stored in a db). I think it's out of scope of the core framework though. |
Could you not use a HMAC generated with a secret only known by the server? You could also send a cookie with a client only secret to be included in the generated HMAC.. The server would then be able to verify the HMAC without starting the session. |
This does beg a question though - why do you need CSRF protection against XSS attacks for browser sessions which will not be authenticated? |
Sorry, never mind - stupid question. :) |
AFAIK, there is no need at all for any server side state. Comparing the cookie and the request is enough, provided the token is truly random. |
Cookies are fine for CSRF protection. The point is to prove that the request came from the user. In a cross-site context, an attacker cannot access cookies, nor can they set cookies. Therefore, if a cookie and a request token match, it had to come from a domain that could read and set both (assuming sufficient randomness in the token). Therefore, that mode-of-operation for CSRF protection is perfectly acceptable. You don't need sessions to secure against CSRF. |
We must specify the cookie format. I see 2 options: Option 1: One cookie
This has the benefit of using only 1 cookie (easier for reverse proxy config), but in case of simultaneous requests, the cookie may be overwritten ; loosing the token of the 1st request. Option 2: Multiple cookies
This let each token live independently in its own cookie, avoiding most request collisions risks. |
From the OWASP wiki: Prevention Measures That Do NOT Work: using a Secret Cookie |
If you have a read further down there's a section on the double submit cookies method that is perfectly valid. |
Right, just did that, so a cookie and a request parameter/hidden input are needed and the server checks they are the same. As I reread @ircmaxell comment now I realised he mentioned this but it wasn't so obvious to me when I first looked at this issue ... |
Curious to know what's the conclusion of this discussion, was the cookie support added? What's the recommended way to do it? |
Any updates on that issue ? |
@jderusse implemented cookie CSRF storage in #33171, but we decided against it because it appears to us that the complexity might not be worth the maintainance effort, especially when browsers implement or are implementing other countermeasures based on e.g. the |
FTR, I'm experimenting on this topic in #58095 |
…SRF protection (nicolas-grekas) This PR was merged into the 7.2 branch. Discussion ---------- [Security] Implement stateless headers/cookies-based CSRF protection | Q | A | ------------- | --- | Branch? | 7.2 | Bug fix? | no | New feature? | yes | Deprecations? | no | Issues | #13464 | License | MIT #54705 made me think about our CSRF protection and I wrote the attached CSRF token manager to implement stateless headers/cookies-based validation. By defaults, the existing stateful manager is used. In order to leverage this new stateless manager, one needs to list the token ids that should be managed this way: ```yaml framework: csrf_protection: stateless_token_ids: [my_stateless_token_id] ``` * This CSRF token manager uses a combination of cookie and headers to validate non-persistent tokens. * * This manager is designed to be stateless and compatible with HTTP-caching. * * First, we validate the source of the request using the Origin/Referer headers. This relies * on the app being able to know its own target origin. Don't miss configuring your reverse proxy to * send the X-Forwarded-* / Forwarded headers if you're behind one. * * Then, we validate the request using a cookie and a CsrfToken. If the cookie is found, it should * contain the same value as the CsrfToken. A JavaScript snippet on the client side is responsible * for performing this double-submission. The token value should be regenerated on every request * using a cryptographically secure random generator. * * If either double-submit or Origin/Referer headers are missing, it typically indicates that * JavaScript is disabled on the client side, or that the JavaScript snippet was not properly * implemented, or that the Origin/Referer headers were filtered out. * * Requests lacking both double-submit and origin information are deemed insecure. * * When a session is found, a behavioral check is added to ensure that the validation method does not * downgrade from double-submit to origin checks. This prevents attackers from exploiting potentially * less secure validation methods once a more secure method has been confirmed as functional. * * On HTTPS connections, the cookie is prefixed with "__Host-" to prevent it from being forged on an * HTTP channel. On the JS side, the cookie should be set with samesite=strict to strengthen the CSRF * protection. The cookie is always cleared on the response to prevent any further use of the token. * * The $checkHeader argument allows the token to be checked in a header instead of or in addition to a * cookie. This makes it harder for an attacker to forge a request, though it may also pose challenges * when setting the header depending on the client-side framework in use. * * When a fallback CSRF token manager is provided, only tokens listed in the $tokenIds argument will be * managed by this manager. All other tokens will be delegated to the fallback manager. ``` Since it's stateless, end users won't loose their content if they take time to submit a form: even if the session is destroyed while they populate their form, remember-me will reconnect them and the form will be accepted. Recipe update at symfony/recipes#1337 Commits ------- 27d8a31 [Security] Implement stateless headers/cookies-based CSRF protection
It would be nice add cookies csrf token storage. Use case: we are having form which available for anonymous users (and bots like googlebot). Session starts on each time when this page open. And too much files was generated with session data.
The text was updated successfully, but these errors were encountered: