since there are several misunderstandings surrounding CSRF, which keep coming up, I was hoping to clear things up a bit and avoid confusion in the future.
Briefly, a CSRF attack means that you trick the browser of a privileged user into taking actions in their name. Let's say you target the member of an online shop. Then you could try to have the victim's browser buy products or change the user password to "123456" or whatever. If the application only checks the session ID, it will actually accept those requests, because the browser automaticalls sends the session ID in all requests.
Protecting against CSRF is actually pretty simple: When a user logs in or visits a form, you generate a random token. You store this token somewhere only you or your user has access to (like the session or a cookie or HTML5 Local Storage), and you also include it in the form. In the processing script, you retrieve the token from where you've stored it and compare it to the token sent with the request. If and only if they match, you accept the request.
This simple technique makes it impossible for somebody else to "forge" a request as decribed above. They may set up a form, but since they don't know what token to put in, the request will be rejected.
Now, there are several misunderstandings:
So anti-CSRF is not about making sure that a request comes from your own form. This is impossible to do and doesn't help you anyway. What you want is that nobody except the user can create a valid request. If the user decides to initiate the request from another website, that's fine. You just don't want anybody else to do it.
Secondly, the anti-CSRF token does not have to be stored in the session. It may very well be stored on the client in a cookie or HTML5 Local Storage or Web SQL or whatever. If you think that you'll run into the same problem you have with the session cookie (it automatically gets sent with each request), that's wrong. The cookie with the token does get sent. But in order to forge a request, you have to actually know it. And that's impossible due to the same origin policy (and if the cookie is set to HttpOnly). You can neither read nor set the cookie, which means you're out of luck setting up your malicious form. You just don't know which value to use in the "anti_csrf_token" field.
So it's perfectly fine to store the anti-CSRF token in a cookie (as long as you set it to HttpOnly). This doesn't break the protection at all. The only requirement for the token is that it can only be read and set by you and the user. And that's indeed the case for cookies.
In fact, it doesn't even make sense to claim that storing the token in a cookie is dangerous and at the same time promote storing it in a session. Since sessions are also cookie-based, they're also automatically opened whenever the user makes a request.