Is a JWT usable as a CSRF token?

TL;DR

A JWT, if used without Cookies, negates the need for a CSRF token - BUT! by storing JWT in session/localStorage, your expose your JWT and user's identity if your site has an XSS vulnerability (fairly common). It is better to add a csrfToken key to the JWT and store the JWT in a cookie with secure and http-only attributes set.

Read this article with a good description for more info https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage

You can make this CSRF protection stateless by including a xsrfToken JWT claim:

{ "iss": "http://galaxies.com", "exp": 1300819380, "scopes": ["explorer", "solar-harvester", "seller"], "sub": "[email protected]", "xsrfToken": "d9b9714c-7ac0-42e0-8696-2dae95dbc33e" }

So you will need to store the csrfToken in local/sessionStorage as well as inside the JWT (which is stored in a http-only and secure cookie). Then for csrf protection, verify that the csrf token in the JWT matches the submitted csrf-token header.


There is no need to encrypt the token or to include the nonce. The key properties of a CSRF token are that it is not predictable by an attacker, and, unlike cookies, that it is not added to every request by the browser. A cryptographically secure JWT stored in a hidden field meets both of these properties.

Note that you need to use JWT's that have user-unique data in them. Having an empty or generic JWT that isn't specific to the user will not provide you with security.


You could use a JWT as a CSRF token, but it would be needlessly complicated: a CSRF token doesn't need to contain any claims, or be encrypted or signed.

There is probably a misunderstanding about what JWT or CSRF tokens are used for (I was confused at first too). The JWT is an access token, used for authentication. The CSRF token, on the other hand, is used to protect the user from being tricked into sending a forged authenticated request. This is necessary when using a session or HTTP basic auth or storing the JWT in a cookie -- any authentication that is done automatically by the browser.

If you have such an authentication scheme, make sure that you

  • use proper HTTP verbs (GET must not have side-effects)
  • generate a new CSRF token on each request
  • include the CSRF token in a header or as an HTTP parameter on each PATCH, POST, PUT, and DELETE requests

Read, for example, how Spring handles CSRF.

Tags:

Csrf

Jwt