Skip to content

Security: Multiple IDOR in Shortcut Analytics and User Settings (CWE-639) #500

@lighthousekeeper1212

Description

@lighthousekeeper1212

Summary

Multiple Insecure Direct Object Reference (IDOR) vulnerabilities exist in the Shortcut and User Setting gRPC services, allowing any authenticated user to access or leak data belonging to other users.

CWE-639: Authorization Bypass Through User-Controlled Key

Affected Endpoints

1. GetShortcutAnalytics — Missing Ownership Check

GetShortcutAnalytics() in server/route/api/v1/shortcut_service.go (lines 250-310) fetches a shortcut by ID and returns full analytics without verifying the caller owns or has access to the shortcut.

Compare with DeleteShortcut() (line 237) which correctly checks shortcut.CreatorId != user.ID before proceeding. GetShortcutAnalytics() has no equivalent ownership check.

2. GetUserSetting — Missing Caller Verification

GetUserSetting() in server/route/api/v1/user_setting_service.go (lines 15-21) passes request.Id directly to getUserSetting() without verifying that the authenticated caller's user ID matches request.Id. Any authenticated user can read any other user's settings by supplying an arbitrary user ID.

3. UpdateUserSetting — Response Information Leak

UpdateUserSetting() in the same file (line 51) correctly performs the actual update using user.ID from the authenticated context. However, the response is built by calling getUserSetting(ctx, s.Store, request.Id) where request.Id is caller-controlled rather than the authenticated user's ID. This leaks another user's settings in the response.

4. ListShortcuts — Missing Visibility/Ownership Filter

ListShortcuts() (lines 24-43) returns all shortcuts without filtering by visibility or ownership. The FindShortcut{} query struct has no user or visibility filter applied, exposing all users' shortcuts (including private ones) to any authenticated caller.

Impact

  • Confidentiality: Any authenticated user can read other users' shortcut analytics, user settings, and private shortcuts.
  • Severity: High

Recommended Fix

  1. GetShortcutAnalytics: Add an ownership check (shortcut.CreatorId != user.ID) matching the pattern already used in DeleteShortcut().
  2. GetUserSetting: Verify request.Id == user.ID, or ignore request.Id and always use the authenticated user's ID from context.
  3. UpdateUserSetting: Change the response call to use getUserSetting(ctx, s.Store, user.ID) instead of request.Id.
  4. ListShortcuts: Add a CreatorId or visibility filter to FindShortcut{} so users only see their own shortcuts and public shortcuts.

Thank you for your work on Slash. Happy to answer any questions about these findings.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions