aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVipul A M <vipulnsward@gmail.com>2016-02-18 17:38:19 +0530
committerVipul A M <vipulnsward@gmail.com>2016-02-21 23:20:55 +0530
commit92203d754f535c01c5ec3175627425d20e3d2839 (patch)
treed699582ee11ce7e5c1fbec4310527a033d87a05d
parent3156a7692c3c51adb846252192364172b05bd67f (diff)
downloadrails-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.rb44
-rw-r--r--actionview/lib/action_view/helpers/url_helper.rb4
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