• General Solutions
  • Ruby On Rails
  • Jackson (JSON Object Mapper)
  • GSON (JSON Object Mapper)
  • JSON-Lib (JSON Object Mapper)
  • Flexjson (JSON Object Mapper)
  • References and future reading
  • Microservices Security
  • Microservices based Security Arch Doc
  • Mobile Application Security
  • Multifactor Authentication
  • NPM Security
  • Network Segmentation
  • NodeJS Docker
  • Nodejs Security
  • OS Command Injection Defense
  • PHP Configuration
  • Password Storage
  • Prototype Pollution Prevention
  • Query Parameterization
  • REST Assessment
  • REST Security
  • Ruby on Rails
  • SAML Security
  • SQL Injection Prevention
  • Secrets Management
  • Secure Cloud Architecture
  • Secure Product Design
  • Securing Cascading Style Sheets
  • Server Side Request Forgery Prevention
  • Session Management
  • TLS Cipher String
  • Third Party Javascript Management
  • Threat Modeling
  • Transaction Authorization
  • Transport Layer Protection
  • Transport Layer Security
  • Unvalidated Redirects and Forwards
  • User Privacy Protection
  • Virtual Patching
  • Vulnerability Disclosure
  • Vulnerable Dependency Management
  • Web Service Security
  • XML External Entity Prevention
  • XML Security
  • XSS Filter Evasion

Mass Assignment Cheat Sheet ¶

Introduction ¶, definition ¶.

Software frameworks sometime allow developers to automatically bind HTTP request parameters into program code variables or objects to make using that framework easier on developers. This can sometimes cause harm.

Attackers can sometimes use this methodology to create new parameters that the developer never intended which in turn creates or overwrites new variable or objects in program code that was not intended.

This is called a Mass Assignment vulnerability.

Alternative Names ¶

Depending on the language/framework in question, this vulnerability can have several alternative names :

  • Mass Assignment: Ruby on Rails, NodeJS.
  • Autobinding: Spring MVC, ASP NET MVC.
  • Object injection: PHP.

Example ¶

Suppose there is a form for editing a user's account information:

Here is the object that the form is binding to:

Here is the controller handling the request:

Here is the typical request:

And here is the exploit in which we set the value of the attribute isAdmin of the instance of the class User :

Exploitability ¶

This functionality becomes exploitable when:

  • Attacker can guess common sensitive fields.
  • Attacker has access to source code and can review the models for sensitive fields.
  • AND the object with sensitive fields has an empty constructor.

GitHub case study ¶

In 2012, GitHub was hacked using mass assignment. A user was able to upload his public key to any organization and thus make any subsequent changes in their repositories. GitHub's Blog Post .

Solutions ¶

  • Allow-list the bindable, non-sensitive fields.
  • Block-list the non-bindable, sensitive fields.
  • Use Data Transfer Objects (DTOs).

General Solutions ¶

An architectural approach is to create Data Transfer Objects and avoid binding input directly to domain objects. Only the fields that are meant to be editable by the user are included in the DTO.

Language & Framework specific solutions ¶

Spring mvc ¶, allow-listing ¶.

Take a look here for the documentation.

Block-listing ¶

Nodejs + mongoose ¶, ruby on rails ¶, django ¶, asp net ¶, php laravel + eloquent ¶, grails ¶, play ¶, jackson (json object mapper) ¶.

Take a look here and here for the documentation.

GSON (JSON Object Mapper) ¶

Take a look here and here for the document.

JSON-Lib (JSON Object Mapper) ¶

Flexjson (json object mapper) ¶, references and future reading ¶.

  • Mass Assignment, Rails and You

DEV Community

DEV Community

Jack Kim

Posted on Nov 12, 2022 • Updated on Dec 5, 2022

Ruby On Rails: Strong Params and Mass Assignment

In this writing, I will explain the benefits and dangers of mass assignment and use params.permit to allow specific params.

What is mass assignment?

The mass assignment passes a :key => value params hash to a model's create() or new() method to create an instance.

A benefit of using a mass assignment The mass assignment can simplify creating an instance of a model with multiple attributes.

Instead of typing every single attribute:params[:attribute] , using mass assignment with one params argument will look like as simple as

A danger of using mass assignment Mass assignment in its nature has a vulnerability where :key => value params hash will be accepted as is. For an example, I can send a params hash such as :admin => true or :email => "[email protected]" .

Strong params To prevent "dangerous params hash", you can create a function with using params.permit to allow specific params.

The animal_trainer_params function now filters "unassigned" :key => value params hash to the prevent mass assignment vulnerability.

My understanding of strong params is like an attendance sheet in a classroom where you cannot be sitting in the classroom and you do not have an access to the class materials if your name is not on the attendance sheet.

An example from my code:

My code with strong params

If you would like to know more details about strong params and mass assignment, please refer to Rails Guide Mass Assignment .

Cover Image: https://cdn.searchenginejournal.com/wp-content/uploads/2020/08/a-personalized-entity-repository-in-the-knowledge-graph-5f48cec744afc.png

Mass Assignment Vulnerability: https://en.wikipedia.org/wiki/Mass_assignment_vulnerability

Strong params: https://guides.rubyonrails.org/action_controller_overview.html#strong-parameters

Top comments (0)

pic

Templates let you quickly answer FAQs or store snippets for re-use.

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink .

Hide child comments as well

For further actions, you may consider blocking this person and/or reporting abuse

clouddiadem profile image

Hosting Your Company's landing page (static website) on Google Cloud Using HTTPS & HTTP With Azure DNS Zone record

Adaeze Nnamdi-Udekwe - Jun 4

debasmita-a profile image

Taking my first step with technical blogging!

Debasmita Adhikari - Jun 4

afnan_ahmed profile image

Scripting vs. Programming Languages: Uncover the Key Differences Every Developer Should Know!

Afnaan - Jun 4

thenjdevopsguy profile image

Combing Kubeflow With A Dedicated Stack: Enter deployKF

Michael Levan - Jun 4

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Mission Critical Labs

Mass Assignment and Security in Ruby on Rails

By Jeff Hunter

Monday, August 3, 2009

The topic of security vulnerabilities exposed through attributes= in ActiveRecord::Base recently came up on the SF Ruby Meetup list . The related blog entry can be found here . It’s an important question about Rails, and one that a little information can help clarify what to worry about and what not to worry about.

First off, for anyone not familiar enough with Rails, what is attributes= ?. It’s the magic method that allows mass assignment of attributes from a hash. It’s what lets you do things like the following with your active record classes:

The attributes= method takes each key in the hash, and as long as your model provides a mutator method for that attribute (responds to “key=” , and, of course, each column in your table gets one of these mutators created by default). However, before attributes= begins processing the hash, it first passes it to remove_attributes_protected_from_mass_assignment (unless you’ve called attributes= with guard_protected_attributes set to false). By default, this will exclude the primary key column, the inheritance column (e.g. type), and the column named id (if your primary key has another name). Everything else is fair game.

Protecting Attributes

For simple models, the default behavior may be just fine. You don’t have to worry about your id or type columns getting changed, and anything else can be easily used with update_attributes . Things can get tricky, though, once you start adding in some of the extra goodies in Rails. Let’s say, for example, that I have a blog_posts table. I have a simple model that just inherits from ActiveRecord::Base and I’ve decided to add created_at and updated_at fields to get some automatic time stamping behavior. Let’s say the update action in my controller looks like this:

Here, any HTTP client can pass me a parameter named blog_post[created_at] and my creation time will be set to whatever value is passed in (any value passed in for updated_at will be overridden when the record is saved, so it’s not exposed in this particular scenario). That’s probably not what I want. I probably only want to allow the creation time to be set when the record is first saved.

