Forums

Flask - The CSRF session token is missing on some browsers??

I have a Flask app with a login functionality. It works in Chrome and Firefox on my PC and I am able to login. However I get a "The CSRF session token is missing" on Edge and Chrome. Chrome is on my mobile phone. I have read through many forums and can summarise my implementation as follows,

I have enable CSRF globally in my init.py

from flask_wtf.csrf import CSRFProtect
csrf = CSRFProtect()
csrf.init_app(app)

I have added it to my templates and I can also see the token when I view the HTML in view source.

<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
<input type="hidden" name="csrf_token" value="IjdhMGM5MjAyMGViZWI0ZjkxM2U2ZjQwOGI2YWI1YTI5ZmNiZjZmYTYi.YLZA9Q.fkFgK5gN6x0LryFCqbwHLIjKxTg"/>

I have also added the below to my config

SERVER_NAME = 'flaskcms.pythonanywhere.com'

My secret key is also set. It is so wierd that it works on 2 browsers (Chrome & Firefox) but fails with a 400 bad request error - "The CSRF session token is missing" on Edge (PC) and Chrome (mobile app).

Have anyone experienced similar or have any ideas? Thanks

That's sounds weird. Two things you may try:

Upgrade packages (Flask, Flask-WTF, WTForms, etc) to the most recent versions.

Make sure that you have force https enabled (there is a switch on the "Web" page in the "Security" section)

Let us know if that helped.

Thanks for the quick response. I tried as you suggested - switched on force HTTPS and updated all my packages but got the same result. I also logged in using my work PC and got the exact same results. Works on Chrome/Firefox but doesnt work in Edge. (Strange as I thought Edge uses the same engine as Chrome) .. and I dont see any wierd settings in Edge. Also still getting the CSRF token issue on Chrome mobile browser. Anyway .. will continue to keep looking ..

Sure -- another idea is to use developers tools in Edge and check if it refuses to send the cookie for some reason (Chrome would provide some information in such a case).

So it appears the session cookie is not being set in Edge - when you navigate to the login page. I checked another Flask app that I have and it is being set for that app, so there must be some config issue on this app.

I currently have the below config setting, as I am implementing some breadcrumbs which requires it. Is the below setting correct and do you think it is the cause of this behaviour? This is about the only difference I can see between my current app that doesn't work and my previous one that does.

SERVER_NAME = 'flaskcms.pythonanywhere.com'

Thanks

Are the dev tools in the browser alerting you in any way? In short, anything red?

I can see 3 errors in red

1/ Under compatibility

'text-size-adjust' is not supported by Firefox, Firefox Android, Safari, iOS Safari. Add '-webkit-text-size-adjust' to support Firefox Android 49+, iOS Safari.

2/ Under performance

A 'cache-control' header is missing or empty.

3/ Under security

Response should include 'x-content-type-options' header.

None of those are likely to cause the issue. Are you sure that the session cookie is being sent to Edge? If it is, then Edge should have some sort of indication somewhere about why it rejected the cookie.

Ok I finally located the error. So I inspected the server response headers. There is a set cookie there:

Set-Cookie: session=eyJjc3JmX3Rva2VuIjoiY2JhNTFiODViODZlMTM3NGQyYmZkMjA3YjdlMDNlMTlmYWEzMzAyMCJ9.YLmpYg.vb_KCByR3HmnfrUqSzV6KyfICvE; Domain=.flaskcms.pythonanywhere.com; Secure; HttpOnly; Path=/

The error is: "This Set-Cookie was blocked because its Domain attribute was invalid with regards to the current host url"

So what is wrong with Domain=.flaskcms.pythonanywhere.com?

Isn't this my site's URL ?

My login page is at https://flaskcms.pythonanywhere.com/admin

Hello I had a similar issue. My issue was the session cookie was not being written to mobile browsers (Chrome on Android). It turned out that I was using the session cookie for all my info and due to the size of the data being stored mobile was not saving accepting the session cookie but was ok on the desktop. I changed this so only a token is stored in the session and all session data is stored in a db against this token not sure if this is a solution for you but thought I would share so can be eliminated. Another possible solution to the domain issue could be found here https://nickjanetakis.com/blog/fix-missing-csrf-token-issues-with-flask.

Thanks @seanmcenroe , I took a look at your suggestion, but I think my case was a bit different.

I finally fixed the issue. For me I added the below to my config to ensure domain was not being set in the set-cookie directive.

SESSION_COOKIE_DOMAIN = False

For the record I needed to have SERVER_NAME='flaskcms.pythonanywhere.com' because I needed to generate URL in config.py for some breadcrumb functionality I was creating. But by adding this for some reason it made Edge and Chrome on Android reject the cookie because something to do with the domain (?). By adding SESSION_COOKIE_DOMAIN = False this told Flask not to include domain in the set-cookie header.

Problem solved!

Glad to hear you worked it out! I must say that that "." at the start of the domain name in your Set-Cookie header looks a bit odd -- I would have expected Domain=flaskcms.pythonanywhere.com rather than Domain=.flaskcms.pythonanywhere.com -- but as far as I can see, leading dots are ignored in the current version of the HTTP spec. Perhaps Edge doesn't ignore them, though?