8

Say I've got that web application that has a CSRF protection according to the Synchronizer Token Pattern. The server expects a valid CSRF token in each POST request when the user is authenticated. Now imagine the following scenario:

  1. The user opens a browser tab (tab anonymous) and starts some AJAX functionality that periodically reads from the server (e.g. a timestamp). The user is not authenticated in this tab.

  2. The user opens a new browser tab (tab authenticated) and performs a login there. If he now loads the AJAX framework, the CSRF token gets written into the source code of the AJAX framework by server-side includes and gets stored in the variable token.

  3. If the next automatic poll is done from tab anonymous, the session cookie gets submitted indicating a logged in user but this tab never received a CSRF token since the AJAX framework was loaded before performing the login on tab authenticated.
    This will result in an error thrown by the server because it received a valid session token without CSRF protection token.

How do I overcome this?


Edit:
Things get even worse if the user

  • does a login on tab 1 (user1)
  • opens tab 2
  • does a logout on tab 2
  • performs a new login on tab 2 (different user, user2)

In that case, the first tab provides the formerly valid CSRF token of user1 but the submitted session cookie belongs to user2 logged in on tab 2. This must lead to an error issued by the CSRF protection (by the way, in terms of HTTP error codes: what to use? 403 looks as if it could be used but I'm unsure).

Feeling now like the whole CSRF thing could be solved very nice in theory but could use some thinking in times of AJAX.

Is there any canonical solution for the issue described above? Or do users simply accept that they have to reload a page due to security-thingies-don't-match stuff?

eckes
  • 438
  • 1
  • 4
  • 13

2 Answers2

3

You could have a flag in your anonymous requests to let them know they are always treated as anonymous, despite the presence of the authentication cookie.

e.g. { "Anon" : "true" }

This will always cause the public results of the request to be returned and no auth cookie or CSRF request token will be considered in the logic.

SilverlightFox
  • 33,408
  • 6
  • 67
  • 178
  • Unless you were careful, wouldn't this just introduce a client-side way of disabling the check? You would have to mark some server side end points to explicitly allow the 'disable' behaviour. – JT. Dec 17 '13 at 01:20
  • Yes, this would have to be implemented properly. The `Anon` flag would need to cause the request to effectively be treated as unauthenticated. – SilverlightFox Dec 17 '13 at 10:05
0

As far as I've seen, all browsers tabs and open windows to the same website share the same cookie data. A cookie set in one tab is visible in all other tabs.

With regards to CSRF protection in a HTTP POST action there is a value embedded in the HTML output. You could include a value in HTML that gets POSTed back that can tell the back end to ignore any authentication token that may be present.

You would have to add this HTML token to each and every webpage that uses CSRF protection, and update every Javascript POST to send this value when dealing with service requests.

It's a bit hairy, depending on how complex your site is, but it can be done.

makerofthings7
  • 50,090
  • 54
  • 250
  • 536