Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does this stop mass assignment?

I wanted to start using attr_accessible with my models to stop the problem with mass assignment. I understand how it works and have researched as much as I could.

What I don't understand is the difference between using update_attributes(params[:my_form]) or create(params[:my_form]) and setting the fields one by one? Aren't both just as vulnerable?

What is the difference between NOT having attr_accessible and doing this...

@model_object = ModelObject.new
@model_object.create(params[:model_object_params])

And having attr_accessible and doing this...

@model_object = ModelObject.new
@model_object.field1 = params[:model_object_params][:field1]
@model_object.field2 = params[:model_object_params][:field2]
@model_object.field3 = params[:model_object_params][:field3]
@model_object.save!

Aren't both these methods of creating the record just as vulnerable? The hacker/cracker could send a url to both these methods and both would do just the same, right?

Or does using attr_accessible and updating the fields one-by-one do something different or somehow become safer?

There's where all these methods I'm finding of using attr_accessible don't make any sense to me. It seems to be doing the same thing two different ways. What am I missing?

Thanks.

like image 235
dsmorey Avatar asked Jun 21 '11 03:06

dsmorey


People also ask

How do you prevent mass assignment insecure binder configuration?

The solution 😊 Jackson provides an annotation that can be used on class level (JsonIgnoreProperties). So simple, just add @JsonIgnoreProperties(ignoreUnknown = true) before the class.

What is mass assignment in API?

It is a severe API threat that arises when you save the request body as it is on the server instead of getting values from it one by one. It allows the user to initialize or overwrite server-side variables that the application does not intend.


2 Answers

In the way you are doing it, it does not prevent "mass assignment".

"Mass assignment" is the term used when Rails is handling the assigning of values to attributes in a model. This is typically done in a controller, using the names and values in params.

When you're doing the assigning yourself, it is also "mass assignment", in a way; but you have fine control over what to assign and what not to in this case. So, to save writing that boilerplate assignment code, Rails provides attr_accesible - same control, less code.

To see how it is used:

Presume that a ActivityLog model has an attribute called user_ip_address.

Now, user_ip_address is an attribute in the model, and could be assigned by mass-assignment or by "self-rolled-mass-assignment".

But in both cases that is wrong -- you don't want user-supplied input to set a value for that attribute.

Instead, you want to always find out the actual IP address of the user and assign that value (ignoring any value in params). So you would exclude user_ip_address from attr_accessible and instead assign it yourself.

attr_accessible :all_attributes_except_user_ip_address

@al = ActivityLog.new(params[:model_object_params])
@al.user_ip_address = get_origin_user_ip_address
@al.save

For any information that a user should not be able to change, use attr_accessible and exclude it from the list.

like image 143
Zabba Avatar answered Oct 24 '22 06:10

Zabba


The short answer is that it stops field4 from being set implicitly.

The difference is that without attr_accessible a hacker could update a field that is not in your form. With attr_accessible this impossible.

E.g. if your user model has a field is_admin, a hacker could try to create a new admin by posting:

params[:user][:is_admin] = true

If attr_accessible is set (and obviously it shouldn't contain is_admin) this is impossible.

About your example: if your model only has field1, field2 and field3 and there are no other database columns you want to protect, there is no need to use attr_accessible. Hope this makes it clear.

Just remember:

Without any precautions Model.new(params[:model]) allows attackers to set any database column’s value.

Source: http://guides.rubyonrails.org/security.html#mass-assignment

like image 35
Mischa Avatar answered Oct 24 '22 04:10

Mischa