diff options
author | Vipul A M <vipulnsward@gmail.com> | 2016-02-18 17:38:19 +0530 |
---|---|---|
committer | Vipul A M <vipulnsward@gmail.com> | 2016-02-21 23:20:55 +0530 |
commit | 92203d754f535c01c5ec3175627425d20e3d2839 (patch) | |
tree | d699582ee11ce7e5c1fbec4310527a033d87a05d | |
parent | 3156a7692c3c51adb846252192364172b05bd67f (diff) | |
download | rails-92203d754f535c01c5ec3175627425d20e3d2839.tar.gz rails-92203d754f535c01c5ec3175627425d20e3d2839.tar.bz2 rails-92203d754f535c01c5ec3175627425d20e3d2839.zip |
Fixed passing of delete method on button_to tag, creating wrong form csrf token
Fixes #23524
-rw-r--r-- | actionpack/test/controller/request_forgery_protection_test.rb | 44 | ||||
-rw-r--r-- | actionview/lib/action_view/helpers/url_helper.rb | 4 |
2 files changed, 46 insertions, 2 deletions
diff --git a/actionpack/test/controller/request_forgery_protection_test.rb b/actionpack/test/controller/request_forgery_protection_test.rb index 1984ad8825..6dc4f3fe51 100644 --- a/actionpack/test/controller/request_forgery_protection_test.rb +++ b/actionpack/test/controller/request_forgery_protection_test.rb @@ -136,6 +136,10 @@ class PerFormTokensController < ActionController::Base render inline: "<%= form_tag (params[:form_path] || '/per_form_tokens/post_one'), method: (params[:form_method] || :post) %>" end + def button_to + render inline: "<%= button_to 'Button', (params[:form_path] || '/per_form_tokens/post_one'), method: (params[:form_method] || :post) %>" + end + def post_one render plain: '' end @@ -710,6 +714,46 @@ class PerFormTokensControllerTest < ActionController::TestCase end end + def test_rejects_token_for_incorrect_method_button_to + get :button_to, params: { form_method: 'delete' } + + form_token = nil + assert_select 'input[name=custom_authenticity_token]' do |elts| + form_token = elts.first['value'] + assert_not_nil form_token + end + + actual = @controller.send(:unmask_token, Base64.strict_decode64(form_token)) + expected = @controller.send(:per_form_csrf_token, session, '/per_form_tokens/post_one', 'delete') + assert_equal expected, actual + + # This is required because PATH_INFO isn't reset between requests. + @request.env['PATH_INFO'] = '/per_form_tokens/post_one' + assert_raises(ActionController::InvalidAuthenticityToken) do + patch :post_one, params: { custom_authenticity_token: form_token } + end + end + + def test_accepts_proper_token_for_delete_method_button_to + get :button_to, params: { form_method: 'delete' } + + form_token = nil + assert_select 'input[name=custom_authenticity_token]' do |elts| + form_token = elts.first['value'] + assert_not_nil form_token + end + + actual = @controller.send(:unmask_token, Base64.strict_decode64(form_token)) + expected = @controller.send(:per_form_csrf_token, session, '/per_form_tokens/post_one', 'delete') + assert_equal expected, actual + + # This is required because PATH_INFO isn't reset between requests. + @request.env['PATH_INFO'] = '/per_form_tokens/post_one' + assert_nothing_raised do + delete :post_one, params: { custom_authenticity_token: form_token } + end + end + def test_accepts_global_csrf_token get :index diff --git a/actionview/lib/action_view/helpers/url_helper.rb b/actionview/lib/action_view/helpers/url_helper.rb index 87218821ed..4d82cbd469 100644 --- a/actionview/lib/action_view/helpers/url_helper.rb +++ b/actionview/lib/action_view/helpers/url_helper.rb @@ -311,8 +311,8 @@ module ActionView form_options[:action] = url form_options[:'data-remote'] = true if remote - request_token_tag = if form_method == 'post' - token_tag(nil, form_options: form_options) + request_token_tag = if (form_method == 'post' || method == 'delete') + token_tag(nil, form_options: form_options.merge(method: method)) else '' end |