/ mass-assignment

Mass Assignment in Rails 3

What is Mass Assignment?

Assigning multiple attributes of a record with params received from the application within a single query.

For example,{:user => {:first_name => "FirstName", :last_name => "LastName", :role => "admin"}}

So while creating a new record in User table, we specify as => User.create(params[:user])
In the above query, rails gives the freedom for one-to-one mapping of params attributes with model-record attributes. Lets say, we don't explicitly specify as User.create(:first_name => params[:user][:first_name], :last_name => params[:user][:last_name].......).

Such assignments also does works with .new(), and .update_attributes() methods.

In a nutshell, these methods allow assignments of attributs in bulk.

How is it vulnerable?

Mass assignments are straightforward. Because one don’t have to set each value individually. Simply passing hash to above methods, all the work is done.
But the problem is the parameters passed to controller is easily accessible even to attacker.

Ex: {:user => {:first_name => "FirstName", :last_name => "LastName", :role => "user"}} can be fiddled as {:user => {:first_name => "FirstName", :last_name => "LastName", :role => "admin"}}

Hence, normal user can gain an access of Admin.

Model-level declaration::

  1. " attr_accessible " says "the specified attributes are accessible and all others are protected"
  2. " attr_protected " says "the specified attributes are protected and all others are accessible"

    Above model-level accessibility are exactly opposite to each other.

    A bit safer protection is provided by " attr_accessible " because it's less about making an attribute accessible and more about making it inaccessible.

Hence, an update has been added to Rails to whitelist by default:

In config/application.rb,

config.active_record.whitelist_attributes = true.

This will by default protect model attributes in case of mass assignments. If one needs to add model-attributses in mass assignment, just declaring " attr_accessible " will do the work.