Skip to main content

Free 30-min security demo  — We'll scan your real code and show live findings, no commitment Book Now

Offensive360
Home / Knowledge Base / Mass Assignment
High CWE-915 A04:2021 Insecure Design

Mass Assignment

Mass assignment lets attackers set unintended model properties via extra HTTP request fields. Learn how DTOs and property allow-lists prevent it.

Affects: C#JavaRubyPythonJavaScriptPHP

What is Mass Assignment?

Mass assignment occurs when a framework automatically maps HTTP request parameters to model/entity properties. If the application binds user input directly to a domain object without restricting which properties are settable, an attacker can include extra fields in their request to set properties they are not supposed to control — such as isAdmin, role, balance, or confirmed.

The vulnerability is especially common in MVC frameworks (Rails, ASP.NET Core, Spring, Laravel) that offer automatic model binding as a convenience feature. It famously affected GitHub in 2012, where a researcher used mass assignment to add their SSH key to any organization.

How exploitation works

A user updates their profile. The intended request:

{ "name": "Alice", "email": "alice@example.com" }

The attacker adds an extra field:

{ "name": "Alice", "email": "alice@example.com", "role": "admin", "isActive": true }

If the server binds the entire request body to a User entity, all three fields — including role — are written to the database.

Vulnerable code examples

ASP.NET Core — direct entity binding

// VULNERABLE: Binds ALL User properties from request body, including Role
[HttpPut("profile")]
[Authorize]
public async Task<IActionResult> UpdateProfile([FromBody] User user)
{
    _db.Users.Update(user); // Attacker can set user.Role = "admin"
    await _db.SaveChangesAsync();
    return Ok();
}

Ruby on Rails — unsanitized params

# VULNERABLE: Permits all params — attacker can set :admin => true
def update
  @user = User.find(params[:id])
  @user.update(params[:user]) # No strong parameters — mass assignment
end

Secure code examples

ASP.NET Core — dedicated DTO

// Define a DTO with only the properties users are permitted to change
public class UpdateProfileDto
{
    public string Name { get; set; }
    public string Email { get; set; }
    // No Role, IsAdmin, Balance — not included means not bindable
}

// SECURE: Bind DTO, map explicitly to the entity
[HttpPut("profile")]
[Authorize]
public async Task<IActionResult> UpdateProfile([FromBody] UpdateProfileDto dto)
{
    var user = await _db.Users.FindAsync(CurrentUserId);
    user.Name = dto.Name;
    user.Email = dto.Email;
    await _db.SaveChangesAsync();
    return Ok();
}

Ruby on Rails — strong parameters

# SECURE: Strong parameters allow-list only safe attributes
def update
  @user = User.find(params[:id])
  @user.update(user_params)
end

private

def user_params
  params.require(:user).permit(:name, :email) # :admin, :role not permitted
end

What Offensive360 detects

  • Direct entity binding — Controller actions binding request bodies directly to domain entities or EF/Hibernate models
  • Missing DTOs — Absence of Data Transfer Objects separating API input from domain models
  • Unfiltered params.merge or request.body — Rails, Django, or Laravel handlers that update models without strong parameter filtering
  • [Bind] attribute misuse — ASP.NET’s [Bind] include lists that are overly permissive or missing

Remediation guidance

  1. Always use DTOs — Define separate Input/Request classes that contain only the fields users are allowed to set. Map these explicitly to domain objects.

  2. Use strong parameters (Rails)params.require(...).permit(...) is the Rails convention. Never use params[:user] directly.

  3. Avoid [Bind] in favor of explicit mapping — While [Bind(Include=...)] helps, it is error-prone. Prefer separate input models.

  4. Apply [BindNever] or [JsonIgnore] on sensitive fields — Decorate properties like Role or IsAdmin with attributes that prevent them from being bound from user input.

  5. Audit model binding on every endpoint — During code review, verify that every model-binding operation has a corresponding restriction.

References

By Offensive360 Security Research Reviewed: March 2026

Detect Mass Assignment automatically

Run Offensive360 SAST on your codebase to find this and 100+ other vulnerabilities.