Mass Assignment An Overview
Mass Assignment:
An attack used on websites that involve some sort of model-binding to a request. The framework binder used for binding the HTTP request parameters to the model class has not been explicitly configured to allow, or disallow certain attributes.
In this article, we’ll review what mass assignment is, how it can be a problem, and what can be done to fix it in applications coded in various languages.
In order to ease development, most modern frameworks allow an object to be automatically instantiated and the HTTP request parameters whose names match an attribute of the class to be bound get automatically populated. This can lead to serious problems if implemented without caution. Any attribute in the bound or nested classes, will be automatically bound to the HTTP request parameters. Therefore, malicious users will be able to assign a value to any attribute in bound or nested classes, even if they are not exposed to the client through web forms or APIs. The Mass assignment vulnerability shows up every now and then in several popular applications. For example, in 2012, a developer, named Egor Homakov, took advantage of a security hole at Github to gain commit access to the Rails project. This vulnerability can be reproduced in several other websites and languages, thus the need to explicitly map solutions for the same.
Example:
Suppose there is a form for editing a user’s account information:
The object that the form is binding to is as follows:
Here is the controller handling the request:
The exploit is:
General Solution
Create Data Transfer Objects (DTOs):
Create form or DTO objects that have fields for only what is in the form and what should be editable by the users.
Example:
Framework Specific Solutions
ASP .NET MVC:
[Bind] Attribute:
The Bind Attribute lets you whitelist only those properties which should be bound from the incoming request.
The Bind Attribute can also be used with a blacklist approach.
UpdateModel and TryUpdateModel API:
Explicit binding with the UpdateModel and TryUpdateModel API can be performed. These methods also support whitelist and blacklist parameters.
Interface Definitions:
The controller can be coded as shown below.
Assuming your interface looks like:
The model will have to implement this interface:
[ReadOnly] attribute:
This attribute can be used if binding of a certain property is not required at all.
Use two different models:
Put user input into a model designed for user input only.
Spring MVC:
Whitelisting:
Register fields that should be allowed for binding.
Blacklisting:
Register fields that should not be allowed for binding.
Ruby on Rails:
attr_protected (Blacklist Approach):
The attr_protected method takes a list of attributes that will not be accessible for mass-assignment.
Example:
Where “admin” is the role option. If no role is defined then attributes will be added to the “:default” role.
attr_accessible (WhiteList Approach):
This accepts a list of attributes that will be accessible for mass-assignment. All other attributes will be protected.
Example:
The most secure technique to protect your whole project would be to enforce that all models define their accessible attributes. This can be achieved with an application config option:
This will create an empty whitelist of attributes available for mass-assignment for all models in your application. As such, your models will need to explicitly whitelist or blacklist accessible parameters by using an attr_accessible or attr_protected declaration. (Note: This technique is best applied at the start of a new project.)
Django:
Create forms to avoid Mass assignment. All fields that are intended for inclusion in the form should be listed explicitly in the “fields” attribute.
In Conclusion..
Mass assignment can be an incredibly useful feature when writing code. However, the consequences of a Mass Assignment vulnerability can be serious and mass assignment security is really about handling untrusted input. A developer can protect an application by following some basic coding best practices such as:
- Whitelist the bindable, non-sensitive fields
- Blacklist the non-bindable, sensitive fields
- Use Data Transfer Objects (DTOs)