we have a simple form. From time to time some people (which we don´t know) produce the following error we get in appsignal.
HTTP request error: invalid CSRF (Cross Site Request Forgery) token, make sure all requests include a valid '_csrf_token' param or 'x-csrf-token' header
We know one user who sometimes has this error and sometimes not. How can that be?
It seems that mostly IE / Safari (ipad, iphone) / Opera users are affected. How can we debug what happens?
In Phoenix, the CSRF-token is added to all forms you have. As long as you use normal forms (and not submitting forms through e.g. AJAX-request), this should work in all browsers, including browsers that have Javascript turned off.
Other than noting the pages (where the forms were submitted) and attempting to reproduce it with exactly the same browser version, there is little you can do to reproduce it, I’m afraid.
I’d like to pitch in as well. We are also seeing this error occurring regularly. I did some investigation and it seems the token is tied to the session of the user, so the only reproduction scenario I can think of is opening the form, clearing the session on the client, and then submitting the form. I find it highly unlikely though that this is what the user is actually doing. Is there any other behaviour surrounding the CSRF token that we need to be aware of? Does it expire after a certain amount of time for instance?
@laurens how is your session stored? If you are using ETS, every server restart will clear all sessions. Any login pages rendered with the old session will raise this exception.
Or until the internal lifetime is elapsed (which in the next phoenix version defaults to 1 day I think, instead of the like 1 year or whatever it defaults to now, though it is best to set is explicitly regardless).
Sorry to reply to this old post. But I have been having this issue in production as well. same as @augnustin, I am having this InvalidCSRFTokenError around 1% off our request(or event a bit higher). So far we can’t see any pattern. It looks completely random and we are using standard cookies storage.
I will appreciate if any of you found a way to solve this issue or at least know the root cause?
This issue happens mostly because of how browsers purge sessions but keep pages. Here is most likely a way to reproduce it:
Load a page containing the form
Quit the browser software completely but ask it preserve pages
Reopen the browser
Submit the form
Between quitting and reopening the browser, the session was purged, but the now outdated CSRF token is still in the form. The browser does not ping the server at all, so there is nothing we can do to address this in a way that won’t also make applications vulnerable.
The long term answer is the SameSite cookie attribute, but it will be a while until it is standardized. You can also set protect_from_forgery to clear_session but it still means that the form submission won’t work.