From 7c49986a5646e892a115725abb43cf97b5d7c1d2 Mon Sep 17 00:00:00 2001 From: Fuwn Date: Mon, 1 Jun 2026 15:11:27 +0000 Subject: fix(security): authorize shadowHide target in badges endpoint (IDOR) PUT /api/badges?shadowHide= called setShadowHidden on an arbitrary user_id with no ownership/privilege check, so any logged-in user could flip shadow_hidden on another user's badges (e.g. un-hide moderator-hidden ones). The GraphQL path already guarded this; the REST twin didn't. Extract the owner-or-privileged check into a shared isOwnerOrPrivileged helper, use it in both the REST endpoint and the GraphQL resolver, and add a regression test. --- src/graphql/user/resolvers.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/graphql/user/resolvers.ts') diff --git a/src/graphql/user/resolvers.ts b/src/graphql/user/resolvers.ts index 905a2b4f..a90c6c4c 100644 --- a/src/graphql/user/resolvers.ts +++ b/src/graphql/user/resolvers.ts @@ -25,6 +25,7 @@ import { type UserPreferences, } from "$lib/Database/SB/User/preferences"; import { decodeAuthCookieOrNull } from "$lib/Effect/authCookie"; +import { isOwnerOrPrivileged } from "$lib/Utility/authorisation"; import privilegedUser from "$lib/Utility/privilegedUser"; import type { Badge, Resolvers as RootResolvers, WithIndex } from "../$types"; @@ -110,7 +111,7 @@ const ensureOwnerOrPrivileged = ( authorised: boolean, targetUserId: number, ) => { - if (!authorised && identity.id !== targetUserId) + if (!isOwnerOrPrivileged(identity.id, targetUserId, authorised)) throw new Error("Unauthorized"); }; -- cgit v1.2.3