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/lib/Utility/authorisation.ts | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 src/lib/Utility/authorisation.ts (limited to 'src/lib/Utility/authorisation.ts') diff --git a/src/lib/Utility/authorisation.ts b/src/lib/Utility/authorisation.ts new file mode 100644 index 00000000..c6b64414 --- /dev/null +++ b/src/lib/Utility/authorisation.ts @@ -0,0 +1,9 @@ +/** + * Whether a caller may act on resources belonging to `targetUserId`: either the + * caller owns them, or the caller is a privileged (allow-listed) user. + */ +export const isOwnerOrPrivileged = ( + callerUserId: number, + targetUserId: number, + privileged: boolean, +) => privileged || callerUserId === targetUserId; -- cgit v1.2.3