I am having issues with chrome and SameSite. I am serving a webpage in a shopify iframe and when setting the session using flask-login, chrome tells me this:
A cookie associated with a cross-site resource at
URL was set without the
SameSite
attribute. It been blocked, as Chrome now only delivers
cookies with cross-site requests if they are set withSameSite=None
andSecure
.
Secure is set, but I tried to set SameSite in all the possible way, but without effect.
I tried setting
app.config[‘SESSION_COOKIE_SAMESITE’] = "None"
I tried, changing the behavior of the library, I tired setting the attribute in set_cookie() but nothing seemed to work. The response I see doesn’t have the SameSite attribute.
(I have the last versions of flask, flask-login, flask-security and werkzeug)
Can you help me?
Thank you
4
Answers
From: https://github.com/GoogleChromeLabs/samesite-examples/blob/master/python-flask.md
Assuming you’re on the latest version of
werkzeug
that includes the fix to this issue, you should be able to useset_cookie()
like this:
Otherwise, you can still
set the header
explicitly:
Just to expand on this, using flask application config just as you’ve mentioned, you can set everything except when setting
SESSION_COOKIE_SAMESITE=None
Google Chrome doesn’t seem to place the value as "None", which then defaults to "Lax".How i worked around this problem was to add the cookie back into the response header. First I had to get the cookie value because using
request.cookies.get("my_cookie")
doesn’t seem to extract the cookie value from the response and always appears as None.secondly, using the
response.set_cookie()
still doesn’t set thesamesite=None
value. I have no idea why because i’m using the latest version offlask
andWerkzeug
which apparently should fix the problem but it doesn’t. After lots of testing, I found out using theresponse.headers.add()
works to add aSet-Cookie:
header but I needed a way to extract the cookie value to ensure I can get the same session. After looking through flask docs and other online forums. I found out that I can actually callSecureCookieSessionInterface
class and get the signed session from there.Lastly, i had to ensure that the same session is added to the response after the request has been established rather than calling it on every route which doesn’t seem feasible within a full fledged application. This is done by using the after_request decorator which runs automatically after a request.
What I noticed in Chrome is that, it basically sets a duplicate cookie with the same signed value. Since both are identical with one having
samesite=None
in the response header and the other blocked by Chrome seems to be ignored. Thus, the session is validated with the flask app and access is allowed.A mistake easily made (as I did) is to confuse
None
with"None"
. Be sure to use the string instead of the python literal like so:samesite=None
would indeed be ignored and defaults to "Lax".I had a similar issue where it kept setting SESSION_COOKIE_SAMESITE to Lax. In my case it was caused by flask-talisman, who was overwriting my config.
Specifying
in the Talisman constructor worked.