John H
John H

Reputation: 2488

Is CSRF Protection necessary on a sign-up form?

Rails automatically adds CSRF protection to all forms by default by adding an authentication_token to all forms generated by the site.

I'd really like my site to have a simple sign up form on the front page of the site, which of course would be a static HTML page. This would ideally avoid hitting the Rails stack at all, allowing me to serve far more requests to the front page.

The downside of this is that it makes CSRF protection more difficult.

But I'm wondering if it is really necessary to have CSRF protection on a sign-up form, considering that CSRF attacks typically depend on the victim being logged in so that trust can be exploited. The sign-up form would log the user in if it validates correctly, but I don't think that would be any use to an attacker.

Is there an established view on this or a work-around using Rails/jQuery?

Upvotes: 41

Views: 13009

Answers (6)

f4der
f4der

Reputation: 731

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 ;)

Upvotes: 18

mayankcpdixit
mayankcpdixit

Reputation: 2464

Yes, So other websites can't mimic your sign-up form! As simple as that.

What can they achieve by doing it?

  • First: you don't wanna allow that. you wanna own where requests come from.
  • Second: False alerts can be blocked.
  • Third: If you allow auto login post sign up it's as vulnerable as login form csrf

Upvotes: 0

tmendo
tmendo

Reputation: 9

Generically speaking its a good idea to protect your registration forms against CSRF attacks. Consider Google Search, and suppose the login form is protected against CSRF but the registration form is vulnerable. An attacker can force a victim to register a new account with credentials the attacker knows, and from that moment on any search the victim does will also be visible to the attacker, because he knows the credentials to log in the victims account. This assumes the vulnerable site immediately logs in the user after registration.

Other scenario, with email providers, is to create accounts for spam purposes. An attacker can force victims to create new accounts, with a CSRF in the registration form, and use those accounts to send spam. The idea is to defeat security mechanisms that throttle account creation based on IP or country.

However, in a specific scenario, it might not possible to exploit a vulnerable registration form, but this kind of analysis might be hard for a non-expert in the subject. Its a good idea to protect the form, but there aren't many scenarios where a successful attack can be create thus the risk is normally low.

Upvotes: 0

ss ulrey
ss ulrey

Reputation: 310

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?" :)

Upvotes: 3

Alex Ghiculescu
Alex Ghiculescu

Reputation: 7540

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.

Upvotes: 2

Dennis Hackethal
Dennis Hackethal

Reputation: 14285

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.

Upvotes: 19

Related Questions