There are a few different ways to protect my created_at attribute. ActiveRecord::Base provides two mechanisms for controlling which attributes are weeded out by remove_attributes_protected_from_mass_assignment . You can use attr_protected to specify a list of additional attributes which may not be used with attributes= (a black list). Alternatively, you can use attr_accessible to specify an exclusive list of attributes that may be used with attributes= (a white list). If you use attr_accessible , any attribute not in the list you specify cannot be used with mass assignment. Lastly, in this case we could also just mark created_at as a read-only attribute. Read-only attributes may be mass assigned when calling new, but not through other means. So, either one of these two additions to our model will prevent surprises happening to created_at :

Why doesn’t Rails just protect these magical attributes by default? In my view, what protection you need for the time stamp fields, if any, is really application-specific. While most applications probably don’t want to allow these fields to be set outside of the model itself, that’s not always the case. In the case of my BlogPost example, if I were to add functionality allowing posts to be imported from other blogs, there might be a legitimate case where I want to allow created_at to be explicitly set (to preserve the value from the imported post). Leaving this decision to the application developer ultimately provides the most flexibility, but it does require some awareness of the consequences when using mass assignment.

Associations

A forged created_at value isn’t terribly dire for most applications, but plugins and associations can add new assignment methods to your model, some of which may cause much bigger security problems. Associations in particular can expose some security vulnerabilities for the naïve programmer. Coming back to my blog post example, let’s say I want to track the author of each post. I have a User model, and, for simplicity, I’m just going to let the author be tracked as the user property on a blog post:

With no modification to my controller, I could wind up with a very nasty surprise if an HTTP client were to pass in a blog_post[user_id] parameter. In effect, it could allow anyone to spoof the author of a post or corrupt the data in my table by specifying an invalid user id. In this example, there’s really no case where I want to allow unchecked mass assignment to the user_id property, so changing my model to prohibit that will provide some added protection:

That leaves me with the issue of how to legitimately set the author on a blog post. For the sake of simplicity, let’s say I have the current user id stored in the session. We’ll imagine my application controller takes care of preventing users that haven’t logged in from accessing my controller, so I don’t have to worry about the id not being set. (Perhaps not the best implementation, but, again, it keeps this example simple.) Lastly, in my application I consider the author to be the user who creates the post, not any subsequent users who edit it, so I’ll do this work in the create method:

Here I’m actually using the user assignment method created by the association. I could assign directly to the user_id attribute, but for the cost of an additional database call, I’ll get an exception if I try to assign an invalid id. Whether that’s really worth doing or not depends and involves using some of your own judgement. What gets highlighted here, though, is yet another assignment method we’ve acquired. Do we need to worry about protecting the user= method as well? You certainly can protect it the same way. However, that method will throw an AssociationTypeMismatch exception if you try to assign anything other than a User model instance, which provides some protection from the kind of attack that user_id is vulnerable to. The one exception to this kind of type-based protection is classes which have association collections (reference many associated objects of the same type). The _ids methods that are added by has_many and has_and_belongs_to_many could be assigned to through mass assignment using HTTP parameters, so some thought should be put into whether or not to protect them in your application.

Other than using attr_protected , there is another way you could potentially safeguard user_id from malicious HTTP clients, and it builds on the kind of precaution in the previous controller example. You could simply validate the attribute. Here’s what that might look like:

This, of course, doesn’t prevent an HTTP client from setting the user_id (unless the controller always explicitly assigns the user after a mass assignment), but it does prevent assigning an invalid user id, whether by the HTTP client or application code using the model, and it some applications that may be sufficient. It also has the added draw of containing the safeguards specific to a model within the model instead of letting them leak out into the controller.

At about this point in the discussion, I should point out that one blog entry referenced in the original thread has a very different take. The author of that post argues for using attr_accessible for every model, always. That’s certainly available in ActiveRecord for you to do that if you choose, but I fundamentally disagree with that as an approach and I feel it runs counter to the spirit of Rails. It solves the problem of potentially exposing an attribute for mass assignment without intending to do so, but at the cost of quite a bit of tedium on any sizable application. You are forced to enumerate all columns which can be used with mass assignment (which may well be most) for all tables and to update the list for every schema change. That’s highly error prone, and part of the whole point of the ActiveRecord approach is not configuring your entire schema in both the database and the model.

Context Sensitive Attributes

In many real-world applications it’s not just a matter of whether or not to allow an attribute to be assigned to, but when and who is allowed. In my blog example, I may decide that administrators are allowed to post as other users and can choose the author from a drop-down list. Naturally, I wouldn’t want to allow non-administrators to do so. In other words, the context of the assignment matters. In fact, this was the underlying issue of the original message in the thread. Easily enough you could limit mass assignment to the subset of attributes which can always be assigned to in any context and then manually deal with the exceptions in the controller. In my example that might look something like:

I’m assuming here that I’ve added a current_user method to the application controller that returns the user object for the currently logged in user. This handles the issue, but it’s not particularly elegant, and can quickly get unwieldy if, as in actual applications, many of these exceptions occur in many different places.

The temptation is to try to somehow make all the magic happen within the model. Another list member wound up blogging about this very issue here . I agree with his assessment that the model really isn’t a place to put that kind of contextual knowledge. Contextual information belongs in the controller. He suggests an approach that allows lists of sensitive parameters to be declared in the model and then selectively used to filter parameters by the controller. I think an ideal situation would allow the user to declare multiple filtering lists in the model and then selectively choose them from the controller, possibly applying them as part of a mass assignment call. And, of course, validation should still be applied for sensitive bits like foreign keys. Unfortunately, as far as I know, no plugin yet exists to do all of that magically.

So, to summarize a bit, I really see the question that spawned all of this to be touching on two slightly different issues: general security/data integrity issues associated with mass assignment and how to more elegantly handle filtering parameters for mass assignment based on context. Unfortunately, there really isn’t a single best practice for the latter, but I’d certainly be interested in hearing how others address it. I don’t, as some would seem to argue, feel that either attr_protected or attr_accessible have outlived their usefulness. Even in an application that strictly adheres to a strong division of responsibilities between the model and controller, they make sense for attributes that the model itself may wish to exclude from mass assignment, such as time stamps or other attributes which may have special meaning or behavior.

Tuesday, August 4, 2009

Shannon -jj Behrens

Thanks for your comments, and thanks for referencing my blog post. I added a comment on my blog referencing yours ;) Your post is very well written, and describes the problem perfectly. I'm a real stickler about a lot of things. Hence, I'm really a fan of being closed by default. Unless I explicitly say otherwise, things like @blog_post.user_id should never be updatable by attributes=. That's why I really like the idea of using ActiveRecord::Base.send(:attr_accessible, nil). That makes it so that if any other engineer makes a mistake, he gets a bug (i.e. a field that isn't being updated) instead of a security vulnerability. I'm definitely up for hearing about other approaches to solving the attributes= problem, but I really want things to be closed by default. For instance, one of my only complaints about Rails is that you have to remember to call h() in your templates. The problem is that people aren't perfect. One thing I really liked about Genshi (which is another templating engine in Python) is that it would automatically escape HTML by default, unless it knew the HTML was coming from another template. Similarly, most modern Linux distributions have all ports closed by default. The OpenBSD guys are some of the most security conscious guys on the planet, but even they have occasionally made mistakes. That's why it's better to not have sshd listening by default unless you decide you really need to, and you're going to make sure the system stays up to date. Getting back to your post, I guess I'd rather have " @blog_post.user_id = params[:blog_post][:user_id] if current_user.admin?" in my controller than risk someone inadvertently leaving a backdoor open. Personally, I don't even find it all that ugly. It just says, "If you're an admin, you're also allowed to set the :user_id when you use this action." It's okay if we disagree, though. Engineers generally do ;)

Comments are now closed for this post.

Mass Assignment

Introduction.

Software frameworks sometime allow developers to automatically bind HTTP request parameters into program code variables or objects to make using that framework easier on developers. This can sometimes cause harm.

