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.
@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.
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.
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.