ASP MVC: Mass Assignment

 
 
  • Gérald Barré

This post is part of the series 'Vulnerabilities'. Be sure to check out the rest of the blog posts of the series!

#What's Mass Assignment?

Rather than making a big pavement, I'll use an example.

Here is the model used:

C#
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:

Razor
@using(Html.BeginForm())
{
    @Html.EditorFor(model => model.FirstName)
    @Html.EditorFor(model => model.LastName)
    <input type="submit" value="Submit" />
}

And the controller:

C#
[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.

C#
public ActionResult Index([Bind(Include = "FirstName, LastName")]User user)

Or

C#
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.

C#
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!

Follow me:
Enjoy this blog?Buy Me A Coffee💖 Sponsor on GitHub