CSC/ECE 517 Fall 2017/E1784 Fix mass assignments reported by Brakeman.rb
About Expertiza
Expertiza is an open source project based on Ruby on Rails framework. Expertiza allows the instructor to create new assignments and customize new or existing assignments. It also allows the instructor to create a list of topics the students can sign up for. Students can form teams in Expertiza to work on various projects and assignments. Students can also peer review other students' submissions. Expertiza supports submission across various document types, including the URLs and wiki pages.
Introduction
Background
Mass Assignment is the name Rails gives to the act of constructing your object with a parameters hash. It is "mass assignment" in that you are assigning multiple values to attributes via a single assignment operator.
The following snippets perform mass assignment of the name and topic attribute of the Post model:
- Post.new(:name => "John", :topic => "Something")
- Post.create(:name => "John", :topic => "Something")
- Post.update_attributes(:name => "John", :topic => "Something")
In order for this to work, your model must allow mass assignments for each attribute in the hash you're passing in.
There are two situations in which this will fail:
- You have an attr_accessible declaration which does not include :name
- You have an attr_protected which does include :name
Problem Statement
With the help of mass assignment, when we create or update certain object, we do not need to write an assignment statement for each attribute. But mass assignment could cause security vulnerabilities. Hackers could add other parameters to do some bad things. For example:
- @post = Post.new(params[:post])
Typically this is used when the user submits a form rendered by a form_for @post. In an ideal world, the params[:post] hash should only contain the fields we displayed on the form. However, it is trivial easy hackers to pass additional fields in their request, so in effect you're allowing a user to set any fields on @post, not just the ones displayed on the form.
Rails 4 introduces strong parameters, which is a new approach to protect mass assignment. So our group needs to resolve all these "Unprotected mass assignment" issues according to Brakeman report.
Implementation
Problem 1: Potentially dangerous attribute available for mass assignment
Previsouly, only two attributes :parent_id, :node_object_id are protected. So we removed the two attributes so that all attributes in all models will be mass assignment protected.
Problem 2: Mass assignment is not restricted using attr_accessible
If there was no protection at all in the model file. We just added "attr_acessible".
Problem 3: Unprotected mass assignment
We modified the code in an unobtrusive way, i.e. processing the mass assignment parameters with a function without changing them directly.
Parameters come from requests
Fix unprotected mass assignment in update
Fix unprotected mass assignment in new
Parameters come from other objects
If the parameters come from requests, we can directly use "params.permit()" to implement a whitelist. However, if the parameters come from values of other objects, we cannot directly call that built-in function. Firstly, we need to build a hash with those values and pass the hash into "params". And then we can filter the parameters using permit().
Fix unprotected mass assignment in create
Fix unprotected mass assignment in new
params.permit!
Reference
- https://github.com/expertiza/expertiza
- https://codeclimate.com/github/expertiza/expertiza/issues?category=security
- https://apidock.com/rails/ActiveModel/MassAssignmentSecurity/ClassMethods/attr_accessible
- https://docs.google.com/document/d/1rdolBAHxVGI9I0N-cT866AqnfORM2L1_m_bo2gRYRrI/edit#
- https://www.happybearsoftware.com/how-i-avoid-the-rails-mass-assignment-security-mistake
- https://code.tutsplus.com/tutorials/mass-assignment-rails-and-you--net-31695