views:

7419

answers:

3

I am running into some issues regarding Authenticity Token in rails, as I did many times now. But I really don't want to just solve this problem and go on, I would really like to understand Authenticity token. Well, my question is, do you have some complete source of information on this subject or would spend your time to explain in details here?

This is my last resource before going to the source code :-)

+11  A: 

The authenticity token is designed so that you know your form is being submitted from your website. It is generated from the machine on which it runs with a unique identifier that only your machine can know, thus helping prevent cross-site scripting hacks.

If you are simply having difficulty with rails denying your AJAX script access, you can use

<%= form_authenticity_token %>

to generate the correct token when you are creating your form.

You can read more about it in the documentation.

Topher Fangio
+2  A: 

The Authenticity Token is rails' method to prevent 'cross-site request forgery (CSRF or XSRF) attacks'.

To put it simple, it makes sure that the PUT / POST / DELETE (methods that can modify content) requests to your web app are made from the client's browser and not from a third party (an attacker) that has access to a cookie created on the client side.

andi
+59  A: 

What happens: When the user views a form to create, update, or destroy a resource, the rails app would create a random authenticity_token, store this token in the session, and place it in a hidden field in the form. When the user submits the form, rails would look for the authenticity_token, compare it to the one stored in the session, and if they match the request is allowed to continue.

Why this happens: Since the authenticity token is stored in the session, the client can not know its value. This prevents people from submitting forms to a rails app without viewing the form within that app itself. Imagine that you are using service A, you logged into the service and everything is ok. Now imagine that you went to use service B, and you saw a picture you like, and pressed on the picture to view a larger size of it. Now, if some evil code was there at service B, it might send a request to service A (which you are logged into), and ask to delete your account, by sending a request to http://service%5FA.com/close%5Faccount. This is what is known as CSRF (Cross Site Request Forgery).

If service A is using authenticity tokens, this attack vector is no longer applicable, since the request from service B would not contain the correct authenticity token, and will not be allowed to continue.

Notes: Keep in mind, rails only checks POST, PUT, and DELETE requests. GET request are not checked for authenticity token. Why? because the HTTP specification states that GET requests should NOT create, alter, or destroy resources at the server, and the request should be idempotent (if you run the same command multiple times, you should get the same result every time).

Lessons: Use authenticity_token to protect your POST, PUT, and DELETE requests. Also make sure not to make any GET requests that could potentially modify resources on the server.

Faisal
+1 this is very helpful!
yuval
the best explanation on CSRF
lakshmanan
+1 for the exaplanation about CSRF
Agusti-N
@Faisal, is it possible then, for an attacker to simply read/capture the 'hidden' element of the form for Service A and get that unique token generated for the user - given that they have gotten access to the session started by the user for Service A?
marcamillion
For instance by hijacking the data returned from a debug function? Just a thought.
marcamillion
@marcamillion: If somebody hijacked your session at service A, then the authenticity token won't protect you. The hijacker will be able to submit a request and it will be allowed to proceed.
Faisal
@Faisal, that's what I thought. So just wanted to confirm that. Thanks.
marcamillion