Attackers can sometimes use this methodology to create new parameters that the developer never intended which in turn creates or overwrites new variable or objects in program code that was not intended.

This is called a Mass Assignment vulnerability.

Alternative Names

Depending on the language/framework in question, this vulnerability can have several alternative names :

  • Mass Assignment: Ruby on Rails, NodeJS.
  • Autobinding: Spring MVC, ASP NET MVC.
  • Object injection: PHP.

Suppose there is a form for editing a user's account information:

Here is the object that the form is binding to:

Here is the controller handling the request:

Here is the typical request:

And here is the exploit in which we set the value of the attribute isAdmin of the instance of the class User :

Exploitability

This functionality becomes exploitable when:

  • Attacker can guess common sensitive fields.
  • Attacker has access to source code and can review the models for sensitive fields.
  • AND the object with sensitive fields has an empty constructor.

GitHub case study

In 2012, GitHub was hacked using mass assignment. A user was able to upload his public key to any organization and thus make any subsequent changes in their repositories. GitHub's Blog Post .

  • Whitelist the bindable, non-sensitive fields.
  • Blacklist the non-bindable, sensitive fields.
  • Use Data Transfer Objects (DTOs).

General Solutions

An architectural approach is to create Data Transfer Objects and avoid binding input directly to domain objects. Only the fields that are meant to be editable by the user are included in the DTO.

Language & Framework specific solutions

Whitelisting.

Take a look here for the documentation.

Blacklisting

Nodejs + mongoose, ruby on rails, php laravel + eloquent, jackson (json object mapper).

Take a look here and here for the documentation.

GSON (JSON Object Mapper)

Take a look here and here for the document.

JSON-Lib (JSON Object Mapper)

Flexjson (json object mapper), references and future reading.

  • Mass Assignment, Rails and You

Authors and Primary Editors

Abashkin Anton - [email protected]

results matching " "

No results matching " ".

  • 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.

We'd really appreciate it if you could take a minute to rate how valuable this lesson was for you and provide feedback to help us improve! Also, make sure to check out our lessons on other common vulnerabilities.

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?

Overreliance on llms, insecure plugins for llms, snyk apprisk pro - using application analytics (tenant->analytics->applications).

Navigation Menu

Search code, repositories, users, issues, pull requests..., provide feedback.

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly.

To see all available qualifiers, see our documentation .

  • Notifications You must be signed in to change notification settings

Mass_Assignment_Cheat_Sheet.md

Latest commit, file metadata and controls, mass assignment cheat sheet, introduction.

Software frameworks sometime allow developers to automatically bind HTTP request parameters into program code variables or objects to make using that framework easier on developers. This can sometimes cause harm.

Attackers can sometimes use this methodology to create new parameters that the developer never intended which in turn creates or overwrites new variable or objects in program code that was not intended.

This is called a Mass Assignment vulnerability.

Alternative Names

Depending on the language/framework in question, this vulnerability can have several alternative names :

  • Mass Assignment: Ruby on Rails, NodeJS.
  • Autobinding: Spring MVC, ASP NET MVC.
  • Object injection: PHP.

Suppose there is a form for editing a user's account information:

Here is the object that the form is binding to:

Here is the controller handling the request:

Here is the typical request:

And here is the exploit in which we set the value of the attribute isAdmin of the instance of the class User :

Exploitability

This functionality becomes exploitable when:

  • Attacker can guess common sensitive fields.
  • Attacker has access to source code and can review the models for sensitive fields.
  • AND the object with sensitive fields has an empty constructor.

GitHub case study

In 2012, GitHub was hacked using mass assignment. A user was able to upload his public key to any organization and thus make any subsequent changes in their repositories. GitHub's Blog Post .

  • Allow-list the bindable, non-sensitive fields.
  • Block-list the non-bindable, sensitive fields.
  • Use Data Transfer Objects (DTOs).

General Solutions

An architectural approach is to create Data Transfer Objects and avoid binding input directly to domain objects. Only the fields that are meant to be editable by the user are included in the DTO.

Language & Framework specific solutions

Allow-listing.

Take a look here for the documentation.

Block-listing

Nodejs + mongoose, ruby on rails, php laravel + eloquent, jackson (json object mapper).

Take a look here and here for the documentation.

GSON (JSON Object Mapper)

Take a look here and here for the document.

JSON-Lib (JSON Object Mapper)

Flexjson (json object mapper), references and future reading.

  • Mass Assignment, Rails and You

Mass Assignment in Ruby

Vulnerable example, rails >= 4.

In Rails 4 and newer, protection against mass assignment is on by default. The Action Controller Parameters must be used to choose which attributes should be permitted for mass updating by using the permit method.

A vulnerable example would explicitly permit an unsafe attribute, such as is_admin .

An attacker could craft a request by adding the is_admin POST field with value 1 to exploit the attack and register a new user with administrative privileges.

It’s possible to change this safe default by either setting the permit_all_parameters to modify all new instances or by updating a single instance by invoking the permit declaration with .permit! .

Rails < 4

In previous versions, the mass assignment feature may allow an attacker to set any model’s attributes. The following Ruby snippet shows a Ruby On Rails controller that creates a new user based on the user-provided user object.

Make sure to only permit values that are safe to be set. Foreign keys are likely unsafe, as they may allow an attacker to manipulate foreign records.

Old versions of Ruby On Rails should use the attr_protected method, which takes a list of attributes that will not be accessible for mass assignment. For example:

The attr_accessible method can also be used to enforce an allow list approach. It takes a list of attributes that will be accessible, while all other attributes will be protected.

Ruby On Rails Security Guide - Mass Assignment

Ruby On Rails Guides - Action Controller Overview - Strong Parameters

CWE - CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes

OWASP - Mass Assignment Cheat Sheet

