Rails 4 Preview: Strong Parameters

This article will show you how to use strong parameters in your Rails 3.x or Rails 4.0 application.


Published on:March 27, 2013

Background

In the old days of Ruby on Rails, it was possible to trick poorly coded Ruby on Rails applications into letting you update any field in a given table during an update statement. For example, lets say you have a user record similar to the following:

create_table :users do |t|
  t.string :email
  t.string :name
  t.string :password_digest
  t.boolean :is_admin

  t.timestamps
end

In a poorly coded Rails application, you would often find this in the update method of a users controller. For example, take a look at the following code:

@user = current_user

if @user.update_attributes(params[:user])
  redirect_to home_path, notice:  "Your profile has been successfully updated."
else
  render action: "edit"
end

The problem with the above code is that it makes it extremely easy to elevate yourself to an administrator. A user can inject a form field for the :is_admin field and set the value to true. This would give the user administrative rights and he would then have complete control over the site. This is just one example. Ruby on Rails 3.x has parameter whitelisting/blacklisting features that would resolve a lot of this, but both parameter whitelisting and blacklisting are done on the model, NOT the controller. It would be better if instead we could control which parameters to accept in the controller. This gives us significantly more flexibility and overall it's a cleaner way of doing things.

Introducing Strong Parameters

Strong parameters resolve the aforementioned issue by moving parameter concerns back to the controller. Using strong parameters we can quickly and easily filter our parameters as needed. Take a look at the example below:

def UsersController < ActionController::Base
  def update
    @user = current_user

    if @user.update_attributes(user_profile_parameters)
      redirect_to home_path, notice:  "Your profile has been successfully updated."
    else
      render action: "edit"
    end
  end

private
  def user_profile_parameters
    params.require(:user).permit(:name, :password, :password_confirmation, :email)
  end
end

In the code above you'll see the new functionality provided by Rails 4.0. The require method ensures that only parameters belonging to the user object are used. The permit method specifies what parameters you'll accept for the update. If a user tries to use a parameter other than the ones specified in the list, it won't be passed to your object. For example, if i attempted to pass is_admin with a value of true, it would be filtered out by the permit method. In this case we place the params options in a method to make the code more reusable.

Strong Parameters in rails 3

Rails 3 users can utilize strong parameters as well. First, include the following line in your gemfile:

gem 'strong_parameters'

Next, create an initializer in config/initializers and call it strong_parametes.rb. Inside this file add the following code:

ActiveRecord::Base.send(:include, ActiveModel::ForbiddenAttributesProtection)

Finally, open your config/application.rb file and update the line containing config.active_record.whitelist_attributes so that it's set to false:

config.active_record.whitelist_attributes = false

Conclusion

That's it! You are now ready to utilize strong parameters in your application. For more information you can visit the Strong Parameters GitHub Page. A Rails 2.x version of Strong Parameters is also available at this location.