I am attempting to build an application that submits numerous fetch/XHR requests to a NodeJS backend. I'd like to implement CSRF token protection, but would like to avoid implementing server-side rendering/templating or middleware on the frontend (trying to go as vanilla JS as possible on frontend). This means I can't inject the token into a <meta>
or <form>
tag before the page renders. I don't have any <form>
tags anyway.
How can I security convey the CSRF Token (generated on the server) to the frontend without injecting it directly into the index.html file on load (which would require server-side rendering/templating and middleware)?
Keep in mind that the server will be storing the token on its end in a session. Additionally, both the frontend and backend will live at the same domain.
I can think of two ways:
- Have server create cookie with 'samesite' set to strict and CSRF token included and have frontend read that cookie to send CSRF token to server in custom
x-csrf-token
headers as part of fetch/XHR calls. Thus, frontend learns of CSRF token via cookie. - Have server reply to user login POST with CSRF token in response body and have frontend read that response body to send CSRF token to server in custom
x-csrf-token
headers as part of subsequent fetch/XHR calls. Thus, frontend learns of CSRF token via successful login response body.
Are either of those ways secure? If not, what is a secure method of passing CSRF token to website frontend after it has loaded (i.e., without pre-baking the CSRF token into a <meta>
or <form>
tag)?
samesite
cookie: isn't CSRF mitigated alone by this?httponly
), 1 is impossible. 2 is safe over HTTPS since it could only be exploited by a MITM.SameSite=strict
.SameSite=Lax
orSameSite=None
are still vulnerable to CSRF requests. For example,SameSite=Lax
does send Cookies for cross-site requests when specific conditions are met, which can be exploited for CSRF attacks.