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:
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
Use Data Transfer Objects instead of binding parameters directly to internal objects.
Clarification
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 section:
publicclassUserRegistrationFormDTO {privateString userid;privateString password;privateString email;// NOTE: isAdmin field is not present// Getters & Setters}
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.
Example
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.
Implement comprehensive input validation for each request parameter, see the Input Validation page.
Auto-binding allow list implementation
Gin Web Framework 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 section: