Link Search Menu Expand Document

Mass Assignment in Ruby

Vulnerable Example

Rails >= 4

In Rails 4 and newer, protection against mass assignment is on by default. The Action Controller Parameters must be used to choose which attributes should be permitted for mass updating by using the permit method.

A vulnerable example would explicitly permit an unsafe attribute, such as is_admin.

def signup
  @user = User.new(params.permit(:name, :password, :first_name, :last_name, :is_admin))
end

An attacker could craft a request by adding the is_admin POST field with value 1 to exploit the attack and register a new user with administrative privileges.

It’s possible to change this safe default by either setting the permit_all_parameters to modify all new instances or by updating a single instance by invoking the permit declaration with .permit!.

User.new(params.permit!)

Rails < 4

In previous versions, the mass assignment feature may allow an attacker to set any model’s attributes. The following Ruby snippet shows a Ruby On Rails controller that creates a new user based on the user-provided user object.

def signup
  @user = User.new(params[:user])
end

Prevention

Rails >= 4

Make sure to only permit values that are safe to be set. Foreign keys are likely unsafe, as they may allow an attacker to manipulate foreign records.

Rails < 4

Old versions of Ruby On Rails should use the attr_protected method, which takes a list of attributes that will not be accessible for mass assignment. For example:

attr_protected :is_admin

The attr_accessible method can also be used to enforce an allow list approach. It takes a list of attributes that will be accessible, while all other attributes will be protected.

attr_accessible :name, :password, :first_name, :last_name

References

Ruby On Rails Security Guide - Mass Assignment Ruby On Rails Guides - Action Controller Overview - Strong Parameters