diff options
Diffstat (limited to 'actionpack')
-rw-r--r-- | actionpack/lib/action_controller/metal/request_forgery_protection.rb | 9 | ||||
-rw-r--r-- | actionpack/test/controller/request_forgery_protection_test.rb | 10 |
2 files changed, 17 insertions, 2 deletions
diff --git a/actionpack/lib/action_controller/metal/request_forgery_protection.rb b/actionpack/lib/action_controller/metal/request_forgery_protection.rb index 8cdb9a7655..c88074d4c6 100644 --- a/actionpack/lib/action_controller/metal/request_forgery_protection.rb +++ b/actionpack/lib/action_controller/metal/request_forgery_protection.rb @@ -190,7 +190,7 @@ module ActionController #:nodoc: # verify that JavaScript responses are for XHR requests, ensuring they # follow the browser's same-origin policy. def verify_authenticity_token - @marked_for_same_origin_verification = true + mark_for_same_origin_verification! if !verified_request? logger.warn "Can't verify CSRF token authenticity" if logger @@ -218,10 +218,15 @@ module ActionController #:nodoc: end end + # GET requests are checked for cross-origin JavaScript after rendering. + def mark_for_same_origin_verification! + @marked_for_same_origin_verification = request.get? + end + # If the `verify_authenticity_token` before_action ran, verify that # JavaScript responses are only served to same-origin GET requests. def marked_for_same_origin_verification? - defined? @marked_for_same_origin_verification + @marked_for_same_origin_verification ||= false end # Check for cross-origin JavaScript responses. diff --git a/actionpack/test/controller/request_forgery_protection_test.rb b/actionpack/test/controller/request_forgery_protection_test.rb index f1ed545205..1f5fc06410 100644 --- a/actionpack/test/controller/request_forgery_protection_test.rb +++ b/actionpack/test/controller/request_forgery_protection_test.rb @@ -305,6 +305,16 @@ module RequestForgeryProtectionTests end end + # Allow non-GET requests since GET is all a remote <script> tag can muster. + def test_should_allow_non_get_js_without_xhr_header + assert_cross_origin_not_blocked { post :same_origin_js, custom_authenticity_token: @token } + assert_cross_origin_not_blocked { post :same_origin_js, format: 'js', custom_authenticity_token: @token } + assert_cross_origin_not_blocked do + @request.accept = 'text/javascript' + post :negotiate_same_origin, custom_authenticity_token: @token + end + end + def test_should_only_allow_cross_origin_js_get_without_xhr_header_if_protection_disabled assert_cross_origin_not_blocked { get :cross_origin_js } assert_cross_origin_not_blocked { get :cross_origin_js, format: 'js' } |