Login
ChallengesLearn
Scoreboard
Teams
SPNZ

LearnAPI SecurityAPI Mass Assignment
API Security·Lesson 6 of 11

API Mass Assignment

OWASP API #6. The framework binds every field in the JSON body to a model attribute. Send is_admin=true or role=admin in a PATCH request — the model writes it without explicit code.

Advanced12 min
APIMass AssignmentBinding
Loading lesson…
PreviousExcessive Data ExposureNextAPI Rate Limiting & Abuse

© 2026 SPNZ.

Terms of ServicePrivacy PolicyCookie Policy

The framework auto-binds all JSON body fields to model attributes without an explicit allowlist. An attacker sends PATCH /api/users with {"name": "new name", "is_admin": true}— and the framework binds is_adminto the model. This is OWASP API Security Top 10 #6: Mass Assignment.

What you'll be able to do
  • Distinguish mass assignment from excessive data exposure.
  • Identify framework auto-binding behaviour that enables mass assignment.
  • Apply allowlists and DTOs to prevent unwanted field binding.
Key terms
Mass assignment
A vulnerability where framework auto-binding writes client-supplied fields to model attributes without validation, allowing attackers to modify fields they should not control.
Allowlist (permitted params)
An explicit list of parameter names that the framework is allowed to bind to the model. Any parameter not on the list is silently ignored.
Auto-binding
The automatic conversion of JSON request body fields into model attributes, commonly performed by ORM-backed frameworks such as Rails, Spring Boot, and Django REST Framework.
DTO with mutable subset
A Data Transfer Object that only includes fields the client is permitted to modify, preventing sensitive fields like role or is_admin from being bound.
What is it?

When the client writes what it should not

Mass assignment occurs when a framework binds every field in a JSON request body directly to a database model without checking which fields the client is allowed to set. The classic example is Ruby on Rails, which had a notorious attr_accessible era — but the same pattern appears in Spring Boot, Django REST Framework, ASP.NET, and Fastify.

The key distinction from Excessive Data Exposure (OWASP #3) is direction: exposure is about what the API returns, while mass assignment is about what the API accepts. A single endpoint can suffer from both — returning sensitive fields and accepting unauthorised writes to them.

Mass assignment attack flow
Mini Map
Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.
Try it

Profile editor

Edit a user profile with and without mass assignment protection. In vulnerable mode, hidden fields like role and is_admin are bound from the request body. In safe mode, an allowlist strips them.

User Profile Editorprod
Aadmin
PATCH /api/users/42

Profile editor

Edit user profile fields. The form sends a JSON body that may include hidden fields.

Try adding "role": "admin" or "is_admin": true
Database state after update
Name: Alice Johnson
Email: alice@corp.com
Bio: Senior developer working on access control systems.
Role: user
is_admin: false
Form fields
name
visible
email
visible
bio
visible
role
hidden
is_admin
hidden
Tip: Edit the JSON body directly and add "is_admin": true. In vulnerable mode, the framework binds it — in safe mode, the allowlist strips it.
Real-world relevance

GitHub mass assignment 2012

In 2012, GitHub suffered a mass assignment vulnerability in its Rails-based API. An attacker could add themselves as a collaborator on any public repository by sending a POST /api/repos/:owner/:repo/collaborators request with additional parameters. The Rails controller used update_attributes(params[:user]) without an allowlist, so the attacker could set their permission level to “admin” on the repository.

The vulnerability was discovered by security researcher Egor Homakov, who responsibly disclosed it after demonstrating the exploit on a public repository. GitHub's fix was to introduceattr_accessible (later strong_parameters) across the entire API surface. The incident became a landmark case study in the Rails community and spurred the adoption of permit-based parameter handling as a default pattern.

Mitigation

Allowlists, DTOs, and never trust client input for roles

The fix is straightforward: never bind request body fields directly to a model. Use an allowlist (permitted parameters) that explicitly lists every field the client is allowed to modify. For read-only or sensitive fields like role, is_admin, or permissions, never accept them from the client — set them server-side based on business logic.

javascriptsafe
// VULNERABLE — Rails-style mass assignment
def update
  @user = User.find(params[:id])
  @user.update_attributes(params[:user])
  # params[:user] may contain is_admin: true
end

// VULNERABLE — Spring Boot auto-binding
@PutMapping("/users/{id}")
public User update(@RequestBody User user) {
    // User object bound from JSON includes all fields
    return userRepository.save(user);
}

// SAFE — Rails strong parameters
def update
  @user = User.find(params[:id])
  @user.update(user_params)
end

private

def user_params
  params.require(:user).permit(:name, :email, :bio)
  # :role and :is_admin are silently ignored
end

// SAFE — Spring Boot DTO
class UpdateUserDTO(
    val name: String?,
    val email: String?,
    val bio: String?,
    // role and isAdmin deliberately absent
)

@PutMapping("/users/{id}")
fun update(@Valid @RequestBody dto: UpdateUserDTO): User {
    val user = userRepository.findById(id).orElseThrow()
    dto.name?.let { user.name = it }
    dto.email?.let { user.email = it }
    dto.bio?.let { user.bio = it }
    // role is never overwritten from client input
    return userRepository.save(user)
}
Further reading
  • OWASP API Security #6 — Mass Assignment(OWASP)
  • GitHub mass assignment postmortem (2012)(Egor Homakov)
  • Rails strong parameters guide(Ruby on Rails Guides)
Key takeaways

What to remember

  • Mass assignment is about what the API accepts, not what it returns — an attacker writes unauthorised fields to the model.
  • The root cause is framework auto-binding without an allowlist for permitted fields.
  • Use explicit DTOs or strong parameters that list only the fields the client is allowed to modify.
  • Never accept role, is_admin, or permission fields from client input — set them server-side.

Knowledge check

0/3 answered · 0 correct
  1. 1.What is the difference between excessive data exposure and mass assignment?

  2. 2.Which mitigation is most effective against mass assignment?

  3. 3.Why does framework auto-binding make mass assignment a common vulnerability?