Summary

Intermittent errors related to invalid csrf tokens when using a CsrfCookieTokenRepository

Actual Behavior

We're seeing intermittent messages in our logs for an internal application

Invalid CSRF Token '3c49b924-5b26-4413-b456-7a44f5ac4751' was found on the request parameter '_csrf' or header 'X-XSRF-TOKEN'.

Expected Behavior

Tokens generated by spring-security shouldn't be rejected. I may be misunderstanding this, but the documentation seems to suggest that the issue isn't related to timeouts, as tokens from the CsrfCookieTokenRepository do not expire.... in the way that tokens from a HttpSessionCsrfTokenRepository would when the session times out.

Configuration

Http security is configured as follows

            .csrf()
            .csrfTokenRepository(new CookieCsrfTokenRepository().withHttpOnlyFalse())
            ....
````

The token is actually being injected into the HTML as a metatag via a thymeleaf template at the moment.


The token is being passed in a header via a json/ajax call.  

const csrfHeaderValue = this.getMetaContent("_csrf");

options.headers = new Headers({ "X-Requested-With": "XMLHttpRequest", "Content-Type": "application/json", "X-XSRF-TOKEN": csrfHeaderValue, ...options.headers });

fetch(getBaseUrl() + path, options)


As can be seen in the error message above, a non-null token value is being passed in with requests, but is rejected.

### Version

Spring boot starter security - 2.0.2.RELEASE

**Comment From: rwinch**

Each time a user authenticates or logs out the CSRF token is regenerated to protect users. Are you ensuring to update the token at that time? Since you are placing the token in the cookie a better approach is to just read the token from the cookie directly instead of the meta tag?

If the issue is happening around the time of authentication or logging out, it is possible that you are reaching a race condition. An example would be:

* Request 0 grabs the CSRF from the cookie and creates an AJAX request with the CSRF token in the headers
* Request 1 authenticates the user and gets a response back with the new CSRF token in a cookie. The browser stores the Cookie
* Request 0 submits the original CSRF token along with the new CSRF token in the cookie. The values do not match and thus the server rejects the request.

If this doesn't help, please provide additional details on how to reproduce the issue. Providing a sample will likely give your issue higher priority as it helps the team to troubleshoot the problem easier.

**Comment From: kiftio**

Thanks for the quick response.  I'll switch to reading the token from the cookie, and find out whether it's happening around authentication time

**Comment From: kiftio**

Hi @rwinch, just switching to reading the token from a cookie and noticed we seem to receive two, is that expected?

Set-Cookie: XSRF-TOKEN=; Max-Age=0; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure Set-Cookie: XSRF-TOKEN=5ebc8888-17b7-4ef9-80b1-3d7a8d10acb1; Path=/; Secure ```

Comment From: rwinch

it is first invalidating the cookie and then setting the cookie. That is expected if you log out and then try and use a token

Comment From: kiftio

I think that's resolved it, thanks for the help