ASP MVC: Mass Assignment
This post is part of the series 'Vulnerabilities'. Be sure to check out the rest of the blog posts of the series!
- Impersonation and security
- SQL injections
- How to prevent CSRF attacks
- ASP MVC and XSRF
- Cross-site scripting (XSS)
- ASP MVC: Mass Assignment (this post)
- Regex - Deny of Service (ReDoS)
- Deserialization can be dangerous
- Prevent Zip bombs in a .NET application
- Prevent Zip Slip in .NET
- How to protect against XML vulnerabilities in .NET
#What's Mass Assignment?
Rather than making a big pavement, I'll use an example.
Here is the model used:
public class User
{
public string FirstName { get; set; }
public string LastName { get; set; }
public bool IsAdmin { get; set; }
}
The page allowing to modify only the first and last names of the user:
@using(Html.BeginForm())
{
@Html.EditorFor(model => model.FirstName)
@Html.EditorFor(model => model.LastName)
<input type="submit" value="Submit" />
}
And the controller:
[HttpPost]
public ActionResult Index(User user)
{
return View();
}
What happens when the user clicks the submit button?
The framework will create an instance of type User
and set its properties using the data of the request (query string and body). In our case the form allows only the last name and first name to be defined. But what happens if the attacker guesses the name of the property IsAdmin
and he or she decides to set its value to true
in the URL (https://example.com/mapage?IsAdmin=True
). The binder will use this value while creating the instance of type User
and we will end up with a user considered as administrator.
#How to guard against it?
There are mainly 2 ways to do it.
The first is to use the Bind attribute. This lets you specify which properties must be included or excluded during binding.
public ActionResult Index([Bind(Include = "FirstName, LastName")]User user)
Or
public ActionResult Index([Bind(Exclude = "IsAdmin")]User user)
The second possibility is to define a new class containing only the properties required for this view and to use a tool to do the mapping between the two classes. AutoMapper allows you to do this.
public class UserModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
[HttpPost]
public ActionResult Index(UserModel user)
{
User u = Mapper.Map<UserModel, User>(user);
return View();
}
And voilà.
Do you have a question or a suggestion about this post? Contact me!