What is the security flaw in this user-update endpoint, and how would you fix it?
Vulnerable code
javascript
app.patch('/api/users/me', requireAuth, async (req, res) => {
// BUG: passes entire request body to update — mass assignment
const user = await db.users.update({
where: { id: req.user.id },
data: req.body,
});
res.json(user);
});Mass Assignment
Fixed
javascript
app.patch('/api/users/me', requireAuth, async (req, res) => {
// Allow-list only the fields the user may change
const { name, bio, avatarUrl } = req.body;
const user = await db.users.update({
where: { id: req.user.id },
data: { name, bio, avatarUrl },
});
res.json(user);
});This is a mass assignment (also called auto-binding or object injection) vulnerability. The endpoint passes the entire raw request body directly to user.update(). An attacker can include any field the model supports — including ones not shown in the UI, such as isAdmin: true, role: 'admin', email: 'attacker@evil.com', or balance: 99999. The ORM blindly applies every key in the object to the DB record.
The fix is to explicitly allow-list the fields a user is permitted to update. Use destructuring or a pick utility to extract only the intended fields (here: name, bio, avatarUrl) and pass only those to the ORM. Never spread or pass raw request body objects directly to data-layer methods.