My web application (myApp further) is embedded in iframe of a single third-party webpage. MyApp sets cookie Set-Cookie: JSESSIONID=38FE580EE7D8CACA581532DD37A19182; Path=/myapi; Secure; HttpOnly
for maintaining users sessions. Sometime ago it stopped working in Chrome since https://blog.chromium.org/2020/02/samesite-cookie-changes-in-february.html update changed treating default behaviour for cookies without SameSite
attribute from None
to Lax
.
I'm going to send cookies from myApp host with SameSite=None; Secure
. Also X-CSRF-TOKEN
header is included in every response. myApp javascript gets X-CSRF-TOKEN
and puts it in header of every XHR request to myApp host. Does this suffice to prevent CSRF attack?
Should Access-Control-Allow-Origin: third-party-webpage
header be added in responses?
SameSite=Lax —cookie is sent if you navigate to the site through following a link from another domain but not if you submit a form. This is generally what you want to protect against CSRF attacks!
Some web sites defend against CSRF attacks using SameSite cookies. The SameSite attribute can be used to control whether and how cookies are submitted in cross-site requests.
The none value won't give any kind of protection. The browser attaches the cookies in all cross-site browsing contexts. The default value of the SameSite attribute differs with each browser, therefore it is advised to explicitly set the value of the attribute.
I did more research and thought I would post my conclusion here.
I had misunderstood how the Antiforgery middleware worked.
The cookie configured by AddAntiforgery
does not actually transmit the token to the client.
Instead it appears to be the encrypted or hashed token that is used to validate the token which must be provided in the header.
This allows the validation of the token to be done statelessly as the browser will pass the value of this cookie back with each request.
I refer to this cookie as the "validation cookie" below.
The middleware does not automatically transmit the token itself to the client.
That must be done by calling GetAndStoreTokens
and providing the RequestToken
value to the client to be set as a header for subsequent requests.
In our application we do that with a separate cookie (I call this the "token cookie" below).
Here's the Microsoft article demonstrating this technique.
I have determined that it is safe to use SameSite=None
for the validation cookie and for the token cookie.
The SameSite
setting does not have any effect on who can read the cookie value, it just determines whether or not the cookie will be sent to the server with future requests.
The validation cookie must be sent back to the server with future requests so that the token provided in the header can be validated.
It is acceptable that this cookie is sent even for cross origin requests since those requests will only validate if the token is provided in the header.
It is also acceptable for the token cookie to use SameSite=None
since we are only using this cookie to provide the value to the client.
We never read this value from the cookie on the server when validating the token, the middleware reads the token from the header.
The value of the token cookie cannot be read by a different origin regardless of the SameSite
property so that remains secure.
I also that realized that this exact pattern was employed by the Antiforgery middleware long before SameSite=Lax
became the default value for cookies by chrome in 2020.
Prior to this the default behavior for the validation cookie would have always been None
.
So I think it is reasonable to conclude that this technique is just as secure now with SameSite=None
as it was before Lax
became the default.
NOTE: There appear to be some browsers that don't handle SameSite=None
correctly so the antiforgery process might fail for these browsers when the app is hosted in an iframe.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With