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

Mass Assignment

Mass assignment vulnerabilities allow attackers to set unintended model properties by submitting extra fields in HTTP requests, leading to privilege escalation and data tampering. Learn how to use DTOs and property allow-lists.

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": "[email protected]" }

The attacker adds an extra field:

{ "name": "Alice", "email": "[email protected]", "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.