Last updated
Last updated
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:
The web application implements the following view:
The controller that handles the creation request (Spring provides the automatic bind with the User
model):
In this case, the browser sends the following request when the form is submitted:
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.
This page contains recommendations for the implementation of protection against mass parameter assignment attacks.
Use Data Transfer Objects instead of binding parameters directly to internal objects.
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.
For example, the UserRegistrationFormDTO
below does not contain the isAdmin
parameter that might be used to elevate privileges as it is described in the section:
Implement comprehensive input validation for each request parameter, see the page.
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 section: