API Security · intermediate · ~10 min

Mass assignment

Explain mass assignment and the allowlist fix.

Overview

Mass assignment is auto-binding client JSON onto a model so the client can set fields it shouldn't (role, is_admin, balance). Test by adding sensitive fields to write requests. Fix: allowlist accepted fields per endpoint (DTOs/permit-lists); never bind the raw body.

Why it matters

Mass assignment is a direct privilege-escalation/tampering bug — set role=admin or balance via an ordinary update. It's easy to introduce with ORM convenience features and easy to miss without testing extra fields.

Core concepts

Auto-binding. Every JSON key → model field. Hidden fields. role/is_admin/verified/price ride along. Test. Add returned/sensitive fields to writes; see if they persist. Fix. Per-endpoint field allowlist / explicit DTOs; sensitive fields server-set only.

Lesson

Mass assignment happens when an API binds client-supplied JSON fields straight onto an internal object/model — including fields the client was never meant to set.

The pattern

A profile-update endpoint expects {"name": "...", "email": "..."}. The model also has role, is_admin, account_balance, verified. If the framework auto-binds all incoming fields:

PATCH /api/v1/users/me
{"name":"Ada","email":"a@x.com","role":"admin","is_admin":true}

…and the server happily promotes you. The client sends fields the UI never exposes.

Why it happens

Convenience features (Model.update(request.body), @ModelAttribute, ORM auto-binding) map every JSON key to a column unless restricted. Hidden/internal fields ride along.

How to test

  • Note all fields the API returns for an object — those are candidates to set.
  • Add sensitive-looking fields (role, isAdmin, verified, price, userId) to write requests and check if they stick.

The fix

Allowlist the exact fields each endpoint may accept (explicit DTOs / permit(:name, :email) / binding allowlists). Never bind the raw request body to a model. Mark sensitive fields read-only/server-set. This is the API cousin of the web "business logic / trust the client" problem.

Summary

Mass assignment lets clients write internal fields by exploiting blanket request-body binding. The fix is an explicit allowlist of accepted fields per endpoint, keeping sensitive attributes server-controlled.