COMMENTS

  1. What is mass-assignment in Rails 3

    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 ...

  2. Mass Assignment

    This is called a Mass Assignment vulnerability. Alternative Names¶ Depending on the language/framework in question, this vulnerability can have several alternative names: Mass Assignment: Ruby on Rails, NodeJS. Autobinding: Spring MVC, ASP NET MVC. Object injection: PHP. Example¶ Suppose there is a form for editing a user's account information:

  3. Ruby on Rails

    We're exploring a new way to deal with mass-assignment protection in Rails. Or actually, it's not really a new way, it's more of an extraction of established practice with some vinegar mixed in for when you forget. This new approach is going to be a part of Rails 4.0 by default, but we'd like your help in testing and forming it well in advance of that release.

  4. Ruby on Rails Guides: Ruby On Rails Security Guide

    Ruby On Rails Security Guide. This manual describes common security problems in web applications and how to avoid them with Rails. If you have any questions or suggestions, please mail me, Heiko Webers, at 42 {_et_} rorsecurity.info. ... The mass-assignment feature may become a problem, as it allows an attacker to set any model's attributes ...

  5. Ruby On Rails: Strong Params and Mass Assignment

    What is mass assignment? The mass assignment passes a :key => value params hash to a model's create() or new() method to create an instance. A benefit of using a mass assignment. The mass assignment can simplify creating an instance of a model with multiple attributes. AnimalTrainer.create(.

  6. ActiveModel::MassAssignmentSecurity::ClassMethods

    Mass assignment security provides an interface for protecting attributes from end-user assignment. For more complex permissions, mass assignment security may be handled outside the model by extending a non- ActiveRecord class, such as a controller, with this behavior. For example, a logged in user may need to assign additional attributes ...

  7. ruby on rails

    I'm doing a security audit on a Rails 2.3.8 application and one of the things that has come up is our lack of attr_protected or attr_accessible in my model definitions. I understand the reasoning behind them, and have even written a gem to assist with mass assignment, but I'm looking for attributes that I might potentially be missing.. The problem I have is determining which fields should be ...

  8. Mass Assignment and Security in Ruby on Rails

    Mass Assignment and Security in Ruby on Rails. By Jeff Hunter. Monday, August 3, 2009. The topic of security vulnerabilities exposed through attributes= in ActiveRecord::Base recently came up on the SF Ruby Meetup list. The related blog entry can be found here. It's an important question about Rails, and one that a little information can help ...

  9. ActiveRecord::AttributeAssignment

    assign_attributes (new_attributes, options = {}) Link. Allows you to set all the attributes for a particular mass-assignment security role by passing in a hash of attributes with keys matching the attribute names (which again matches the column names) and the role name using the :as option. To bypass mass-assignment security you can use the ...

  10. Mass Assignment · OWASP Cheat Sheet Series

    This is called a Mass Assignment vulnerability. Alternative Names. Depending on the language/framework in question, this vulnerability can have several alternative names: Mass Assignment: Ruby on Rails, NodeJS. Autobinding: Spring MVC, ASP NET MVC. Object injection: PHP. Example. Suppose there is a form for editing a user's account information:

  11. Mass Assignment in Rails. Ruby on Rails is known as a useful…

    Mass Assignment in Rails. Ruby on Rails is known as a useful, powerful framework for both back end and full stack web development. Thanks to the opinionated nature of Ruby, Rails is an accessible ...

  12. What is mass assignment?

    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.

  13. Ruby on Rails

    One of the most common security issues in a Rails application is the mass-assignment vulnerability which allows a user to set any attribute on the model. Lea...

  14. Mass_Assignment_Cheat_Sheet.md

    Mass Assignment: Ruby on Rails, NodeJS. Autobinding: Spring MVC, ASP NET MVC. Object injection: PHP. Example. Suppose there is a form for editing a user's account information:

  15. Mass assignment vulnerability

    Mass assignment is a computer vulnerability where an active record pattern in a web application is abused to modify data items that the user should not normally be allowed ... In 2012 mass assignment on Ruby on Rails allowed bypassing of mapping restrictions and resulted in proof of concept injection of unauthorized SSH public keys into user ...

  16. Getting started guide: warn about mass assignment?

    Regarding Getting Started with Rails — Ruby on Rails Guides The mass assignment in the code example respond_to do |format| if @post.update_attributes(params[:post]) format.html { redirect_to(@post, ... allows to edit the comments, too. This is not a problem because later, authentication is added for this method. However, I think that newcomers (who the guides are for) will think that update ...

  17. Mass Assignment in Ruby

    Mass Assignment in Ruby . Play Ruby Labs on this vulnerability with SecureFlag! Vulnerable Example Rails >= 4 . In Rails 4 and newer, protection against mass assignment is on by default. The Action Controller Parameters must be used to choose which attributes should be permitted for mass updating by using the permit method.

  18. Rails Mass Assignment

    Description. Ruby On Rails is a popular framework used to build web applications based on the Model-View-Controller (MVC) architectural pattern. A mass assignment vulnerability occurs when an application automatically performs the mapping between a request parameters and a model attributes. This vulnerability can be leveraged by an attacker to ...

  19. Understanding SOLID Principles for Ruby on Rails Development

    The SOLID principles are a set of five design guidelines that can help developers achieve this goal. When applied to Ruby on Rails development, these principles can lead to cleaner, more efficient code. Let's delve into each of these principles and see how they can be applied in a Ruby on Rails context. S: Single Responsibility Principle (SRP)

  20. Ruby on Rails

    Ruby on Rails - Has_many, Mass Assignment issue. Ask Question Asked 11 years, 9 months ago. Modified 11 years, 9 months ago. Viewed 1k times 0 I'm using rails 3.2.3 and am having issues with mass assignement. ... Rails mass assignment issue. 0. rails 3 has_and_belongs_to_many doesn't assign record. 0. Mass Assignment issue in rails. 1.

  21. ruby on rails

    0. You can assign the attribute manually, for example if your model is named User you can do the following : user = User.first. user.update_attributes(attributes_hash) user.admin = true. user.save. attr_accessible is used only for mass assignment via update_attributes for example, but you can always assign a specific property by calling it ...