How To Prevent
- API7:2019 Security Misconfiguration
- API8:2019 Injection
- API9:2019 Improper Assets Management
- API10:2019 Insufficient Logging & Monitoring
- What's Next For Developers
- What's Next For DevSecOps
- Methodology and Data
- Acknowledgments
API6:2019 - Mass Assignment
Is the api vulnerable.
Objects in modern applications might contain many properties. Some of these properties should be updated directly by the client (e.g., user.first_name or user.address ) and some of them should not (e.g., user.is_vip flag).
An API endpoint is vulnerable if it automatically converts client parameters into internal object properties, without considering the sensitivity and the exposure level of these properties. This could allow an attacker to update object properties that they should not have access to.
Examples for sensitive properties:
- Permission-related properties : user.is_admin , user.is_vip should only be set by admins.
- Process-dependent properties : user.cash should only be set internally after payment verification.
- Internal properties : article.created_time should only be set internally by the application.
Example Attack Scenarios
Scenario #1.
A ride sharing application provides a user the option to edit basic information for their profile. During this process, an API call is sent to PUT /api/v1/users/me with the following legitimate JSON object:
The request GET /api/v1/users/me includes an additional credit_balance property:
The attacker replays the first request with the following payload:
Since the endpoint is vulnerable to mass assignment, the attacker receives credits without paying.
Scenario #2
A video sharing portal allows users to upload content and download content in different formats. An attacker who explores the API found that the endpoint GET /api/v1/videos/{video_id}/meta_data returns a JSON object with the video’s properties. One of the properties is "mp4_conversion_params":"-v codec h264" , which indicates that the application uses a shell command to convert the video.
The attacker also found the endpoint POST /api/v1/videos/new is vulnerable to mass assignment and allows the client to set any property of the video object. The attacker sets a malicious value as follows: "mp4_conversion_params":"-v codec h264 && format C:/" . This value will cause a shell command injection once the attacker downloads the video as MP4.
- If possible, avoid using functions that automatically bind a client’s input into code variables or internal objects.
- Whitelist only the properties that should be updated by the client.
- Use built-in features to blacklist properties that should not be accessed by clients.
- If applicable, explicitly define and enforce schemas for the input data payloads.
- CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes
- Browse topics
SNYK LEARN LOGIN
- 🌍 Snyk (recommended)
OTHER REGIONS
For Snyk Enterprise customers with regional contracts. More info
- 🇦🇺 Snyk AUS
Mass assignment
Be careful with parameters that are automatically bound from requests to objects, select your ecosystem, mass assignment: the basics, what are mass assignment vulnerabilities.
To make it easier to save data submitted via an HTML form into a database or object, many web application frameworks have included libraries to automatically bind HTTP request parameters (typically sent via forms) to the fields of database models or members of an object, requiring only minimal coding.
Let’s say we have a (very simple) HTML form:
When the form is submitted to the web application, it will send the form data as HTTP request parameters, and the backend code will have to read each parameter individually into a corresponding variable. Then, once all the fields have been read, the application will usually execute a database update or insert operation to save the data.
Mass Assignment makes it possible to write less code to handle this process - think about how much coding this technique could save if it was an object that had dozens of fields, and multiply this across a complex application that has many of these objects in its database.
Mass assignment vulnerabilities occur when the database model that is being assigned contains security-relevant fields, and the application user can supply values in the POST request that are saved to those fields, even though they are not present in the HTML form.
For example, if the User model contained a field isAdmin: Boolean , the user could add the POST body parameter isAdmin=true and make themselves an administrator.
For this to occur, an attacker would need to guess the names of the sensitive fields, or the source code for the vulnerable application would have to be available to the attacker (allowing them to see what sensitive fields are present in the data model).
Impacts of this attack can include bypassing authentication or authorization logic or elevation of privilege. This could then result in the destruction or disclosure of data within the application.
About this lesson
In this lesson, you will learn how mass assignment vulnerabilities work and how to protect your applications against them. We will begin by exploiting a Mass Assignment vulnerability in a simple application. Then we will analyze the vulnerable code and explore some options for remediation and prevention.
Mass assignment in the wild
In 2012, a GitHub user exploited a Mass Assignment vulnerability in GitHub’s public key update form. The flaw allowed the user to add their public key to another organization they were not a member of. The user added their key to the Ruby on Rails organization. To demonstrate proof of the exploit, the user added a file to the Rails project repository. GitHub responded, quickly fixing the vulnerability and they conducted a wide audit of their code to ensure the issue was detected and fixed if it existed anywhere else.
Mass assignment in action
New SaaS startup SuperCloudCRM recently launched their web platform designed to help businesses boost their sales and marketing efforts.
Setting the stage
SuperCloudCRM recently launched its web platform. Unfortunately, they suffered a security breach, resulting in data being leaked. What went wrong?
Mass assignment details
As mentioned, SuperCloudCRM’s developers had been logging request data for API endpoints like the POST /user/create endpoint, which creates new user accounts when a user submits the signup form.
A typical JSON payload in the request sent to the /user/create endpoint was supposed to look like this:
But a search of the /user/create endpoint’s logs for the [email protected] account around the time the user was created, found JSON POST data starting with the following excerpt:
It was different to the normal requests, and had a long request body with dozens more fields all starting with the letter r . What was the attacker doing? All of these weird field names that weren’t part of the user model schema, which was:
After doing some testing like the scenario above showed, a few things were discovered.
First, the new user account’s password was apparently being saved to the database in plaintext. Not good! But what stuck out was that the application ignored the non-existent fields and just assigned the fields that were actually part of the User model schema.
The data from the new User document was sent back to the API client and the attacker could then infer which of the list of fields starting with r were part of the User model schema, because if a field existed it was saved and echoed back in the response with the other user data.
A search of the /user/create endpoint’s request log entries around the same time revealed that thousands of similar requests had been sent. Each request testing lists of possible field names in the User model schema.
It was concluded that the attackers had brute-forced HTTP requests with various field name guesses to enumerate the organization and role fields in the schema. Despite them not being referred to anywhere in the client-side JavaScript code, the attackers were able to discover these security-related field names.
So, if the attackers knew these field names, what would they do then? Well, this could have led to a possible mass assignment attack. After hours of reviewing logs for the POST /user/create and POST /user/update endpoints the incident response team found dozens of requests had been submitted to the application, which looked similar to:
The requests appeared to be successful. Each of the requests changed the organization to a different customer, essentially giving the attackers access to each of them as admins. The last request was:
This seemed to explain why [email protected] was an administrator in the Cowmoo Industries organization.
By exploiting this mass assignment vulnerability and adding themselves as the administrator for various customers, the attackers were able to access the organizations’ data within SuperCloudCRM and steal it.
Mass assignment by different names
The concept of mass assignment is known by different names in various programming languages or frameworks. NodeJS and Ruby on Rails call it mass assignment. It is referred to as autobinding in Java Spring MVC and ASP NET MVC. PHP calls it object injection.
Mass assignment under the hood
Let’s have a look at this vulnerable application in more detail by going through the server-side code.
The schema for the User model is defined here, with the user’s credentials, email address, plus their role and organization they belong to. During signup, the credentials and email address are the only values that are supposed to be supplied by the user and accepted by the application.
Firstly, let's recap what took place in the example above.
- The User schema consisted of several fields: username, password, email, role and organization.
- Only the username, password and email fields were sent from the web browser to the /user/create endpoint
- The API endpoint used mass assignment to blindly assign any field from the POST request’s JSON data to the User model in the database (if the field existed in the User schema).
- The attackers were able to determine the names of security-related fields in the schema (role and organization)
- The attackers could supply arbitrary values for these fields when creating or updating a user account
- This let the attackers add themselves to other organizations and elevate their privileges to those of an administrator
Here ( $user = new User($request->post()); ), the endpoint creates a new User object and in doing so, passes all contents of the POST request to the constructor. PHP can “smartly” figure out which parameters go to which attributes of the class; however, this isn’t so smart when those attributes are certain things that shouldn’t be assignable! Even if the form only accepts inputs with username , password and email , a malicious actor can guess the other forms and simply add those fields to the JSON manually. As PHP has no way of discerning what it receives from “good” and “bad”, it simply updates them all. If only there were a way to tell PHP exactly which fields we don’t want to be assignable like that!
Impacts of mass assignment
By exploiting mass assignment vulnerabilities, a malicious actor could create multiple security problems including
- Data tampering : Attackers can modify sensitive information in the database, such as password or account balance
- Data theft : Attackers can gain access to confidential information stored in the database
- Elevation of privilege : Attackers can manipulate the properties of an object to gain additional privileges, such as administrator access
- Unauthorized access : Attackers can manipulate the properties of an object to gain unauthorized access to sensitive resources
Scan your code & stay secure with Snyk - for FREE!
Did you know you can use Snyk for free to verify that your code doesn't include this or other vulnerabilities?
Mass assignment mitigation
Use an allowlist of fields that can be assigned to.
Most mass assignment libraries or helper libraries should provide the ability to restrict the fields that will be read from a request and assigned to the data model. By restricting the assignment of user-supplied fields to only fields in the schema that are known safe ones, the values of security-sensitive fields will be prevented from tampering.
Using this strategy, the code for the application would be changed to add an allowlist using the pick() method of the underscore package and listing the allowed fields in the userCreateSafeFields array:
Laravel provides a library, eloquent , which, among other things, introduces object injection protection features! It gives you the ability to indicate variables that can be assigned, or otherwise, you can indicate variables that you don’t want assignable. This means that when you use mass assignment to populate a class with request data, the Laravel backend can (with your guiding hand) separate POST request input data from fields that should be populated and those that should not!
Using this strategy, the code for the application can be changed to add an allow-list of class attributes, enforcing that only these will be updated:
Use a Data Transfer Object (DTO)
Another option is to create an intermediary object (the DTO) that only has safe, assignable properties, which would be a subset of the target object that has those same fields plus any sensitive fields. Using our User example, the DTO would be:
The mass assignment operation can assign any user-supplied data to the DTO without the risk of inadvertently assigning any sensitive fields. The DTO can be copied to the final object, and during this process, any sensitive fields can be set to secure default values.
This method might require much more coding though. DTOs need to be created for all classes with sensitive fields. If there are many schemas with sensitive fields that require corresponding DTOs, then this becomes nearly as much work as not using mass assignment.
Use a denylist to declare fields that can’t be assigned to
The opposite of using an allowlist to define fields that are allowed to be assigned is to use a denylist of fields that shouldn’t be assigned. Security wisdom says to use allowlisting over denylisting because it’s safer to accidentally not include a safe field than to accidentally omit a dangerous field. So, following this advice, a denylist would be the less preferred option of the two. If there are 50 fields in a schema and only one is security-sensitive, then it is obviously much quicker to just denylist the one sensitive field. The danger here though would be if additional sensitive fields were added to the schema later and the developer forgot to add them to the denylist, then you would have a mass assignment vulnerability.
To use denylists, the code for the application would be changed in a similar manner to the code shown in the allow-list strategy shown earlier, except it would use the omit() method of the underscore package and listing the disallowed fields in the userCreateDisallowedFields array:
To use deny-lists, the code for the application would be changed in a similar manner to the code shown in the allow-list strategy shown earlier, the only difference being the User class is changed to have a “hidden” array:
Utilize a static analysis tool
Adding a static application security testing ( SAST ) tool to your devops pipeline as an additional line of defense is an excellent way to catch vulnerabilities before they make it to production. There are many, but Snyk Code is our personal favorite, as it scans in real-time, provides actionable remediation advice, and is available from your favorite IDE.
Keep learning
To learn more about mass assignment vulnerabilities, check out some other great content:
- OWASP guide to mass assignment vulnerabilties
- Find mass assignment in our top 10 list
Congratulations
You have taken your first step into learning what mass assignment is, how it works, what the impacts are, and how to protect your own applications. We hope that you will apply this knowledge to make your applications safer.
What is mass assignment?
Mass assignment is a type of security vulnerability that occurs when an application code allows user-provided data to be used to set properties on an object without verifying that the user has the right to do so.
What to learn next?
Insecure default variable initialization, uncaught exception, insufficient encapsulation.
- Mass Assignment
What is a Mass Assignment Attack?
In order to reduce the work for developers, many frameworks provide convenient mass-assignment functionality. This lets developers inject an entire set of user-entered data from a form directly into an object or database. Without it, developers would be forced to tediously add code specifically for each field of data, cluttering the code base with repeated form mapping code.
The downside of this functionality is that it is often implemented without a whitelist that prevents users from assigning data to protected fields. An attacker may exploit this vulnerability to gain access to sensitive data or to cause data loss.
As demonstrated by prominent cases , even the best teams of developers can miss this non-obvious vulnerability.
An Example of a Vulnerability
In this example, a web shop allows users to sign up and keep track of their orders. The owner of the web shop has a special administrator account that allows them to manage other users and their orders. The administrator account is created in the database, just like a regular user account, except it has an is_administrator flag set.
On the sign up page, the user is asked to enter their email address and select a password:
The corresponding controller action creates the user in the database:
An attacker may inject their own HTML into form (or otherwise modify the request):
The controller action will create the user, letting the attacker gain complete control of the web shop:
How To Defend Against Mass Assignment Attacks
In the example above, the developer should change the code to either explicitly assign the attributes for the allowed fields, or use a whitelisting function provided by the framework (Ruby on Rails in this case):
More useful information may be found at:
- https://www.owasp.org/index.php/Mass_Assignment_Cheat_Sheet
- http://guides.rubyonrails.org/v3.2.9/security.html#mass-assignment
- https://laravel.com/docs/5.0/eloquent#mass-assignment
- https://odetocode.com/Blogs/scott/archive/2012/03/11/complete-guide-to-mass-assignment-in-asp-net-mvc.aspx
- https://coffeeonthekeyboard.com/mass-assignment-security-part-10-855/
- https://nvisium.com/resources/blog/2014/01/17/insecure-mass-assignment-prevention.html
Let Us Review Your Software
We provide code security reviews as a service. Based on our extensive experience in the field of sofware engineering and IT security, we know how to efficiently review entire code bases and identify security critical parts of the software.
This enables us to provide our security code review service at a fixed rate per review, providing our customers a transparent, efficient and reliable process.
- Security review of your software by experts
- OWASP Top 10 vulnerability check
- Security Report with recommendations
- Invaluable insights into the state of security in your application
Fixed Price per Review
- Broken Access Control
- Broken Authentication
- Cross-Site Request Forgery (CSRF)
- Cross-Site Scripting (XSS)
- Insecure Direct Object Reference
- Security Misconfiguration
- Sensitive Data Exposure
- SQL Injection
- Timing Attack
- Unvalidated Redirection
- Vulnerable Dependencies
Technologies
- Microsoft .Net
- Ruby on Rails
ROPE Security is a Software Security Consultancy Firm based in Denmark. Our clients range from large international enterprises to start-ups and small businesses.
If you have any questions, do not hesitate to contact us at [email protected]