mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 04:50:59 +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({
|
||||
where: { id },
|
||||
select: { id: true, username: true },
|
||||
|
||||
Reference in new issue
Block a user