Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python session SAMESITE=None not being set

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

like image 764
Christian Quintavalle Avatar asked Jul 20 '20 09:07

Christian Quintavalle


People also ask

How do you specify SameSite none?

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.

How do I set specify SameSite none and secure?

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.

What does SameSite none mean?

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.

Why is the SameSite parameter not in the set_cookie method?

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.

Is it possible to set SameSite with cross-site cookies?

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.

Which session cookie is used to maintain SAML session state?

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.

What happens if cookiesamesite is not installed on the server?

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.


2 Answers

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.

like image 81
Prince Avatar answered Sep 22 '22 21:09

Prince


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".

like image 23
JBSnorro Avatar answered Sep 21 '22 21:09

JBSnorro