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 diff | Why it matters |
|---|---|
| Create or update called with the whole request body | Any field on the model becomes writable |
| A model with owner, role or status fields next to user editable ones | One binding exposes both |
| A block list of forbidden fields | A new sensitive field stays writable |
| Nested objects bound automatically | Inner 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
- Find every place request data is passed into a create or update call.
- List the fields on the target model. Mark the ones a normal user should never set.
- Check that the code picks fields by name, or uses a DTO with only safe fields.
- 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.
- 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.