What is Mass assignment?
A bug class where an attacker submits extra fields in a request body (JSON, FormData) that the server unsafely uses to update model fields the attacker should not control — like setting `is_admin: true` on their own user record.
Full explanation
Mass assignment happens when server code copies request fields directly into database fields without an allowlist. Common shape: `db.from('users').update(req.body).eq('id', user.id)` — if req.body contains `{ name: 'Alice', is_admin: true }`, the user just made themselves admin. The bug is especially common in TypeScript/JavaScript apps where Zod schemas are too permissive (catch-all `.passthrough()` instead of `.strict()`). API frameworks that auto-bind request bodies to ORM models (Rails before strong_parameters, early NestJS) ship this bug at high frequency.
Example
PATCH /api/users/me handler does `db.from('users').update(await req.json()).eq('id', session.userId)`. Attacker submits `{ "is_admin": true, "tier": "enterprise", "trial_expires_at": "2099-12-31" }`. All three fields update. Fix: explicit allowlist of updatable fields (`{ name, email, avatar_url } = await req.json()`) or Zod schema with `.strict()` rejecting unknown fields.
Related
FAQ
Doesn't TypeScript catch this at compile time?
No — TypeScript types are erased at runtime. A request body typed as `UpdateUserDto` at compile time is just `any` at runtime; whatever fields the attacker submits get passed to the database. Type annotations are documentation, not validation. Use Zod / Valibot / similar for runtime enforcement.
How does this differ from BOLA?
BOLA is reading or writing the wrong USER's data (cross-user authorization bug). Mass assignment is reading or writing the wrong FIELDS on your own data (privilege-escalation-via-field-control). Both are common in AI-generated CRUD code.