Dj rest auth using JWT Token stored in HttpOnly cookies

I'm making a Django Rest Framework application with a JWT authentication with tokens stored in HttpOnly cookies. Authentication is performed via reading the access cookie. I'm using a dj-rest-auth library for this purpose, but I'm a little confused of the security aspect of such method. Knowing that having authentication data stored in cookies can be used to perform CSRF attack, how can one protect their web against such attacks for a specific case I've described above? All cookies are set to be SameSite=Lex.

Do I need to also send X-CSRFTOKEN header obtained from the backend? That would mean that every request to the api will need to have that header. What should be the optimal setup having all those libraries?


The OWASP foundation has created a detailed cheat-sheet on how to prevent from CSRF attacks: https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html

Two things worth remembering:

  • CSRF is a concern only for data-changing requests, so POST/PUT/PATCH/DELETE methods. An attacker performing a CSRF attack can't read the response from the server, so GET requests are not your concern.

  • The most common way of preventing CSRF is with a csrf token. The server should create the token for the user's session and the token is saved in frontend, but not in a cookie. Then you send that token either in a header or as part of the request body. The server then validates that the token is the same as the one it has for that user session.

If you don't want to persist the token in your server, you can additionally save it in a cookie. So the frontend will keep the token in two places - one in memory/in a hidden form field/etc. and another one in the cookie. Then the server can check if the value from the cookie matches the value from header/body.


All cookies are set to be SameSite=Lex.

Do I need to also send X-CSRFTOKEN header obtained from the backend?

SameSite is not supported by older browsers. As per caniuse, it is supported by 90% browsers in use globally.

Arguments AGAINST implementing CSRF tokens:

  • I think it's a low risk. If you think your users will be among those 90%, then don't bother with CSRF tokens.
  • Since you're using JWTs, I assume the frontend is going to be a modern SPA app. If you don't expect it to run on older browsers, then, again, don't bother with CSRF tokens.

Arguments FOR implementing CSRF tokens:

  • Lax offers no protection on GET requests. You'll have to make sure, today and in future as well, that you never modify server state in GET requests. If you implement CSRF tokens, you'll have one less thing to worry about. Or you can also use SameSite=Strict value.

My opinion:

Personally, I'd just implement CSRF tokens. It's a one time setup and most frameworks already take care of this. So, why not?


P.S.: I'm not sure if you've a typo there, but it is Lax, not Lex.