A “replay-resistant” authentication stops a MITM from storing traffic and being able to perform requests on behalf of the victim.
A CSRF is an attack that allows an intruder to use a valid session, stored or not, to perform requests on behalf of the victim.
A CSRF token makes sure that access to the session alone does not grant access to perform requests on behalf of the victim. It also protects therefore against a "replay-resistance" authentication because the attacker has to have not only the classical HTTP cookie stored session but in addition a more difficult to obtain, if well implemented, CSRF token.
The answer to the question is therefore "No, it is not valid to defend a CSRF token against replay, because the CSRF token actually is the one that can protect against replay. If a CSRF token implementation needs to be "defended" against replay then that implementation is not good enough"
To dig further into a good implementation of a CSRF token, here is what to do (Note that CSRF token protection is not just about demanding a token when a request is received but also about when that token gets sent to the front end, and how the front end keeps it):
- Do not support old browsers. This ensures, for example, that SameSite=lax is set by default for cookies and provides an army of headers that can be sent from the server side to make the browser mitigate front end related attacks. Another example that shows why using latest browser versions is important would be the default "same origin policy" that new browsers use and their support for some controlled relaxing via Content-Security-Policy header. Bottom line, again, stop old browsers from using your app. Risking everybody because few do not upgrade their browsers is a totally incorrect approach.
- Do not allow any backend persistence without providing a CSRF token. So, for example, if your API implementation does not follow a purist REST approach, then consider checking CSRF for everything the server receives including yes, GET requests.
- Return the token as HTTP Header only once after successful login.
- Store the CSRF token in the local browser storage and never as a cookie. This is crucial because if you use a cookie then your browser will be sending the CSRF token regardless of what site does it on your behalf. The CSRF token must be reachable only if a user is running front end code from the app domain.
- Inactivate the session if an incorrect CSRF token is received for it.