Mass assignment happens when you take an entire request body and write it onto a database record. An attacker simply adds extra fields, like role or isAdmin, and they get saved along with the legitimate ones. The fix is to pick out only the specific fields you intend to accept, and ignore everything else.
Why it's a problem
Your form sends name and email, so the code looks fine. But nothing stops a client from also sending isAdmin: true or accountBalance: 999999, and if you spread the whole body onto the record, those are written too. This is a common way ordinary users escalate to admin or tamper with fields the UI never exposed.
The pattern
// writes every field the client sends const user = await User.create(req.body); // or: Object.assign(user, req.body)
The fix
// accept only the fields you allow
const { name, email } = req.body;
const user = await User.create({ name, email });Why AI tools write this
Passing req.body straight into create or update is the most concise way to save a form, and it works perfectly when the client sends only the expected fields. The escalation path opens the moment an attacker adds an extra field, which normal use never does.
The quick fix
- Explicitly pick the fields you accept, never spread the whole request body.
- Keep sensitive fields (roles, flags, balances) out of any client-writable path.
- Use a schema or serializer that whitelists inputs on create and update.