StudioCMS: IDOR in User Notification Preferences Allows Any Authenticated User to Modify Any User's Settings
Date: 2026-03
Affected: npm/studiocms
Attack vector: auth-bypass
Category: vulnerability-disclosure
Severity: Medium
CVE: CVE-2026-32104
CWE: CWE-639
CVSS: 5.4 (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:L)

## Summary The `updateUserNotifications` endpoint accepts a user ID from the request payload and uses it to update that user's notification preferences. It checks that the caller is logged in but never verifies that the caller owns the target account (`id !== userData.user.id`). Any authenticated visitor can modify notification preferences for any user, including disabling admin notifications to suppress detection of malicious activity. ## Details The vulnerable handler is in `packages/studiocms/frontend/pages/studiocms_api/_handlers/dashboard/users.ts:257-311`: ```typescript .handle( 'updateUserNotifications', Effect.fn(function* ({ payload: { id, notifications } }) { // ...demo mode checks... const [sdk, userData] = yield* Effect.all([SDKCore, CurrentUser]); // Line 274: Only checks login + visitor level — any authenticated user passes if (!userData.isLoggedIn || !userData.userPermissionLevel.isVisitor) { return yield* new DashboardAPIError({ error: 'Unauthorized' }); } // Line 280: Uses 'id' from payload — NOT userData.user.id const existingUser = yield* sdk.GET.users.byId(id); // Line 288: Updates target user using attacker-controlled 'id' const updatedData = yield* sdk.AUTH.user.update({ userId: id, // ← attacker controls this userData: { id, // ← attacker controls this name: existingUser.name,


Mitigations:

Architectural layers (MAESTRO):