Role Assignment Restricted
Why it matters
A user update endpoint that accepts a role or isAdmin field in the request body without admin verification is a mass assignment vulnerability (CWE-915) enabling privilege escalation (CWE-285). Any authenticated user who POSTs { "role": "admin" } to their own profile endpoint will elevate their privileges if the backend spreads the request body directly into a database update. OWASP A01 (Broken Access Control) flags this pattern explicitly. NIST 800-53 AC-6 (Least Privilege) requires that users cannot grant themselves permissions beyond what they were assigned.
Severity rationale
Low because the attacker must be authenticated and must know which fields to tamper with, but self-promotion to admin via a single request is a complete authorization bypass.
Remediation
Define a profile update Zod schema that does not include role, permissions, or any privilege field. Handle role changes through a separate admin-only endpoint.
// lib/schemas/user.ts
export const UserProfileUpdateSchema = z.object({
displayName: z.string().optional(),
bio: z.string().optional(),
// 'role' is intentionally absent
});
// app/api/admin/users/[id]/role/route.ts — separate admin-only endpoint
export async function PATCH(req: NextRequest, { params }) {
const session = await auth();
if (session?.user.role !== 'admin') return NextResponse.json({}, { status: 403 });
const { role } = await req.json();
await db.user.update({ where: { id: params.id }, data: { role } });
}
UserProfileUpdateSchema.parse() silently drops any fields not in the schema, so attackers cannot inject privilege fields even if they try.
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-285 — Improper Authorization
- cwe · CWE-915 — Improperly Controlled Modification of Dynamically-Determined Object Attributes
- owasp:2021 · A01
- nist:rev5 · AC-6 — Least Privilege
- 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