Skip to content

security: API-key auth synthesizes userId:0 + ADMIN role (privilege confusion) #2162

@andrew-bierman

Description

@andrew-bierman

Discovered during review of #2083.

File: packages/api/src/middleware/auth.ts:53-57

When an incoming request carries X-API-Key matching PACKRAT_API_KEY, the authPlugin injects { userId: 0, role: 'ADMIN' } into the request context.

Impact: any route protected by isAuthenticated: true (not just isAdmin) now runs with full admin posture for the API-key path, and with a forged userId: 0. Any handler that scopes its query by eq(x.userId, user.userId) will touch rows owned by user 0 (leak on reads, overwrite on writes) if such rows exist, or silently succeed as a no-op if they don't.

Fix options:

  • Reject the API-key path for user-scoped routes (return 401/403 unless the route is explicitly marked service-account-safe)
  • Require a real service-account userId associated with the API key; do not synthesize
  • At minimum, fail closed on user-scoped handlers (detect synthesized identity and 401)

Related: #2083 (introduced by the Hono → Elysia rewrite of this middleware)

Test requirement (for the restored auth.test.ts): API-key path must not satisfy user-scoped handlers.

Metadata

Metadata

Assignees

No one assigned

    Labels

    apibugSomething isn't workingenhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions