Mass-Assignment Is Going to Bite You

This post will be brief because this topic has been covered many times before. But it's so important that I wanted to add this post to the Google index.

The mass-assignment methods

In Rails, attributes= is the main method used for mass-assignment. attributes= is used behind the scenes by others like new, create, and update_attributes as well. In typical usage, your controller would utilize one of these methods while passing in params directly.

Example:

   1  def create
   2    @user = User.new(params[:user])
   3    if @user.save
   4      ...
   5    end
   6  end

The problem

In this example, anything that is in params will be passed through to the User model, including attributes that you may not include in your form.

Example from the RailsCast:

   1  Parameters:
   2  { "user" => { "name" => "hacker", "admin" => "1" } }

Additionally, ActiveRecord includes many dynamically created methods for your associations, such as association_id=, and association_ids= that are available for mass-assignment.

Consider this situation:

   1  class User < ActiveRecord::Base
   2    has_many :credit_cards
   3  end
   4 
   5  Parameters:
   6  { "id" => 123,
   7    "user" => { "name" => "hacker",
   8                "credit_card_ids" => ["1", "2", "3"] } }

The user just assigned credit cards 1, 2, and 3 to their account. Hopefully that sent chills down your spine.

The solution

Luckily, the solution is simple! A lot of developers have heard of attr_protected and regularly use it for things like admin booleans and think that's enough. As seen above, the hidden methods that are generated are the ones that can really bite you. You can't be too careful, really. Are you sure that none of your plugins are generating methods that should be protected?

Use attr_accessible instead. This allows you to whitelist the attributes that are safe for mass-assignment and move on.

Example:

   1  class User < ActiveRecord::Base
   2    attr_accessible :name
   3    has_many :credit_cards
   4  end
   5 
   6  Sanitized Parameters:
   7  { "id" => 123,
   8    "user" => { "name" => "hacker" } }

Please be safe out there!

Read these articles

Most agencies want to build it, bill it, and move on. Not us. We’re in it for the long haul. Nearly every client we’ve ever had is still our client and those applications are still running at full speed.

PROJECTS

FlixCloud - On-demand Video Encoding Red Is White - Christian T-Shirts