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.
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...