3

I'm building an application that uses a lot of ajax. Most anti-CSRF solutions revolve around putting some info in the viewstate and working with that data on post. However, I don't have access to the viewstate in an ajax call.

I plan to generate a GUID to insert a token in the cookie and the session state, make the cookie expire when the user logs out, modify the cookie token and session state at each request, and use an httpmodule to do the work by comparing what in the session with what's coming back from the client, before going to the web service or page method.

Will this make my app CSRF proof?

Thanks.

Charles
  • 50,943
  • 13
  • 104
  • 142
frenchie
  • 51,731
  • 109
  • 304
  • 510
  • 5
    No. Start by reading [Cross-site Request Forgery](http://en.wikipedia.org/wiki/Cross-site_request_forgery). "**If Bob's bank keeps his authentication information in a cookie**, and if the cookie hasn't expired, then the attempt by Bob's browser to load the image will submit the withdrawal form with his cookie, thus authorizing a transaction without Bob's approval." The problem is the browser always has the "valid cookie". However, the GUID/nonce could be transmitted via other means... which is effectively what it is in the viewstate. –  Nov 24 '11 at 07:19
  • 1
    @pst +1. Cookies are what allow CSRF to work in the first place... – Thilo Nov 24 '11 at 07:26
  • @Thilo: ok, thanks for the clarification:) Guess the unintended purpose of the question is to clarify and simplify the problem. – frenchie Nov 24 '11 at 18:50
  • I'd avoid GUIDs. They're not guaranteed to be unpredictable. Use a secure PRNG. – CodesInChaos Nov 29 '11 at 11:07
  • @CodeInChaos: ok, thanks for the tip. – frenchie Nov 30 '11 at 03:37
  • A GUID/UUID v4 generator that is not based on secure PRNG is a problem waiting to happen. A properly generated UUID v4 id is totally ok to be be used for CSRF protection (it contains 122 random bits). I agree that UUID v1 must not be used for CSRF protection. – Mikko Rantalainen Jun 04 '13 at 11:55

1 Answers1

11

No. "anti-CSRF" and "cookie" do not go together. As Thilo so concisely points out:

Cookies are what allow CSRF to work in the first place...

A good initial read is Cross-Site Request Forgery article, which sums most of CSRF up with:

If Bob's bank keeps his authentication information in a cookie, and if the cookie hasn't expired, then the attempt by Bob's browser to load the image will submit the withdrawal form with his cookie, thus authorizing a transaction without Bob's approval.

The problem is the browser always has the "valid cookie". However, the GUID -- really, just a nonce -- could be transmitted back to the server via other means... which is effectively what it is in the view-state.

CSRF Prevention mechanism #1 (per Wikipedia):

Requiring a secret, user-specific token in all form submissions and side-effect URLs prevents CSRF; the attacker's site cannot put the right token in its submissions.

The important thing is this secret (hopefully nonce to avoid replay attacks) is part of the data (URI or content) being sent and not transmitted via a cookie.

Happy coding.


Consider that one way this could be implemented:

Have the server generate a nonce when a session is established (and store it in session data). Then on each AJAX request send this nonce back -- either as part of the URI or as some POST data*.

The server server should accept/reject the request based only on this nonce and if it matched the nonce stored in the session state. (The session state can be maintained via cookies: it is the nonce transmitted via a different channel that will prevent this CSRF, assuming the nonce is secret.)

The nonce can be transmitted to the client in several ways including, but not limited to, a hidden field, a JavaScript variable, direct link manipulation, or even a cookie (read only! not for validation!).

*Of course, there are many overlapping security issues (and prevention mechanisms) at play and a simple XSS could bypass the most elaborate anti-CSFR. It may be worth considering using a well-tested framework...

  • ok, thanks for your feedback! So cookies are no-no, thanks for making that clear. The goal is to transfer the info via ANOTHER mean. This post http://www.codethinked.com/asp.net-mvc-ajax-csrf-protection-with-jquery-1.5 suggests using the headers as the transit mechanism. Some say that users can/do remove the headers. What's your opinion on this technique. Thanks. – frenchie Nov 24 '11 at 18:47
  • 1
    Don't have an opinion on the header technique, but just to clarify: It is not a problem that users themselves can mess with their own request headers, it would be problem if that can be done by an attacker on the user's behalf (without their knowledge, against their wishes). That is the general problem of the "confused deputy". – Thilo Nov 25 '11 at 01:04
  • Ok, the problem in my case is that there doesn't seem to be many options for securing ajax requests. – frenchie Nov 25 '11 at 06:49