Safeguard
Security Guides•

What is mass assignment, and how do you catch it in code review?

Mass assignment lets a request set fields the form never showed. Catch it by looking for model binding without a field allow list, and ask for DTOs.

Safeguard Security Team
4 min read

Mass assignment happens when a framework binds request parameters straight onto an object, so a caller can set fields the developer never meant to expose, such as an admin flag. In review, look for binding of raw request data to a model, and ask for a data transfer object or a field allow list.

What the standard says

The OWASP Mass Assignment Cheat Sheet, which maps to CWE-915, gives a simple example: a form binds to a User class, and adding isAdmin=true to the POST request sets a flag the form never showed. It names the sensitive fields to watch: roles and admin flags, account owner or ownership references, and credentials and keys. It also mentions an incident in 2012 where a user could upload a public key to any organization on GitHub.

Attackers can guess or discover field names without source code, and nested objects plus constructor or setter binding expose fields too.

Patterns to flag

In the diffWhy it matters
Create or update called with the whole request bodyAny field on the model becomes writable
A model with owner, role or status fields next to user editable onesOne binding exposes both
A block list of forbidden fieldsA new sensitive field stays writable
Nested objects bound automaticallyInner fields are exposed too

Defenses to ask for

OWASP lists three. DTOs: bind input to dedicated objects holding only user editable fields. Allow listing: explicitly permit bindable fields, with examples such as Spring's setAllowedFields and a pick helper in Mongoose code. Block listing: possible, but fragile, because a new or overlooked field stays bindable, which is why CWE-915 favors allow lists.

// risky: every field in the body reaches the database
await User.update(req.params.id, req.body);

// safer: only named fields are accepted
const { displayName, timezone } = req.body;
await User.update(req.params.id, { displayName, timezone });

Steps for a review

  1. Find every place request data is passed into a create or update call.
  2. List the fields on the target model. Mark the ones a normal user should never set.
  3. Check that the code picks fields by name, or uses a DTO with only safe fields.
  4. When a new column is added to a model in the same pull request, re-check every binding that touches that model. This is where block lists fail.
  5. Ask for a test that sends an extra field and asserts it is ignored.

It does not replace authorization

The cheat sheet states a limit: DTOs and allow lists control which fields are writable, but they do not replace authorization checks on the object and the operation. A user must still be allowed to update that record at all. Review both questions, which fields and which user.

Try it yourself

Open the API scan in the demo and look for findings about properties that a client can set. Compare what the API accepts with what the documentation shows.

Click through it at your own pace, or open it full screen.

Where Safeguard fits

Safeguard scans dependencies and builds SBOMs, including the ORM and framework versions you rely on. Try the free scan at gold.safeguard.sh/scan.

Quick check

Is a block list of sensitive fields enough?

No. A new or overlooked field stays bindable, so OWASP favors allow lists.

Does a DTO replace an authorization check?

No. It limits which fields are writable. You still need to check that the user may change the object.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.