Mass assignment

Backend security Junior Python 3.13+ PostgreSQL 17+ Reviewed By Best Latest Apps

Spot the bug

Which line lets a user make themselves an admin?

  1. from dataclasses import dataclass
  2. ​
  3. ​
  4. @dataclass
  5. class User:
  6. name: str
  7. email: str
  8. is_admin: bool = False
  9. ​
  10. ​
  11. def update_profile(user: User, body: dict[str, str | bool]) -> User:
  12. for key, value in body.items():
  13. setattr(user, key, value)
  14. return user
Hint 1 of 1

Which keys can the client send?

Choose an answer, then open Show answer below to check it.

Show answer
  • Answer: line 13 setattr(user, key, value)

Line 13 copies every key from the body, including is_admin. Copy only allow-listed fields like name and email.

30-second answer

It happens when an endpoint copies every field of the request body onto a model, so a user can send "is_admin": true or "balance": 1000000 and the server saves it. It's in the OWASP API Top 10 as broken object property level authorization. Prevent it with explicit input schemas per endpoint that list only the fields a caller may set, and separate response schemas so internal fields aren't exposed either.

Practise saying it · 25 s. No recording, just a timer

Explain mass assignment.

Say your answer out loud, then check which of these points you covered:

  • Body copied onto model
  • OWASP API property-level
  • Allow-list schemas
  • Separate response schemas

Deep dive

Pydantic models with extra='forbid' reject unknown fields.

Different roles may need different input schemas.

The response side matters too: don't serialise whole ORM objects.

Tests should try setting protected fields and expect rejection.

Common mistakes

  • user.update(**request.json).
  • Deny-lists of forbidden fields that miss new columns.
  • Returning the whole database row.

Senior take & follow-ups

Define it, then per-endpoint allow-list schemas for input and output.

Follow-up questions

Think of your answer first, then open the hint.

  1. Allow-list or deny-list?

    Show hint

    Allow-list: new columns stay protected by default.

  2. What's the response-side twin?

    Show hint

    Excessive data exposure: returning fields the client shouldn't see.

Suggest a fix if something here is wrong or out of date.