Permalink
Browse files

Don't check authenticity tokens for any AJAX requests

  • Loading branch information...
Ross Kaffenburger and Bryan Helmkamp authored and lifo committed Mar 4, 2009
1 parent 60122e8 commit 523f3ba8daf4968267eb4597bc88359a6337cf90
View
@@ -7,6 +7,8 @@
* Fixed that redirection would just log the options, not the final url (which lead to "Redirected to #<Post:0x23150b8>") [DHH]
* Don't check authenticity tokens for any AJAX requests [Ross Kaffenberger/Bryan Helmkamp]
* Added ability to pass in :public => true to fresh_when, stale?, and expires_in to make the request proxy cachable #2095 [Gregg Pollack]
* Fixed that passing a custom form builder would be forwarded to nested fields_for calls #2023 [Eloy Duran/Nate Wiger]
@@ -81,12 +81,13 @@ def verify_authenticity_token
# Returns true or false if a request is verified. Checks:
#
# * is the format restricted? By default, only HTML and AJAX requests are checked.
# * is the format restricted? By default, only HTML requests are checked.
# * is it a GET request? Gets should be safe and idempotent
# * Does the form_authenticity_token match the given token value from the params?
def verified_request?
!protect_against_forgery? ||
request.method == :get ||
request.xhr? ||
!verifiable_request_format? ||
form_authenticity_token == params[request_forgery_protection_token]
end
@@ -151,14 +151,10 @@ def test_should_not_allow_api_formatted_delete_sent_as_multipart_form_without_to
delete :index, :format => 'xml'
end
end
def test_should_allow_xhr_post_without_token
assert_nothing_raised { xhr :post, :index }
end
def test_should_not_allow_xhr_post_with_html_without_token
@request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s
assert_raise(ActionController::InvalidAuthenticityToken) { xhr :post, :index }
end
def test_should_allow_xhr_put_without_token
assert_nothing_raised { xhr :put, :index }
@@ -168,6 +164,11 @@ def test_should_allow_xhr_delete_without_token
assert_nothing_raised { xhr :delete, :index }
end
def test_should_allow_xhr_post_with_encoded_form_content_type_without_token
@request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s
assert_nothing_raised { xhr :post, :index }
end
def test_should_allow_post_with_token
post :index, :authenticity_token => @token
assert_response :success

4 comments on commit 523f3ba

@mixonic

This comment has been minimized.

Show comment
Hide comment
@mixonic

mixonic Jul 28, 2009

Oh yeah? That's a big security change.

mixonic replied Jul 28, 2009

Oh yeah? That's a big security change.

@norbert

This comment has been minimized.

Show comment
Hide comment
@norbert

norbert Jul 28, 2009

Contributor

This has been discussed before, apparently it doesn't matter because of JavaScript's same origin policy.

Contributor

norbert replied Jul 28, 2009

This has been discussed before, apparently it doesn't matter because of JavaScript's same origin policy.

@jcoglan

This comment has been minimized.

Show comment
Hide comment
@jcoglan

jcoglan Jul 28, 2009

Contributor

True, it doesn't matter. XHR is detected using the X-Requested-With HTTP header. The type of attack that tokens prevent are caused by external sites making a fake request to your site by getting the user to click a link or submit a form, neither of which has the capacity to set headers. In fact XMLHttpRequest is the only client-side request mechanism that can set headers, and browser make sure it only talks to the current page's domain. Basically, if a request has custom headers set, it's either XHR from your own site or it's a request from another server-side program.

Contributor

jcoglan replied Jul 28, 2009

True, it doesn't matter. XHR is detected using the X-Requested-With HTTP header. The type of attack that tokens prevent are caused by external sites making a fake request to your site by getting the user to click a link or submit a form, neither of which has the capacity to set headers. In fact XMLHttpRequest is the only client-side request mechanism that can set headers, and browser make sure it only talks to the current page's domain. Basically, if a request has custom headers set, it's either XHR from your own site or it's a request from another server-side program.

@NZKoz

This comment has been minimized.

Show comment
Hide comment
@NZKoz

NZKoz Jul 28, 2009

Member

Right,

the presence of a custom header in a request is (as per the stanford CSRF paper) considered to be sufficient proof that it originated from you. This doesn't apply if you have a permissive crossdomain.xml file for flash, but if you have that you're screwed anyway.

Member

NZKoz replied Jul 28, 2009

Right,

the presence of a custom header in a request is (as per the stanford CSRF paper) considered to be sufficient proof that it originated from you. This doesn't apply if you have a permissive crossdomain.xml file for flash, but if you have that you're screwed anyway.

Please sign in to comment.