3

I have implemented CSRF attack prevention on my nodejs server in the following way -

User on login receives a CSRF token and a cookie (JWT based token stored in a cookie). The CSRF token is made a part of all future request headers sent from the client using $.ajaxSetup.

Whenever a request is made (GET or POST) by the user, I compare the cookie and csrf token (in the header) sent by the client with the stored ones on my server and the application works fine.

However, when a logged-in user opens a new tab or a new browser window, client has the cookie but does not have the CSRF token in its request headers. So the server considers this as a CSRF attack and blocks the request!

My question is - Without compromising on CSRF security, how can I have the same session running on multiple browser tabs and windows without having the user to login multiple times?

Vijay Singh
  • 247
  • 1
  • 3
  • 15

2 Answers2

5

Do not use CSRF protection on GET requests. To pass a CSRF token in a GET request you have to put it in the URL itself (eg in a query parameter), and URLs are not a good place to put security-sensitive information. They tend to leak through a variety of means, not least the Referer header send when following links or fetching resources from protected pages.

You should ensure that all actions that have an active effect (that is to say, actions that change something in the database, or write to the filesystem, or send a mail) are exposed only through POST requests, and properly protected with CSRF tokens. Views that don't have any active effect (eg view an page, search for something) should be accessible via GET and don't need CSRF protection. The user can then open a new tab and browse to a page with a form in without getting an error; the form will be generated with the correct parameter so will submit OK.

Side-issue: you are using the Double Submit Cookie method of CSRF protection. This is... okay... but does not protect some scenarios that other methods do.

(Specifically, if an attacker can perform a cookie fixation attack—for example by leveraging a vulnerable application on a neighbour/child subdomain, or by MitM attack over HTTP onto HTTPS site—they can bypass the CSRF protection by making the user send the same value in the request parameter that they pushed onto the user in the previous step.)

If the site is a sensitive one or is particularly vulnerable to this due to other less-trusted apps nearby, you might wish to consider using a Synchronizer Token alternative, or Encrypted Token (can be done with just signing too; a good alternative if you are not using any kind of session storage).

bobince
  • 498,320
  • 101
  • 621
  • 807
  • 1
    1. When I'm sending CSRF in GET requests, I send them in a X-XSRF-TOKEN header, not in the request url. 2. What if there is sensitive user information displayed in GET requests which I want to hide from an attacker using CSRF techniques. Thanks. – Vijay Singh Feb 09 '16 at 16:34
  • @bobince Correct me if I'm wrong, but if he was using a Double Submit Cookie solution, opening a new tab wouldn't be a problem because the CSRF cookie would be shared between the two tabs. It sounds like the CSRF token is being injected into the page's JavaScript context. – kuporific Feb 11 '16 at 22:16
0

I decided to go with x-requested-with header. This header is a part of all AJAX requests in jquery by default.

More details -
What's the point of the X-Requested-With header?
https://security.stackexchange.com/questions/107906/alternative-to-anti-csrf-tokens-for-ajax-request-same-origin-policy

This allows cross tab, cross window browsing where a cookie is used for user authentication and x-requested-with header is checked to prevent CSRF attack.

Community
  • 1
  • 1
Vijay Singh
  • 247
  • 1
  • 3
  • 15