No Privilege Escalation via Parameter Tampering
Why it matters
Spreading req.body directly into a db.user.update({ data: body }) call is mass assignment (CWE-915): any field the attacker includes in the request body will be written to the database. For user records, this means { "role": "admin" } is a single-request privilege escalation. CWE-285 (Improper Authorization) and OWASP A01 (Broken Access Control) cover this exact pattern. NIST 800-53 AC-6 (Least Privilege) requires that users cannot update fields beyond their entitlement — without an explicit allowlist, every field in the database schema is implicitly writable by authenticated users.
Severity rationale
High because an authenticated user can escalate to admin privileges with a single crafted PATCH request, requiring no special knowledge beyond knowing which fields exist in the user model.
Remediation
Parse update requests through a Zod schema that explicitly includes only safe profile fields. Zod silently strips any extra fields — including role, permissions, or isAdmin — before the data reaches the database.
// lib/schemas/user.ts
export const ProfileUpdateSchema = z.object({
displayName: z.string().min(1).max(50).optional(),
bio: z.string().max(500).optional(),
avatarUrl: z.string().url().optional(),
// 'role', 'permissions', 'isAdmin' are intentionally absent
});
// app/api/users/[id]/route.ts
export async function PATCH(req: NextRequest, { params }) {
const session = await auth();
if (!session || session.user.id !== params.id) {
return NextResponse.json({ error: 'Forbidden' }, { status: 403 });
}
const data = ProfileUpdateSchema.parse(await req.json()); // Strips sensitive fields
await db.user.update({ where: { id: params.id }, data });
}
Add .strict() to the schema to reject (rather than silently strip) requests that include unexpected fields — this surfaces integration bugs faster.
DetectionPro
The detection method for this pattern is part of AuditBuffet Pro.
The full method (what to look for, pass and fail conditions, and how results get reported) ships inside the Authorization Audit. The pattern definition, severity rationale, and remediation remain openly licensed under CC-BY-4.0.
External references
- cwe · CWE-915 — Improperly Controlled Modification of Dynamically-Determined Object Attributes
- cwe · CWE-285 — Improper Authorization
- owasp:2021 · A01
- nist:rev5 · AC-6
- soc2:2017 · CC6.3 — Role-based access and least privilege
Taxons
History
- 2026-04-18·v1.0.0·Initial import from saas-authorization·automated
- 2026-07-06·v1.0.1·Add SOC 2 TSC mapping (CC6.3) from the verified compliance crosswalk register (docs/compliance/).·by soc2-mapping-enrichment-ship-2