What is mass assignment/overposting?
Mass assignment happens when an API blindly binds all incoming JSON fields to your entity model, allowing attackers to set properties they shouldn’t.
Example
Suppose your User
entity has a IsAdmin
flag.
public class User
{
public int Id { get; set; }
public string Username { get; set; }
public string Email { get; set; }
public bool IsAdmin { get; set; } // Should never be set by the client
}
If your Web API controller does this:
[HttpPost]
public async Task<IActionResult> Register(User user)
{
_context.Users.Add(user);
await _context.SaveChangesAsync();
return Ok(user);
}
An attacker can send:
{
"username": "hacker",
"email": "[email protected]",
"isAdmin": true
}
Now the attacker registers themselves as Admin.
This is overposting (exposing unintended properties to clients).
How to Prevent Overposting in ASP.NET Core
1. Use DTOs (Data Transfer Objects)
Never expose your Entity models directly to the API.
Instead, use DTOs that only contain the fields you want the client to update.
public class RegisterDto
{
[Required, StringLength(50)]
public string Username { get; set; }
[Required, EmailAddress]
public string Email { get; set; }
[Required, StringLength(100)]
public string Password { get; set; }
}
Controller
[HttpPost("register")]
public async Task<IActionResult> Register(RegisterDto dto)
{
var user = new User
{
Username = dto.Username,
Email = dto.Email,
IsAdmin = false // Explicitly controlled
};
_context.Users.Add(user);
await _context.SaveChangesAsync();
return Ok("User registered successfully");
}
Only safe fields are accepted.
Sensitive properties ( IsAdmin
) are not exposed to binding.
2. Use Bind
Attribute (MVC only, not Web API best practice)
You can restrict bound properties in MVC controllers with [Bind]
.
public IActionResult Create([Bind("Username,Email,Password")] User user)
{ ... }
Not recommended for Web APIs—use DTOs instead.
3. Explicit Model Updates
When updating existing entities, don’t call Update()
with the whole model.
Instead, the map only allowed properties.
Vulnerable
[HttpPut("{id}")]
public async Task<IActionResult> Update(int id, User user)
{
_context.Update(user); // Overwrites everything, including IsAdmin
await _context.SaveChangesAsync();
return Ok(user);
}
Safe
[HttpPut("{id}")]
public async Task<IActionResult> Update(int id, UpdateUserDto dto)
{
var user = await _context.Users.FindAsync(id);
if (user == null) return NotFound();
// Only update safe fields
user.Username = dto.Username;
user.Email = dto.Email;
await _context.SaveChangesAsync();
return Ok(user);
}
4. Automapper with Explicit Mapping
If using AutoMapper, configure mappings carefully:
CreateMap<RegisterDto, User>()
.ForMember(dest => dest.IsAdmin, opt => opt.Ignore()); // Prevent assignment
5. Use TryUpdateModelAsync
with Property Whitelisting
If you want to bind selectively:
await TryUpdateModelAsync(user, "",
u => u.Username, u => u.Email);
6. Audit Sensitive Fields
Even with DTOs, add server-side checks to ensure properties like IsAdmin
, Balance
, Role
, etc. are only modified by authorized users.
Example
if (dto.Role != null && !User.IsInRole("Admin"))
{
return Forbid();
}
Best Practices Checklist
Always use DTOs instead of binding entities directly.
Whitelist properties explicitly (DTOs, TryUpdateModelAsync
, AutoMapper configs).
Do not expose sensitive properties (e.g., IsAdmin
, Balance
, CreatedDate
).
Never call _context.Update(entity)
blindly —update only safe fields.
Audit sensitive updates with role-based authorization.
Conclusion
Mass assignment/overposting is a silent but dangerous vulnerability in ASP.NET Core Web APIs.
By using DTOs, explicit property mapping, and whitelisting techniques, you ensure that attackers cannot overwrite sensitive fields.
Always remember:
Bind only what you trust; never trust what you bind.