Is CSRF Protection necessary on a sign-up form?

If you want to cache the front page but still have CSRF protection (which is probably a good idea, as Charles said) you could inject the appropriate authenticity token via Javascript once the page has loaded.

There's some info about this at http://broadcastingadam.com/2011/05/advanced_caching_in_rails/ under the "CSRF and form_authenticty_token" header. The relevant code is:

$("meta[name='csrf-token']").attr('content', '<% Rack::Utils.escape_html(request_forgery_protection_token) %>');
$("meta[name='csrf-param']").attr('content', '<% Rack::Utils.escape_html(form_authenticity_token) %>');

With this technique, you can cache your entire homepage, at the cost of all clients making an additional (but very small, and quick) request to get this auth token.


No, for this specific situation not. A CSRF attack allows an attacker to exploit the rights that a victim has, e.g. bank.com/pay?ammount=1000&to=34.67.978.246

It makes no sense to attack the log in form, since an attacker can log in by himself if he has the information that is required for a succesfull attack on the login field (the username and password).

The reason why Rails uses CSRF protection on the login field is simple: it's much more simple to implement CSRF protection globally than for 95% of the fields ;)


It seems to me that there is little technical reason to be concerned about csrf from a sign-up form. Attacker could trick someone into creating a new account on your site - if the victim then used your site, the attacker could spy on their actions since he would also have access to the account?

The more likely risk is probably non-technical. When your site gets a security audit, you'll have to explain why csrf isn't a risk here... and proving a negative is difficult... "Appscan has flagged this as a critical security hole - why don't you fix it? Why can't you have a nice clean report like Charles?" :)


On CSRF

First, one has to make clear what CSRF actually is.

Cross site request forgery is a type of malicious exploit of a website whereby unauthorized commands are transmitted from a user that the website trusts.

Consider this following example: A hacker knows that you have an account on www.example.com, and let's say that's a website you have logged into and still have a valid session running. Now the hacker can lure you into opening another website, say trustme.com, on which he has posted an image with the following code:

<img src="http://www.example.com/users/delete"/>

If the programmers of www.example.com actually made it possible to delete your account through that URL with a simple GET request and the hacker knows that, simply viewing and loading that image with your valid cookie will delete your account on example.com, even though you were only surfing trustme.com and it seemed like these two sites had nothing to do with each other.

To summarize this example, CSRF exploits the trust that a site has in a user's browser, in this case the trust that www.example.com had in your browser.

To use that analogy for your case would mean to exploit your site's trust in the user's browser - but that trust hasn't been established yet, because the user has not logged in yet when he sees your form. You have to make sure, though, that the user gets redirected when already logged in and trying to load the page with that form again, because otherwise that established trust can be exploited.

So, as a rule of thumb, whenever you use cookies and sessions for requests to validate a user, i.e. to confirm or establish trust in a user, use CSRF protection. Since you want to establish trust in your user when he signs up, the same applies.

Unfortunately, CSRF attacks are not limited to only that. I found out about two other things that can happen (and it is certainly not limited to that):

1.: The following is a nifty example of spying on your account, made possible by omitted CSRF protection on login forms:

  1. The hacker creates an account on a website you actually trust (youtrustthis.com)
  2. He forges a login request from your browser with his own credentials and tricks you into using his account
  3. If you don't notice that you were actually surfing youtrustthis.com as another user, the attacker will later see what you did "on his behalf", which is pretty much spying on you

2.: Without CSRF protection, a hacker can mimic your login or sign up form in his own html document and conveniently submit it again and again (or just do it using curl from the terminal) without the trusted site noticing that the requests do not actually come from itself - i.e., the actual login form on the trusted domain never having been displayed in your browser and not being submitted from there. This enables him to perform brute force attacks much easier. If the malicious user succeeds in trying to find out the credentials, your server will respond with a valid session cookie and trust that user, by which he steals your identity. If it is a sign up form, he will be able to sign up massive amounts of accounts and thereby spam your database.

To summarize this: Go with CSRF protection. A malicious user can very much use unsecured login and sign up forms to misuse your site and spy on your users or steal their identities.

For more information, also refer to this similar question (for login forms) and this academic paper. The latter has a dedicated chapter on login CSRF on page 3. Also, check out this CSRF prevention cheat sheet.

On potential workarounds

Since CSRF protection uses sessions to compare the token generated on the server-side with the one that was submitted from a form, I cannot think of a way to do this only client side, i.e. without hitting the Rails stack. The whole point is that the client only receives the token after it gets generated server side.