Safari not including csrf cookie in post request

I have a front-end using react that sends ajax requests to Django for user login from a separate domain. I have resolved CSRF-related issues in all browsers except Safari.

It seems that Django requires BOTH a header “X-CSRFToken: 71SHXg…” and the cookie “Cookie: csrftoken=71SHXg…” to be included in the request from the front end before accepting the login information.

I have manually put the header “X-CSRFToken: 71SHXg…” into the request, so that part works in all browsers. However I can’t seem to get Safari to include the cookie in the request.

The cookie has been saved in browser storage with Secure=True, and SameSite=None. I have a fetch request using credentials: ‘include’ and a second axios request using “withCredentials: true”. Chrome, Edge, and Firefox all put the csrf cookie in the request, but Safari does not, so Django gives me a Forbidden error in safari.

Has anyone else run into Safari-specific issues with getting cookies into cross-domain requests?

Alternately, is there any way to make Django less strict, and take either the header “X-CSRFToken: 71SHXg…” or the cookie? Why does it need both?


I can address part of this:

Because that’s how the request is validated. The cookie needs to appropriately match the token for the request to be considered valid. The basic intent is that JavaScript from a different host wouldn’t have access to the cookie to build a valid token.

See Cross Site Request Forgery protection | Django documentation | Django for all the gory details.

Regarding Safari, I think the first thing I’d check is that there aren’t any settings set to block cookies or otherwise prevent the cookie from being written or sent.
(I don’t do a lot with Safari, but I just checked one of my sites using Safari on an ipad and have no problems with it at all.)

Thank you! It looks like Safari was having issues because “Prevent cross-site tracking” is on by default. Turning this off and restarting the browser fixes the issue.

1 Like