Skip to content

Commit

Permalink
Protect from forgery by default
Browse files Browse the repository at this point in the history
Rather than protecting from forgery in the generated
ApplicationController, add it to ActionController::Base by config. 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.
  • Loading branch information
Lisa Ugray committed Jul 10, 2017
1 parent b6300f3 commit ec4a836
Show file tree
Hide file tree
Showing 9 changed files with 40 additions and 4 deletions.
10 changes: 10 additions & 0 deletions actionpack/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ module RequestForgeryProtection
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
Expand Down
8 changes: 8 additions & 0 deletions actionpack/lib/action_controller/railtie.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,5 +69,13 @@ class Railtie < Rails::Railtie #:nodoc:
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
2 changes: 2 additions & 0 deletions guides/source/configuring.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand Down
4 changes: 4 additions & 0 deletions railties/lib/rails/application/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ def load_defaults(target_version)
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
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,2 @@
class ApplicationController < ActionController::<%= options[:api] ? "API" : "Base" %>
<%- unless options[:api] -%>
protect_from_forgery with: :exception
<%- end -%>
end
Original file line number Diff line number Diff line change
Expand Up @@ -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
7 changes: 7 additions & 0 deletions railties/test/application/configuration_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1209,6 +1209,13 @@ def create
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
Expand Down
2 changes: 1 addition & 1 deletion railties/test/application/rake_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def test_should_not_eager_load_model_for_rake
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

Expand Down

0 comments on commit ec4a836

Please sign in to comment.