I have read a few articles regarding JWT refresh tokens, and how/why they are used. One thing i have seen mentioned here: https://hasura.io/blog/best-practices-of-using-jwt-with-graphql/#persistance and here: https://dev.to/cotter/localstorage-vs-cookies-all-you-need-to-know-about-storing-jwt-tokens-securely-in-the-front-end-15id
is that using refresh tokens mitigates against CSRF attacks. The first article states:
The refresh token is sent by the auth server to the client as an HttpOnly cookie and is automatically sent by the browser in a /refresh_token API call. Because client side Javascript can't read or steal an HttpOnly cookie, this is a little better at mitigating XSS than persisting it as a normal cookie or in localstorage. This approach is also safe from CSRF attacks, because even though a form submit attack can make a /refresh_token API call, the attacker cannot get the new JWT token value that is returned.
The second article says something similar:
Although a form submit to
/refresh_token
will work and a new access token will be returned, the attacker can't read the response if they're using an HTML form
I am struggling to see how this would prevent CSRF attacks as I am thinking the following:
- A request to
/refresh token
from another domain to the users will return new JWT token to the user. I am going to assume this is stored in a HttpOnly cookie (as is done in the first article) - As CSRF does not involve any injection of javascript and the cookie it httpOnly, the attacker can't read the value of the new JWT token.
- However, if the JWT token is stored in a cookie again, surely a CSRF attacker can just send another request using this new cookie, with the new JWT token sinde?
If my understanding is correct, I am struggling to see how CSRF attacks are prevented by using refresh tokens. Can someone please explain exactly why refresh tokens prevent CSRF attacks, and why the CSRF attacker can't just use the new JWT the user would receive for future attacks?
It seems to me that the thing that would actually be preventing a CSRF attack would be the use of a sameSite cookie, or maybe using some sort of anti-forgery token.