Stephen Sclafani

Ruby on Rails: Secure Mass Assignment

January 4th, 2010

The security implications of mass assignment have been documented since Rails’s inception and yet many applications are still vulnerable. In a survey of the top Rails websites I found that the majority were vulnerable to the issue. At three I was able to gain full admin privileges, at others I was able to gain access to other users’ data, in one case to partial credit card information.

Mass Assignment

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

In the above line of code mass assignment is used to populate a newly created User from the params hash (user submitted data). If no precautions are taken an attacker can pass in their own parameters and set any User attributes.

t.column :admin, :boolean, :default => false, :null => false

Consider an application that has a users table containing an admin column. When creating a new account an attacker can pass in the parameter user[admin] set to 1 and make themselves an admin.

has_many :blog_posts

It’s not only database columns that can be attacked in this fashion. Consider an application that has the above line of code in its User model. Because has_many allows the setting of ids via mass assignment, an attacker can pass in the parameter user[blog_post_ids][] and take control of other users’ blog posts.

Protection

Rails provides the class method attr_accessible which takes a whitelist approach to protection. Using attr_accessible you can specify the attributes that can be set and all others will be protected.

Testing for Vulnerability

From a black box perspective its easy to determine if an application is vulnerable by attempting to set an attribute that you know could not exist. In the majority of cases a 500 error will be returned. In a few cases an error page with an error such as “Unable to create account” or “Unable to save settings” was returned.