Overview
Broken Object Property Level Authorization vulnerabilities arise when an ASP.NET Core application binds user input directly to object properties and relies on coarse-grained or absent per-property checks. Attackers can craft payloads that modify properties they should not be allowed to change (for example IsAdmin, owner identifiers, or other sensitive fields), leading to privilege escalation or unauthorized data modification. The risk is amplified when endpoints accept full domain models instead of restricted DTOs, or when binding attributes do not explicitly whitelist permissible properties. This guide emphasizes constraining binding, implementing explicit authorization, and validating changes on the server side to mitigate such flaws.
To provide historical context, CVE-2017-0247 describes a denial-of-service vulnerability in ASP.NET Core related to encoding logic in System.Text.Encodings.Web that could be exploited by improperly calculating the length of certain Unicode characters. While this DoS issue is not a direct object-level authorization flaw, it illustrates security risks in the ASP.NET Core ecosystem from the same era and highlights why timely updates to the framework and dependencies are essential. The patched versions (ASP.NET Core MVC prior to 1.0.4 and 1.1.x prior to 1.1.3) mitigated that specific vulnerability, underscoring the importance of applying vendor fixes alongside correct authorization practices.
The remediation guidance below focuses on preventing broken object property level authorization in ASP.NET Core apps. It advocates using restricted input models (DTOs), whitelisting bound properties, and performing explicit authorization checks before applying changes to sensitive fields. It also recommends upgrading to patched library versions and adopting per-resource or per-property authorization policies to ensure that only authorized users can modify specific properties.
Affected Versions
ASP.NET Core MVC prior to 1.0.4 and 1.1.x prior to 1.1.3 (CVE-2017-0247); see CVE details for exact patch versions
Code Fix Example
ASP.NET Core API Security Remediation
/* Vulnerable pattern: over-binding and updating sensitive properties like IsAdmin */
public class UserUpdateRequest { public int Id; public string UserName; public bool IsAdmin; }
public class UsersController : Controller {
private readonly YourDbContext _db;
public UsersController(YourDbContext db) { _db = db; }
[HttpPost("update")]
public async Task<IActionResult> UpdateVulnerable([FromBody] UserUpdateRequest req) {
var user = await _db.Users.FindAsync(req.Id);
if (user == null) return NotFound();
// Vulnerable: client can set IsAdmin and modify other sensitive fields
user.UserName = req.UserName;
user.IsAdmin = req.IsAdmin; // <-- dangerous binding
await _db.SaveChangesAsync();
return Ok();
}
}
/* Fixed pattern: restrict binding and enforce authorization before changes */
public class UpdateUserRequest { public int Id; public string UserName; }
public class UsersControllerFixed : Controller {
private readonly YourDbContext _db;
private readonly IAuthorizationService _authorizationService;
public UsersControllerFixed(YourDbContext db, IAuthorizationService authorizationService) {
_db = db; _authorizationService = authorizationService; }
[HttpPost("update-fixed")]
public async Task<IActionResult> UpdateFixed([FromBody] UpdateUserRequest req) {
var user = await _db.Users.FindAsync(req.Id);
if (user == null) return NotFound();
// Authorization check for this resource
var auth = await _authorizationService.AuthorizeAsync(User, user, "CanEditUser");
if (!auth.Succeeded) return Forbid();
// Only bind safe fields; do not touch IsAdmin or other sensitive properties
user.UserName = req.UserName;
await _db.SaveChangesAsync();
return Ok();
}
}