The Double Submit Cookie CSRF Token pattern is a stateless technique that doesn't require storage or a database. However, it's vulnerable to session hijacking attacks and sub-/sibling domains that are susceptible to XSS or HTML injection. A common way to mitigate this risk is by using a session value and signing it using HMAC to validate the authenticity of the request.

For backend programming languages that don't natively support sessions (such as NodeJS) or when not Database is available, JWT is commonly used with HttpOnly Cookies to persist authorization across multiple requests. However, note that while the JWT value can't be tampered with because it's a signed value, it's not a server-side secret and can be read by the client.

Given these considerations, what value unique to a session can be used to generate the HMAC CSRF Token when using JWT?

Some possibilities I thought about were:

  • attaching a random UUID in the JWT payload and encrypting the JWT, but this approach adds a lot of overhead
  • use a database to store session IDs, but this negates the need for JWT in the first place.
  • Welcome to the community. I'm afraid your statement saying that Node.js has no support sessions is semi-false - express.js has sessions for example, which is commonly used. If by natively you mean part of the standard library - then you might be right there, but it doesn't matter, since you need to use at least some libraries or frameworks either way.. Commented Apr 2, 2023 at 10:29
  • P.S. have you looked into JWS? It might solve some of your issues. Commented Apr 2, 2023 at 10:29
  • Node.js is not a language, but a runtime. It uses JavaScript as language.
    – mentallurg
    Commented Apr 2, 2023 at 12:00
  • Please explain what problem are you trying to solve.
    – mentallurg
    Commented Apr 2, 2023 at 12:48
  • @SirMuffington Express is a framework for NodeJS, which needs an additional first-party library to be installed. There are many other web frameworks for Node.js, other than Express, that only have access to a session with the help of third-party libraries, sometimes leading to brittle implementations.
    – Advena
    Commented Apr 2, 2023 at 13:57

1 Answer 1


I think I have found the answer to my question.

Let's take a closer look at what we consider to be secure value to use for a session-bound CSRF token: the session id of a server-side session.

When a session is started in the backend, all session data is stored server-side and assigned a unique ID. This ID is then stored in an HttpOnly Cookie, which means that the session ID is stored in plain text client-side. It just can't be read by JavaScript, but you can easily inspect it with the Browser's devtool.

Now, the JWT is also stored in a HttpOnly Cookie. The values, just like the server-side session id, are stored in plain-text client side (unless the JWT is encrypted). In other words, we can quite safely store a unique ID (a random value) in the JWT that only exists for the lifetime of the JWT. We can then use this unique ID for as the session for the CSRF token.

In both cases, the value we use for session signed CSRF tokens is available client-side, but there is no need to worry. In both cases, the backend has the secret key to sign the CSRF token, making it impossible for an attacker to forge a signed CSRF Token, even if they have knowledge of the session ID or unique ID in a JWT.

  • 1
    "The values, just like the server-side session id, can be read client side" - No. You say that the session ID cookie has HttpOnly attribute set. This means that such cookie cannot be read by the client. This is the purpose of HttpOnly attribute, to prevent client from reading such cookies.
    – mentallurg
    Commented Apr 15, 2023 at 12:39
  • "store a unique ID (a random value) in the JWT" - How does it prevent CSRF?
    – mentallurg
    Commented Apr 15, 2023 at 12:45
  • "a session-bound CSRF token: the session id of a server-side session" - Do you mean that you suggest to use session ID as a CSRF token? If not, please explain it.
    – mentallurg
    Commented Apr 15, 2023 at 12:47
  • "backend has the secret key to sign the CSRF token" - What is the goal of signing the CSRF token? Why do you think that just a random string is not sufficient?
    – mentallurg
    Commented Apr 15, 2023 at 12:51
  • Please explain: 1) how you generate CSRF token; 2) how is it transferred to the client; 3) where is it stored on the client; 4) how is it sent from the client to the server.
    – mentallurg
    Commented Apr 15, 2023 at 12:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .