Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 3 AJAX request authenticity token ignored

Rails seems to be ignoring authenticity tokens for AJAX requests. For instance, I purposely changed my AJAX call to test this with an invalid token and requests seem to go through normally.

The application has the default configuration to use session cookie store and has the protect_from_forgery call in the ApplicationController.

Any ideas what else I could be missing?

like image 552
zzawaideh Avatar asked Nov 06 '10 03:11

zzawaideh


1 Answers

EDIT >> I posted this answer in a blog post as well: http://zadasnotes.blogspot.com/2010/11/rails-3-forgery-csrf-protection-for.html [archive.org]

EDIT 2 >> This was changed in Rails 3.0.4. See follow up post here: http://zadasnotes.blogspot.com/2011/02/rails-forgery-csrf-protection-for-ajax.html [archive.org]

After researching it for a while, I decided to dig a bit into the rails code documentation to find out.

Starting here: http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection.html#method-i-form_authenticity_token

protect_from_forgery adds a before_filter on verify_authenticity_token which is shown below:

# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 95
95:       def verify_authenticity_token
96:         verified_request? || raise(ActionController::InvalidAuthenticityToken)
97:       end

And the verified_request? is shown here:

# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line   
104:       def verified_request?
105:         !protect_against_forgery? || request.forgery_whitelisted? ||
106:           form_authenticity_token == params[request_forgery_protection_token]
107:       end

Finally request.forgery_whitelisted?:

   # File actionpack/lib/action_dispatch/http/request.rb, line 126
126:     def forgery_whitelisted?
127:       get? || xhr? || content_mime_type.nil? || !content_mime_type.verify_request?
128:     end

Notice xhr?. xmlHttpRequest is whitelisted and is not on the protect_from_forgery list. So it appears that this is by design.

After researching further on xmlHttpRequests it appears that there are restrictions on running them across domains, which makes it unnecessary to apply the csrf check on xhr.

like image 167
zzawaideh Avatar answered Nov 15 '22 00:11

zzawaideh