Rails Mass Assignment Protection in the Controller

Github recently had a rails mass assignment bug that caused quite a stir. In the aftermath, several people proposed new ways of handling mass assignment protection in rails. One of the proposals, authored by Yehuda Katz, advocated for protecting against mass assignment in the controller rather than the model. I thought it was a great idea, so I built a little gem called Params Cleaner.

Params Cleaner

Params Cleaner provides you with a module that mixes into your controllers. Once mixed in, an ‘allowed_params’ method is available to define which params keys are allowed under a given root key. Here’s an example:

class PlayersController < ApplicationController  
  include ParamsCleaner

  allowed_params :player => [:name, :email]

  def create
    @player = Player.new(clean_params[:player])

    if @player.save
      redirect_to player_path(@player)
    else
      render :new
    end
  end
end  

Note that now, instead of accessing your params via the ‘params’ method, you’re accessing them using the ‘clean_params’ method.

The symbols provided to ‘allowedparams’ will work at any level of nesting inside the params hash. For example, assume this ‘allowedparams’ declaration:

allowed_params :player => [:name, :email]  
               :name => [:first, :last]

Next, assume our params look like this:

{
  :player => {
    :email => "drew@drewolson.org"
    :bad_key => "nefarious stuff",
    :name => {
      :first => "Drew",
      :last => "Olson",
      :nested_bad_key => "more nefarious stuff"
    }
  }
}

Here’s what you’d see when calling the ‘clean_params’ method:

clean_params[:player]  
# => {:email => "drew@drewolson.org", :name => {:first => "Drew", :last => "Olson"}}

clean_params[:player][:name]  
# => {:first => "Drew", :last => "Olson"}

Use It!

ParamsCleaner is ready for use. Just add ‘params_cleaner’ to your Gemfile. The source is available here if you’re interested in contributing.