How csurf middleware validates tokens?
Asked Answered
B

3

7

I am testing NodeJS express app that uses csurf package along with express-session package.

Problem

While testing, i have to make requests that should include csrf token in them but because i don't really understand how csurf middleware validates csrf tokens in incoming requests, that is causing a lot of problems in testing the app.

Question

Can someone explain in simple terms, how csurf middleware validates csrf tokens when using csurf middleware with express-session package? How it validates token when it receives it in a request? Should tokens be sent in headers or in request body? Is new token created every time a new page is rendered or do we have once token per user session?

I also want to know how that the token validation process will change when using csurf middleware with cookie-parser package?

Blondellblondelle answered 5/9, 2019 at 20:44 Comment(0)
J
10

The csurf works by storing a token secret into either the session (in the case of express-session) or directly into cookie (case of cookie-parser). The server side should then render the website with a dynamically generated (per request) token via req.csrfToken(). This csrf token is derived from token secret and can be verified later.

When calling csurf protected endpoints, this token should then be included by client via body or header (see the default values here). The middleware will then fetch the token secret from either the session or cookie, then verify it is a valid token generated by the secret owned by the user. If the verification fails, it will throw a csrf error.

Since csrf token generated is not time sensitive, for unit testing you can actually hardcode a same token secret into session or cookie, call req.csrfToken() once to receive a valid token, then keep on reusing the same token for every test.

Jujitsu answered 6/9, 2019 at 4:7 Comment(0)
H
0

Whether or not to issue a CSRF token per-request or per user session seems to be an area of debate, and even the top two answers on this stackoverflow security question disagree on the matter.

The Bottom Line:

We should always follow OWASP's recommendations which states that per request CSRF tokens are more secure, but not necessary and can cause other problems.

CSRF tokens should be generated on the server-side. They can be generated once per user session or for each request. Per-request tokens are more secure than per-session tokens as the time range for an attacker to exploit the stolen tokens is minimal. However, this may result in usability concerns.

...

It is worth noting though that the back button issue may not be a problem with csurf since it uses secret mechanism to generate/validate tokens (which allows old tokens to validate).

Finally, if you are building an SPA:

The csurf documentation says to only send down the CSRF token once on the route that renders the page

Haymes answered 8/6, 2021 at 18:47 Comment(0)
L
0

How scurf is implemented

  • Server stores a token secret either into the session or into the cookie owned by the user.
  • Server generates a token dynamically via req.csrfToken(), the token is derived from token secret.
  • Token is sent to the client with the GET response (e.g. within a form's hidden field).
  • Client sends token back to the server when POSTing the form.
  • Server verifies if the token sent by the client is valid for the token secret belonging to the user.

Generation & Verification

csrf is used for CSRF token creation and verification, and csurf is a Node.js middleware. Let's talk more about Generation and Verfication

  • Generation:
    • Token consists of:

      salt a random string, a "-" (hyphen) character, and then the hashed value of "salt-secret". ${salt}-${hashedValue}

      The salt must be sent with the token, otherwise the server can't verify the authenticity of the token: compare(token, salt + '-' + hash(salt + '-' + secret))

    • Regenerating the secret will invalidate all outstanding tokens. This will lead to very poor user experience with no improved security. For example, it is very common for users to have multiple tabs open on a web site. This would break that functionality. A per-page or per-request token can be implemented without regenerating the underlying secret value.

  • Verification:
    • The token is validated against the visitor's session or csrf cookie. This means that the token is valid for the entire life time (in your case the life of the session)......The token is different for each req.csrfToken() to guard against BEAST when served over SSL.

The token secret hold by server is unchanged for the entire life of the session, While each token generated for per request is different but also valid as long as this session is still active. The workflow ensure a good user experience.

Ln answered 17/8 at 17:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.