aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionpack/CHANGELOG.md10
-rw-r--r--actionpack/lib/action_controller/metal/request_forgery_protection.rb4
-rw-r--r--actionpack/lib/action_controller/railtie.rb8
-rw-r--r--guides/source/configuring.md2
-rw-r--r--railties/lib/rails/application/configuration.rb4
-rw-r--r--railties/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb.tt3
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_5_2.rb.tt4
-rw-r--r--railties/test/application/configuration_test.rb7
-rw-r--r--railties/test/application/rake_test.rb2
9 files changed, 40 insertions, 4 deletions
diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md
index f8fd2403ef..59a7f12ac6 100644
--- a/actionpack/CHANGELOG.md
+++ b/actionpack/CHANGELOG.md
@@ -1,3 +1,13 @@
+* Protect from forgery by default
+
+ Rather than protecting from forgery in the generated ApplicationController,
+ add it to ActionController::Base depending on
+ `config.action_controller.default_protect_from_forgery`. This configuration
+ defaults to false to support older versions which have removed it from their
+ ApplicationController, but is set to true for Rails 5.2.
+
+ *Lisa Ugray*
+
* Fallback `ActionController::Parameters#to_s` to `Hash#to_s`.
*Kir Shatrov*
diff --git a/actionpack/lib/action_controller/metal/request_forgery_protection.rb b/actionpack/lib/action_controller/metal/request_forgery_protection.rb
index 4468cbb2fc..117dee2219 100644
--- a/actionpack/lib/action_controller/metal/request_forgery_protection.rb
+++ b/actionpack/lib/action_controller/metal/request_forgery_protection.rb
@@ -85,6 +85,10 @@ module ActionController #:nodoc:
config_accessor :per_form_csrf_tokens
self.per_form_csrf_tokens = false
+ # Controls whether forgery protection is enabled by default.
+ config_accessor :default_protect_from_forgery
+ self.default_protect_from_forgery = false
+
helper_method :form_authenticity_token
helper_method :protect_against_forgery?
end
diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb
index 31db7518f1..1c1cd58732 100644
--- a/actionpack/lib/action_controller/railtie.rb
+++ b/actionpack/lib/action_controller/railtie.rb
@@ -69,5 +69,13 @@ module ActionController
config.compile_methods! if config.respond_to?(:compile_methods!)
end
end
+
+ initializer "action_controller.request_forgery_protection" do |app|
+ ActiveSupport.on_load(:action_controller_base) do
+ if app.config.action_controller.default_protect_from_forgery
+ protect_from_forgery with: :exception
+ end
+ end
+ end
end
end
diff --git a/guides/source/configuring.md b/guides/source/configuring.md
index 21b3ca0efa..28ceef9740 100644
--- a/guides/source/configuring.md
+++ b/guides/source/configuring.md
@@ -401,6 +401,8 @@ The schema dumper adds one additional configuration option:
* `config.action_controller.per_form_csrf_tokens` configures whether CSRF tokens are only valid for the method/action they were generated for.
+* `config.action_controller.default_protect_from_forgery` determines whether forgery protection is added on `ActionController:Base`. This is false by default, but enabled when loading defaults for Rails 5.2.
+
* `config.action_controller.relative_url_root` can be used to tell Rails that you are [deploying to a subdirectory](configuring.html#deploy-to-a-subdirectory-relative-url-root). The default is `ENV['RAILS_RELATIVE_URL_ROOT']`.
* `config.action_controller.permit_all_parameters` sets all the parameters for mass assignment to be permitted by default. The default value is `false`.
diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb
index 7e1359c42b..d403c4fa7c 100644
--- a/railties/lib/rails/application/configuration.rb
+++ b/railties/lib/rails/application/configuration.rb
@@ -96,6 +96,10 @@ module Rails
active_support.use_authenticated_message_encryption = true
end
+ if respond_to?(:action_controller)
+ action_controller.default_protect_from_forgery = true
+ end
+
else
raise "Unknown version #{target_version.to_s.inspect}"
end
diff --git a/railties/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb.tt b/railties/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb.tt
index 413354186d..185c0017f1 100644
--- a/railties/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb.tt
@@ -1,5 +1,2 @@
class ApplicationController < ActionController::<%= options[:api] ? "API" : "Base" %>
-<%- unless options[:api] -%>
- protect_from_forgery with: :exception
-<%- end -%>
end
diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_5_2.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_5_2.rb.tt
index 3809936f9f..e8f5f964ed 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_5_2.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_5_2.rb.tt
@@ -17,3 +17,7 @@
# Use AES-256-GCM authenticated encryption as default cipher for encrypting messages
# instead of AES-256-CBC, when use_authenticated_message_encryption is set to true.
# Rails.application.config.active_support.use_authenticated_message_encryption = true
+
+# Add default protection from forgery to ActionController::Base instead of in
+# ApplicationController.
+# Rails.applocation.config.action_controller.default_protect_from_forgery = true
diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb
index 983ea5c3e6..6c0c087331 100644
--- a/railties/test/application/configuration_test.rb
+++ b/railties/test/application/configuration_test.rb
@@ -1209,6 +1209,13 @@ module ApplicationTests
assert_equal false, ActionController::Parameters.action_on_unpermitted_parameters
end
+ test "config.action_controller.default_protect_from_forgery is true by default" do
+ app "development"
+
+ assert_equal true, ActionController::Base.default_protect_from_forgery
+ assert_includes ActionController::Base.__callbacks[:process_action].map(&:filter), :verify_authenticity_token
+ end
+
test "config.action_controller.permit_all_parameters can be configured in an initializer" do
app_file "config/initializers/permit_all_parameters.rb", <<-RUBY
Rails.application.config.action_controller.permit_all_parameters = true
diff --git a/railties/test/application/rake_test.rb b/railties/test/application/rake_test.rb
index 5ae6ea925f..134106812d 100644
--- a/railties/test/application/rake_test.rb
+++ b/railties/test/application/rake_test.rb
@@ -117,7 +117,7 @@ module ApplicationTests
end
def test_code_statistics_sanity
- assert_match "Code LOC: 26 Test LOC: 0 Code to Test Ratio: 1:0.0",
+ assert_match "Code LOC: 25 Test LOC: 0 Code to Test Ratio: 1:0.0",
Dir.chdir(app_path) { `bin/rails stats` }
end