skip to Main Content

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 with SameSite=None
and Secure.

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


  1. 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 use
    set_cookie()
    like this:

    from flask import Flask, make_response
    
    app = Flask(__name__)
    
    @app.route('/')
    def hello_world():
        resp = make_response('Hello, World!');
        resp.set_cookie('same-site-cookie', 'foo', samesite='Lax');
        resp.set_cookie('cross-site-cookie', 'bar', samesite='None', secure=True);
        return resp
    

    Otherwise, you can still
    set the header
    explicitly:

    from flask import Flask, make_response
    
    app = Flask(__name__)
    
    @app.route('/')
    def hello_world():
        resp = make_response('Hello, World!');
        resp.set_cookie('same-site-cookie', 'foo', samesite='Lax');
        # Ensure you use "add" to not overwrite existing cookie headers
        resp.headers.add('Set-Cookie','cross-site-cookie=bar; SameSite=None; Secure')
        return resp
    
    Login or Signup to reply.
  2. 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.

    Login or Signup to reply.
  3. 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".

    Login or Signup to reply.
  4. 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

    session_cookie_samesite=app.config["SESSION_COOKIE_SAMESITE"]
    

    in the Talisman constructor worked.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search