fbpx
TCM Security is offering free Active Directory Health Checks to any company with 10 or more employees. To inquire, please contact us here.

What is Mass Assignment?

Mass assignment is a feature, and it makes our lives easier when trying to map input passed from the front end to the back end. By automatically assigning values to the properties of an object, we save some time in development and gain some flexibility. However, if not handled properly, it can also introduce security vulnerabilities.

A common scenario

When a web application takes data from a form submission and maps it directly to an object’s properties without validating or filtering, an attacker may exploit this by additional or unexpected fields in the form. This can potentially overwrite or manipulate sensitive data.

In this example, we have a simple user model:

const UserSchema = new Schema({
    username: {
        type: String,
        required: true,
},
    password: {
        type: String,
        required: true,
},
    privileges: {
        type: String,
        required: true,
        default: "user",
    },
});

When a new user is created, the expectation is that the username and password will be submitted from the user.

An insecure way of creating the new user, using Mass Assignment, would be:

app.post('/register', (req, res) => {
    const newUser = new User({ ...req.body });

Here we are using the spread operator. It is used to expand iterable elements into arrays. So in this case, all of the key-value pairs from the re.body will be passed into the User constructor.

A malicious payload would look like this:

{
    "username": "alex",
    "password": "tiramasu",
    "privileges": "admin"
}
mass assignment demo

A secure way to process this would be something like:

app.post("/register", async (req, res) => {
    const { username, password } = req.body;
    const newUser = new User({ username, password });

In the second version of our code, we are being explicit about what fields we allow to be passed from the user, and in our model, we are setting all privileges for new users to “user” by default.

Some other examples of sensitive fields that may be impacted are:

  • Verified
  • Balance
  • Status
  • isAdmin
  • isSubscriber
  • etc

What about web frameworks?

Mass Assignment is commonplace in frameworks too as many of them support Mass Assignment. It’s sometimes also referred to as autobinding. Whilst this is a great feature, it can easily become a security vulnerability when not used appropriately.

Vulnerable code that allows for unintended fields:

@app.route('/users', methods=['POST'])
    def create_user():
    user_data = request.form
    new_user = User(**user_data)

Secure code that extracts only the fields we want to process from the request:

def create_user():
    username = request.form.get('username')
    password = request.form.get('password')
    new_user = User(username=username, password=password)

Detecting Mass Assignment

Discovery of Mass Assignment vulnerabilities can be tricky, though easier if you’re able to carry out code review. I recommend reading through the OWASP WSTG for Testing Mass Assignment to learn more.