2 years ago

#57091

test-img

Ron Michaeli

CSRF token cookie is not set for cross origin requests

The problem:

In production my server and client are running in different origins (CORS).
The client needs to store a cookie sent from the server, but it fails to do so even that the cookie attributes are set as required.
The server is written in Flask and the client sends requests with Axios.

What I've tried so far and current status:

  • First off, when the client and server are in the same origin (localhost:3000 and localhost:5000) the cookie is set as expected
  • To simulate CORS locally, I run the client in 127.0.0.1:3000 and the server in localhost:5000.
    The bug is reproduced in these settings.
  • I followed this post (and many others) and configured the server, client and the cookie as required, but still the cookie is not set in the browser
  • Since this is a cross-origin request, a preflight OPTIONS request is sent first
  • Current status:

Preflight request headers:

OPTIONS /api/v0/get_csrf_token HTTP/1.1
Host: localhost:5000
Connection: keep-alive
Accept: */*
Access-Control-Request-Method: GET
Access-Control-Request-Headers: app-version,authorization,os-type
Origin: http://127.0.0.1:3000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
Sec-Fetch-Dest: empty
Referer: http://127.0.0.1:3000/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9

Preflight response headers:

HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Allow: HEAD, GET, OPTIONS
Access-Control-Allow-Origin: http://127.0.0.1:3000
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: app-version, authorization, os-type
Access-Control-Allow-Methods: DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT
Vary: Origin
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Content-Security-Policy: default-src https://cdnjs.cloudflare.com https://maxcdn.bootstrapcdn.com https://rawgit.com; connect-src 'self' https://*.fontawesome.com; img-src 'self' data: https://*.amazonaws.com https://*.vizcloud.net https://*.viz.cloud; font-src 'self' https://maxcdn.bootstrapcdn.com https://fonts.googleapis.com https://fonts.gstatic.com https://*.fontawesome.com; script-src 'self' 'unsafe-inline' https://code.jquery.com https://cdnjs.cloudflare.com https://maxcdn.bootstrapcdn.com https://unpkg.com http://d3js.org https://rawgit.com https://*.fontawesome.com https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline' https://code.jquery.com https://cdnjs.cloudflare.com https://maxcdn.bootstrapcdn.com https://fonts.googleapis.com https://rawgit.com https://*.fontawesome.com https://cdn.jsdelivr.net
X-Content-Security-Policy: default-src https://cdnjs.cloudflare.com https://maxcdn.bootstrapcdn.com https://rawgit.com; connect-src 'self' https://*.fontawesome.com; img-src 'self' data: https://*.amazonaws.com https://*.vizcloud.net https://*.viz.cloud; font-src 'self' https://maxcdn.bootstrapcdn.com https://fonts.googleapis.com https://fonts.gstatic.com https://*.fontawesome.com; script-src 'self' 'unsafe-inline' https://code.jquery.com https://cdnjs.cloudflare.com https://maxcdn.bootstrapcdn.com https://unpkg.com http://d3js.org https://rawgit.com https://*.fontawesome.com https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline' https://code.jquery.com https://cdnjs.cloudflare.com https://maxcdn.bootstrapcdn.com https://fonts.googleapis.com https://rawgit.com https://*.fontawesome.com https://cdn.jsdelivr.net
Referrer-Policy: strict-origin-when-cross-origin
Content-Length: 0
Server: Werkzeug/0.16.0 Python/3.7.9
Date: Thu, 13 Jan 2022 09:06:31 GMT

Follow-up GET request headers:

GET /api/v0/get_csrf_token HTTP/1.1
Host: localhost:5000
Connection: keep-alive
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="96", "Google Chrome";v="96"
sec-ch-ua-mobile: ?0
Authorization: null
Accept: application/json
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36
os-type: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36
sec-ch-ua-platform: "macOS"
app-version: web
Origin: http://127.0.0.1:3000
Sec-Fetch-Site: cross-site
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://127.0.0.1:3000/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cookie: X-CSRFToken=IjI1ODlkZGQ4MzJlMzRiZDM2M2U5YzgyM2EyODAxNTgxZTIyNDYwOWYi.FMF7UQ.-do_q8Zv3Fonh5QdSvfhaGbAVBk

Follow-up GET response headers:

HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 3
/*** THIS IS THE COOKIE I NEED TO STORE ***/
Set-Cookie: X-CSRFToken=IjFhYmVkNjZmN2Y0NjEzMTNmNzRhNzI4ZGVlZTVmMzQzNTVjN2JmOTgi.FMF9Fw.DWGaapFRX40GwpV3KU07iHEZzKc; Expires=2022-01-13 12:06:31.906331; SameSite=None; Path=/; Secure
Access-Control-Allow-Origin: http://127.0.0.1:3000
Access-Control-Allow-Credentials: true
Vary: Origin, Cookie
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Content-Security-Policy: default-src https://cdnjs.cloudflare.com https://maxcdn.bootstrapcdn.com https://rawgit.com; connect-src 'self' https://*.fontawesome.com; img-src 'self' data: https://*.amazonaws.com https://*.vizcloud.net https://*.viz.cloud; font-src 'self' https://maxcdn.bootstrapcdn.com https://fonts.googleapis.com https://fonts.gstatic.com https://*.fontawesome.com; script-src 'self' 'unsafe-inline' https://code.jquery.com https://cdnjs.cloudflare.com https://maxcdn.bootstrapcdn.com https://unpkg.com http://d3js.org https://rawgit.com https://*.fontawesome.com https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline' https://code.jquery.com https://cdnjs.cloudflare.com https://maxcdn.bootstrapcdn.com https://fonts.googleapis.com https://rawgit.com https://*.fontawesome.com https://cdn.jsdelivr.net
X-Content-Security-Policy: default-src https://cdnjs.cloudflare.com https://maxcdn.bootstrapcdn.com https://rawgit.com; connect-src 'self' https://*.fontawesome.com; img-src 'self' data: https://*.amazonaws.com https://*.vizcloud.net https://*.viz.cloud; font-src 'self' https://maxcdn.bootstrapcdn.com https://fonts.googleapis.com https://fonts.gstatic.com https://*.fontawesome.com; script-src 'self' 'unsafe-inline' https://code.jquery.com https://cdnjs.cloudflare.com https://maxcdn.bootstrapcdn.com https://unpkg.com http://d3js.org https://rawgit.com https://*.fontawesome.com https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline' https://code.jquery.com https://cdnjs.cloudflare.com https://maxcdn.bootstrapcdn.com https://fonts.googleapis.com https://rawgit.com https://*.fontawesome.com https://cdn.jsdelivr.net
Referrer-Policy: strict-origin-when-cross-origin
Set-Cookie: session=eyJjc3JmX3Rva2VuIjoiMWFiZWQ2NmY3ZjQ2MTMxM2Y3NGE3MjhkZWVlNWYzNDM1NWM3YmY5OCJ9.FMF9Fw.r8g0VeK8PjVqEtWz6ZcJrVYg6fo; HttpOnly; Path=/
Server: Werkzeug/0.16.0 Python/3.7.9
Date: Thu, 13 Jan 2022 09:06:31 GMT

Notice that the X-CSRFToken cookie in the GET response headers has SameSite=None and Secure attributes, as required for CORS.
But when I inspect DevTools in Application -> Storage -> Cookies, I see no cookies set in the browser.

You can also see the responses in the following images:

preflight response headers

GET response headers

What am I missing?

flask

cookies

axios

cross-domain

csrf

0 Answers

Your Answer

Accepted video resources