The mass assignment vulnerability
Basically the problem is the following:
Whenever you scaffold generate code for some resource in Rails, which
is pretty common, you can see a snippet like this for creating a
resource:
@user = User. new (params[ :user ]) |
What this does is create a new user, with all the attributes set to
the values that got transmitted from a form and are now in the
params[:user] hash. This is very concise as here you can mass assign
everything the user entered: name, email, description etc. Cool right?
This is why it’s not only generated but also written pretty often. Yeah
so far so good.
The problem starts when you got some attributes in your model, which
you don’t want your users to have direct access to. For instance the
boolean admin, determining if a user is an admin or not. The attacker
may use tools to manipulate the html form and hence the transmitted
parameters to include the key value pair: admin: true ! So params[:user]
may look like this:
params[
:user
] = { name:
'Sapna'
, email:
'evil@example.com'
, description:
'I am an admin soon'
, admin:
true
}
What can I do to protect my app?
Well in general it is pretty easy to protect against this kind of attack you just have to add attr_accessible
to all your rails models. This white lists the attributes, that can be
assigned during mass assignments. Everything else can not be assigned
during mass assignments. So for our example this would look like this:
class
User < ActiveRecord::Base
attr_accessible
:name
,
:email
,
:description
# rest of class omitted
end
Pro-tip: Use Brakeman
Brakeman (can also be found on github)
is a static analysis tool (fancy term for: looks at your code, doesn’t
execute it), looking for vulnerabilities. So it is a vulnerability
scanner for Ruby on Rails. It takes a good look at your source code and
informs you of any found security vulnerabilities including the
confidence of the scanner that this is indeed a problem (e.g. not a
false positive). It seems to find mass assignment vulnerabilities very
reliably and it also informed me of a possible Cross-site scripting
(XSS) vulnerability in my Rails version (3.2.0) and recommended an
update to 3.2.2, as this version fixes the problem. So it is also pretty
up to date and I can only recommend it. Now go ahead and gem install brakeman or add it to your Gemfile.
However the default output isn’t very beautiful on my system and hides many important parts so I’d recommend you to run:
brakeman -f html -o brakeman.html path/to/app |
For a bit prettier html output. Hope that this helps. And don’t forget to add this brakeman.html to your gitignore. Oh by the way: they also have a plugin for Jenkins/Hudson.
So now go ahead and make your Rails apps more secure!