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
Set your application to use SameSite=none if it uses response_mode=form_post when interacting with Auth0 (note that Chrome makes no exceptions, even for localhost ) Set your cookie as secure if its SameSite attribute equals None. Otherwise, it will be rejected by the browser.
SameSite=None requires Secure The warning appears because any cookie that requests SameSite=None but is not marked Secure will be rejected. To fix this, you will have to add the Secure attribute to your SameSite=None cookies. A Secure cookie is only sent to the server with an encrypted request over the HTTPS protocol.
A New Model for Cookie Security and Transparency Developers must use a new cookie setting, SameSite=None , to designate cookies for cross-site access. When the SameSite=None attribute is present, an additional Secure attribute must be used so cross-site cookies can only be accessed over HTTPS connections.
This is due to the RFC treating the absence of this setting in a more impacting way than if it is present but set to None. However on the set_cookie method, the samesite parameter is defaulted to None which results in it not being written into the set-cookie.
It been blocked, as Chrome now only delivers cookies with cross-site requests if they are set with SameSite=None and Secure. Secure is set, but I tried to set SameSite in all the possible way, but without effect. I tried, changing the behavior of the library, I tired setting the attribute in set_cookie () but nothing seemed to work.
The ASP.NET session cookie, rather than aseparate SAML session cookie, is used to maintain SAML session state. The ASP.NET session cookie must include aSameSite value of None and should be marked as secure.
After these changes, the SameSite parameter isincluded. Note though that if the ASP.NET update hasn’tbeen installed on the web server, the unrecognized cookieSameSite attributewill result in an “Unrecognized attribute” configuration error at runtime.
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 the samesite=None
value. I have no idea why because i'm using the latest version of flask
and Werkzeug
which apparently should fix the problem but it doesn't. After lots of testing, I found out using the response.headers.add()
works to add a Set-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 call SecureCookieSessionInterface
class and get the signed session from there.
from flask import session
from flask.sessions import SecureCookieSessionInterface
# where `app` is your Flask Application name.
session_cookie = SecureCookieSessionInterface().get_signing_serializer(app)
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.
@app.after_request
def cookies(response):
same_cookie = session_cookie.dumps(dict(session))
response.headers.add("Set-Cookie", f"my_cookie={same_cookie}; Secure; HttpOnly; SameSite=None; Path=/;")
return response
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:
response.set_cookie("key", value, ..., samesite="None")
samesite=None
would indeed be ignored and defaults to "Lax".
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