javascriptruby-on-railsrubyauthenticity-token

Ruby on Rails: Difference of Authenticity Token being in Header or POST


I've just noticed it doesn't matter where I put my Authenticity Token when submitting a request via AJAX. I can either append it to the form as POST data, or put it into the Header.

Is there any difference? Especially regarding security?

Additionally:

I didn't encode the Token in Javascript. Am I exposed to something now?

Thanks in advance.

EDIT:

form.on("sending", function(file, xhr, formData) {
   xhr.setRequestHeader('X-CSRF-Token', AUTH_TOKEN);
   // formData.append('authenticity_token', AUTH_TOKEN);
});

This is my Javascript adding the token to the Header or (commented out) to the POST data. AUTH_TOKEN is the raw key. I did not encode it in any way.


Solution

  • Part one

    There is totally no difference if you pass authenticity token via GET params, POST data or request headers (POST/GET params are virtually the same in Rails).

    Let's look at the code (not the best code I've ever seen but...)

    def verified_request?
      !protect_against_forgery? || request.get? || request.head? ||
        form_authenticity_token == params[request_forgery_protection_token] ||
        form_authenticity_token == request.headers['X-CSRF-Token']
    end
    

    Request if valid if (any of following)

    1. protect_against_forgery? is false
    2. request is GET
    3. request is HEAD
    4. token in params equals one stored in session
    5. token in headers equals one stored in session

    I should add that token is generated for every request and stored in session for later inspection (if subsequent request is POST/PUT/PATCH/DELETE)

    So as you see both ways of passing authenticity token are valid.

    Part two

    Is passing raw auth token in AJAX dangerous? No, as much as passing it in a form is totally not dangerous. To explain further I will quote an excellent answer in another SO question

    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://serviceA.com/close_account. This is what is known as CSRF (Cross Site Request Forgery).

    original answer: https://stackoverflow.com/a/1571900/2422778

    I still consider this question laziness/lack of patience on your side as all I wrote is very well explained both in Rails Guides and on Stack Overflow. Hope next time you will be more persistent in looking for answers before posting here.
    Anyway I am glad I could help.