Skip to content

Commit

Permalink
added config.active_record.whitelist_attributes which creates an empt…
Browse files Browse the repository at this point in the history
…y whitelist of attributes available for mass assignment for all models in your app
  • Loading branch information
joshk committed Apr 24, 2011
1 parent b3ba368 commit f3b9d3a
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 3 deletions.
3 changes: 3 additions & 0 deletions activerecord/lib/active_record/railtie.rb
Expand Up @@ -50,6 +50,9 @@ class Railtie < Rails::Railtie

initializer "active_record.set_configs" do |app|
ActiveSupport.on_load(:active_record) do
if app.config.active_record.delete(:whitelist_attributes)
attr_accessible(nil)
end
app.config.active_record.each do |k,v|
send "#{k}=", v
end
Expand Down
2 changes: 2 additions & 0 deletions railties/guides/source/configuring.textile
Expand Up @@ -229,6 +229,8 @@ h4. Configuring Active Record

* +config.active_record.lock_optimistically+ controls whether ActiveRecord will use optimistic locking. By default this is +true+.

* +config.active_record.whitelist_attributes+ will create an empty whitelist of attributes available for mass-assignment security for all models in your app.

The MySQL adapter adds one additional configuration option:

* +ActiveRecord::ConnectionAdapters::MysqlAdapter.emulate_booleans+ controls whether ActiveRecord will consider all +tinyint(1)+ columns in a MySQL database to be booleans. By default this is +true+.
Expand Down
6 changes: 3 additions & 3 deletions railties/guides/source/security.textile
Expand Up @@ -459,13 +459,13 @@ When assigning attributes in Active Record using +new+, +attributes=+, or +updat
@user.is_admin # => true
</ruby>

A more paranoid technique to protect your whole project would be to enforce that all models whitelist their accessible attributes. This can be easily achieved with a very simple initializer:
A more paranoid technique to protect your whole project would be to enforce that all models define their accessible attributes. This can be easily achieved with a very simple application config option of:

<ruby>
ActiveRecord::Base.send(:attr_accessible, nil)
config.active_record.whitelist_attributes = true
</ruby>

This will create an empty whitelist of attributes available for mass assignment for all models in your app. As such, your models will need to explicitly whitelist accessible parameters by using an +attr_accessible+ declaration. This technique is best applied at the start of a new project. However, for an existing project with a thorough set of functional tests, it should be straightforward and relatively quick to insert this initializer, run your tests, and expose each attribute (via +attr_accessible+) as dictated by your failing tests.
This will create an empty whitelist of attributes available for mass-assignment for all models in your app. As such, your models will need to explicitly whitelist or blacklist accessible parameters by using an +attr_accessible+ or +attr_protected+ declaration. This technique is best applied at the start of a new project. However, for an existing project with a thorough set of functional tests, it should be straightforward and relatively quick to use this application config option; run your tests, and expose each attribute (via +attr_accessible+ or +attr_protected+) as dictated by your failing tests.

h3. User Management

Expand Down
12 changes: 12 additions & 0 deletions railties/test/application/configuration_test.rb
Expand Up @@ -258,6 +258,18 @@ def index
assert_equal res, last_response.body # value should be unchanged
end

test "sets all Active Record models to whitelist all attributes by default" do
add_to_config <<-RUBY
config.active_record.whitelist_attributes = true
RUBY

require "#{app_path}/config/environment"

assert_equal ActiveModel::MassAssignmentSecurity::WhiteList,
ActiveRecord::Base.active_authorizers[:default].class
assert_equal [""], ActiveRecord::Base.active_authorizers[:default].to_a
end

test "registers interceptors with ActionMailer" do
add_to_config <<-RUBY
config.action_mailer.interceptors = MyMailInterceptor
Expand Down

2 comments on commit f3b9d3a

@josevalim
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May I ask why a configuration option? What is the use case?

@josevalim
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ugh, nevermind. I see the main use case is to set all attributes as protected by default. +1

Please sign in to comment.