The risky pattern
await db.user.update({ where: { id }, data: req.body });Allow-list with a schema
const schema = z.object({ name: z.string().max(80), bio: z.string().max(500) });
const data = schema.parse(req.body);
await db.user.update({ where: { id: session.user.id }, data });Test it on your own app
- Take a profile update request and add fields such as role, isAdmin, price or userId.
- The server should ignore them or reject the request.
- Repeat for signup, checkout and any create or update route.
Database-level backstops
Use column permissions or row-level rules so that even a buggy route cannot write to sensitive columns.
Frequently asked questions
Does client-side validation prevent this?
No. Attackers send requests directly. Validate on the server.