# Mass Assignment

## 1. Introduction:

Modern frameworks encourage developers to use functions that automatically bind input from the client into code variables and internal objects. (Easier to code  !-> safe code) The binding of client-provided data (e.g., JSON) to data models, without adequate properties filtering based on an allowlist, usually leads to Mass Assignment. Either through guessing objects properties(eg. `admin: true`, `role: admin`), exploring other API endpoints, reading the documentation, or providing additional object properties in request payloads, allows attackers to modify object properties they are not supposed to.&#x20;

You can read more about Mass Assignment, from an attacker's perspective, [here](https://cheatsheetseries.owasp.org/cheatsheets/Mass_Assignment_Cheat_Sheet.html).

## 2. Typical vulnerable code:

In the usual vulnerable scenario, the developer does not bind what aspect of the object they want to update through the request. Take a look at the following code:

```javascript
const express = require('express');
const app = express();
const router = app.router;

const UserManager = require('UserManager');

/*

Imagine that the schema of the User object looks like:

{
    "uid": String,
    "email": String,
    "password": String,
    "username": String,
    "role": String
}

*/

router.post('/api/reset-password', (req, res) => {

    const token = req.getHeader('Authorization');
    const isValid = UserManager.validateToken(token);
    
    if (isValid) {
        const user = req.body.user;
        UserManager.updateUserSettings(user);
        res.status(200).send();
    } else {
        res.status(403).send();
    }
    
});
```

And now assume that the request would look similar to this:

```http
POST /api/reset-password

.....

{
    "user": {
        "password": "new_password"
    }
}
```

Since the developer does not specifically bind which fields of the accounts they want to update, it follows suit that we can input ANY field(as long as we know/ guess them) and hence update all those fields. With the request of:

```
POST /api/reset-password

.....

{
    "user": {
        "password": "new_password",
        "role": "admin"
    }
}
```

An attacker successfully updates their `role` field into `admin`, thus escalating their privileges.&#x20;

{% hint style="warning" %}
This is just a typical attack scenario, and one can infer that there are several other ways of exploiting this vulnerability(eg. changing another user's password/ email/ username/ etc)
{% endhint %}

## 3. Mitigations:

By far the safest method of protecting against such a vulnerability is using a schema database validation framework(such as [mongoose](https://mongoosejs.com/docs/guide.html)). You can also specifically retrieve the object that you want from the request(eg. `req.body.password`) and have a function that would **ONLY** update the `password` field. Here's how to patch the code:

```javascript
const express = require('express');
const app = express();
const router = app.router;

var UserSchema = new mongoose.Schema({
    uid: String,
    email: String,
    password: String,
    username: String,
    role: String
});

const User = mongoose.model('User', UserSchema);
​
router.post('/api/reset-password', (req, res) => {

    const user_id = req.session.user_id;
    
    if (user_id) {

        User.findbyId(user_id, function (err, user) {
            //   ...
              user.password = req.body.new_password;
              user.save();
            //   ...
            }
        });

    } else {
        res.status(403).send();
    }

});
```

Note that on line `23` we specify which exact field of the user object we want to update.

## 4. Takeaways:

Following these essential points will defend your endpoints against Mass Assignment:

* Bind the fields that you want to work with from the request.
* Do not blindly trust the methods of the frameworks you are working with. Read the documentation!
* All schemas and types that are expected in the requests should be explicitly defined at design time and enforced at runtime.

{% hint style="info" %}
You can find more details about this topic here

* [CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes](https://cwe.mitre.org/data/definitions/915.html)
* [Mass Assignment](https://raw.githubusercontent.com/OWASP/API-Security/master/2019/en/dist/owasp-api-security-top-10.pdf)
* [Mass Assignment Application Security](https://application.security/free-application-security-training/owasp-top-10-api-mass-assignment)
  {% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://vladtoie.gitbook.io/secure-coding/api/mass-assignment.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
