> For the complete documentation index, see [llms.txt](https://0xn3va.gitbook.io/application-security-handbook/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://0xn3va.gitbook.io/application-security-handbook/web-application/vulnerability-mitigation/mass-parameter-assignment.md).

# Mass Parameter Assignment

## Overview

Many modern software development frameworks bind user input directly into internal objects. This is known as mass parameter assignment or auto-binding. While this feature is helpful to assign parameters to objects, an attacker can use it to write fields that should not be set by a user, leading to privilege escalation, data tampering, bypass of security mechanisms, and more.

For example, consider a Java Spring web application with a `User` object:

```java
public class User {
    private String username;
    private String password;
    private String email;
    private boolean isAdmin;

    // Getters & Setters
}
```

The web application implements the following view:

```html
<form action="/createUser" method="POST">
    <input name="username" type="text">
    <input name="password" type="text">
    <input name="email" text="text">
    <input type="submit" value="Create">
</form>
```

The controller that handles the creation request (Spring provides the automatic bind with the `User` model):

```java
@RequestMapping(value = "/createUser", method = RequestMethod.POST)
public String createUser(User user) {
    userService.add(user);
    return "successPage";
}
```

In this case, the browser sends the following request when the form is submitted:

```
POST /createUser HTTP/1.1
...

username=bob&password=supersecretpassword&email=bob@domain.test
```

Due to the auto-binding, an attacker can add the `isAdmin` parameter to the request, which the controller will automatically bind to the model. As a result, the request below will create a user with administrative privileges.

```
POST /createUser HTTP/1.1
...

username=bob&password=supersecretpassword&email=bob@domain.test&isAdmin=true
```

This page contains recommendations for the implementation of protection against mass parameter assignment attacks.

## General

<div align="left"><img src="/files/QJuMWI21M60ZKzo0mFAN" alt=""></div>

* Use Data Transfer Objects instead of binding parameters directly to internal objects.

<details>

<summary>Clarification</summary>

A Data Transfer Object (DTO) is an object which only contains attributes that can be modified by a user. It serves as an intermediary between received parameters and a final object. Using Data Transfer Objects makes mass parameter assignment or auto-binding completely safe because they do not contain additional parameters that should not be passed by a user.

For example, the `UserRegistrationFormDTO` below does not contain the `isAdmin` parameter that might be used to elevate privileges as it is described in the [Overview](#overview) section:

```java
public class UserRegistrationFormDTO {
    private String userid;
    private String password;
    private String email;

    // NOTE: isAdmin field is not present

    // Getters & Setters
}
```

</details>

* If there is no possibility to use DTOs, use an allow list and non-sensitive parameters to restrict auto-binding only to those. Avoid using block lists.

<details>

<summary>Example</summary>

In the example below, the binding function uses a set of allowed fields, restricting any other field to be auto-bound and preventing the mass parameter assignment attack.

```java
@Controller
public class UserController
{
    @InitBinder
    public void initBinder(WebDataBinder binder, WebRequest request) {
        binder.setAllowedFields(["userid", "password", "email"]);
    }
    // ...
}
```

</details>

* Implement comprehensive input validation for each request parameter, see the [Input Validation](/application-security-handbook/web-application/input-validation.md) page.

## Auto-binding allow list implementation

{% tabs %}
{% tab title="Go: Gin" %}
[Gin Web Framework](https://github.com/gin-gonic/gin) allows mass parameter assignment with functions such as `Bind()`, `shouldBind()` or `mustBind()`. These functions rely on the `form:` tag in a struct and only attributes tagged with `form:` will be considered safe for auto-binding. Use the `form` tag to mark parameters that are safe to be auto-bound.

For example, the `User` struct below does not have the `form:` tag for the `IsAdmin` parameter. It means that `IsAdmin` can not be auto-bound and used to elevate privileges as it is described in the [Overview](#overview) section:

```go
package main

import (
    "log"
    "github.com/gin-gonic/gin"
)

type User struct {
    Username    string  `form:"username"`
    Password    string  `form:"password"`
    Email       string  `form:"email"`
    IsAdmin     bool    `default:false`
}

func main() {
    route := gin.Default()
    route.POST("/createUser", createUser)
    route.Run()
}

func createUser(c *gin.Context) {
    var user User
    if c.ShouldBind(&user) == nil {
        log.Println(user.Username)
        log.Println(user.Password)
        log.Println(user.Email)
        log.Println(user.IsAdmin)
    }
    c.String(200, "Success")
}
```

{% endtab %}
{% endtabs %}

## References

* [OWASP Cheat Sheet Series: Mass Assignment Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Mass_Assignment_Cheat_Sheet.html)
