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:

<form method="post" action="/signup">
  <p>
    Enter your email address:
    <input type="text" name="user[email]">
  </p>
  <p>
    Select a password:
    <input type="password" name="user[password]">
  </p>

  <input type="submit" value="Sign up">
</form>

The corresponding controller action creates the user in the database:

def signup
  @user = User.create(params[:user])
  # => User<email: "[email protected]", password: "qwerty", is_administrator: false>
end

An attacker may inject their own HTML into form (or otherwise modify the request):

<form method="post" action="/signup">
  <!-- INJECTED FIELD: -->
  <input type="hidden" name="is_administrator" value="true">

  <p>
    Enter your email address:
    <input type="text" name="user[email]">
  </p>
  <p>
    Select a password:
    <input type="password" name="user[password]">
  </p>

  <input type="submit" value="Sign up">
</form>

The controller action will create the user, letting the attacker gain complete control of the web shop:

def signup
  @user = User.create(params[:user])
  # => User<email: "[email protected]", password: "qwerty", is_administrator: true>
end

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):

def signup
  # Explicit assignment:

  @user = User.create(
    email: params[:user][:email],
    password: params[:user][:password]
  )

  # or whitelisting:

  @user = User.create(
    params.require(:user).permit(:email, :password)
  )
end

More useful information may be found at:

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.

Simple Pricing
  • 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

    $5,000