mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-15 06:52:04 +00:00
fix(security): block force-logout from targeting the admin's own session
The UI already disabled the per-row force-logout button for the active admin (user-management-section.tsx:295), but the route handler had no matching server-side check. A direct curl/DevTools call (or a compromised admin session) could revoke the caller's own sessions and bounce them to /auth/login mid-action. Mirrors the UI gate with a 422 + an `admin.user.force-logout.denied` audit entry tagged `reason: self_target`. Admin-on-admin force-logout remains permitted (today's intentional behaviour). Closes H1 from .planning/phase-6-code-review-findings.md. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
88c8db1abc
commit
b3f282adab
1 file changed
+13
@@ -31,6 +31,19 @@ export const POST = apiHandler(
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Mirror the UI gate at user-management-section.tsx:295 — admins
|
||||||
|
// mid-action shouldn't bounce themselves to /auth/login. A
|
||||||
|
// determined admin can revoke another admin (intentional today),
|
||||||
|
// but the self-target case is always a footgun.
|
||||||
|
if (admin.id === id) {
|
||||||
|
await auditLog("admin.user.force-logout.denied", {
|
||||||
|
userId: admin.id,
|
||||||
|
ipAddress: getClientIp(request),
|
||||||
|
details: { targetUserId: id, reason: "self_target" },
|
||||||
|
});
|
||||||
|
return apiError("Cannot force-logout your own session", 422);
|
||||||
|
}
|
||||||
|
|
||||||
const target = await prisma.user.findUnique({
|
const target = await prisma.user.findUnique({
|
||||||
where: { id },
|
where: { id },
|
||||||
select: { id: true, username: true },
|
select: { id: true, username: true },
|
||||||
|
|||||||
Reference in new issue
Block a user