Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Express/Connect generate new CSRF token on each request?

As far as I understand there are two approaches in protecting from CSRF attacks: 1) token per session, and 2) token per request

1) In the first case CSRF token is being generated only once when the user's session is initialized. So there is only one valid token for the user at once.

2) In the second case new CSRF token is being generated on each request and after that an old one becomes invalid. It makes harder to exploit the vunerability because even if attacker steals a token (via XSS) it expires when the user goes to the next page. But on the other hand this approach makes webapp less usable. Here is a good quotation from security.stackexchange.com:

For example if they hit the 'back' button and submit the form with new values, the submission will fail, and likely greet them with some hostile error message. If they try to open a resource in a second tab, they'll find the session randomly breaks in one or both tabs

When analizing Node.js Express framework (which is based on Connect) I noticed that a new CSRF token is generated on each request, but an old one doesn't become invalid.

My question is: what is the reason to provide new CSRF token on each request and not to make invalid an old one? Why not just generate a single token per session?

Thank you and sorry for my English!

like image 440
Oleg Avatar asked Feb 08 '14 11:02

Oleg


People also ask

Is CSRF token generated for every request?

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.

Should CSRF change every request?

Generating a new CSRF token for each request is not necessary. However, it is only important for login purposes, because it provides an authentication check for each login attempts.

How does the CSRF token get generated?

A CSRF token is a unique, secret, unpredictable value that is generated by the server-side application and transmitted to the client in such a way that it is included in a subsequent HTTP request made by the client.

How often does CSRF token change?

Often sessions do expire within 60 minutes, so a session based CSRF token has something like that as well (albeit it behaves a bit differently as the timeout period extends with each interaction). However, after each hour, the session id should be regenerated as well to prevent sessions that can be kept open unlimited.


1 Answers

CSRF tokens are nonces. They are supposed to be used only once (or safely after a long time). They are used to identify and authorize requests. Let us consider the two approaches to prevent CSRF:

  1. Single token fixed per session: The drawback with this is that the client can pass its token to others. This may not be due to sniffing or man-in-the-middle or some security lapse. This is betrayal on user's part. Multiple clients can use the same token. Sadly nothing can be done about it.

  2. Dynamic token: token is updated every time any interaction happens between server and client or whenever timeout occurs. It prevents use of older tokens and simultaneous use from multiple clients.

The drawback of the dynamic token is that it restricts going back and continuing from there. In some cases it could be desirable, like if implementing shopping cart, reload is must to check if in stock. CSRF will prevent resending the sent form or repeat buy/sell.

A fine-grained control would be better. For the scenario you mention you can do without CSRF validation. Then don't use CSRF for that particular page. In other words handle the CSRF (or its exceptions) per route.

Update

I can only think of two reasons why single dynamic token is better than multiple:

  1. Multiple tokens are indeed better but have at least one dynamic token like one above. This means designing a detailed workflow which may become complex. For example see here :

    1. https://developers.google.com/accounts/docs/OAuth2
    2. https://dev.twitter.com/docs/auth/implementing-sign-twitter
    3. https://developers.facebook.com/docs/facebook-login/access-tokens/

    These are tokens to access their API (form submission etc.) not just login. Each one implements them differently. Not worth doing unless have good use case. Your webpages will use it heavily. Not to mention form submission is not simple now.

  2. Dynamic single token is the easiest, and the readily available in library. So can use it on the go.

Advantages of multiple tokens:

  1. Can implement transactions. You can have ordering between requests.
  2. Can fallback from timeout and authentication errors (you must handle them now).
  3. Secure! More robust than single tokens. Can detect token misuse, blacklist user.

By the way if you want to use multiple tokens you have OAuth2 libraries now.

like image 192
user568109 Avatar answered Sep 20 '22 13:09

user568109