fix(server): scope memory conversation access to the authenticated user

WX
1d ago
+267-6

Description

The memory REST handlers (handleGetMemoryConversation, handleListMemoryConversationMessages, handleUpdateMemoryConversation, handleDeleteMemoryConversation) fetched and operated on conversations by id without verifying that the requesting user is the conversation owner — the identity the auth middleware injects into the request context was never read. As reported in #1371, any authenticated user could read another user's conversation messages, tamper with its title/metadata and delete it, and GET /api/memory/conversations?userId=<victim> listed the victim's conversations to any authenticated caller.

Changes:

  • server-core handlers accept an optional authenticatedUserId; when it is present, get / messages / update / delete verify it against the conversation's stored userId and mask mismatches as 404 (hiding the conversation's existence), and the conversation list scopes its query with the token's identity instead of a client-supplied userId
  • server-hono memory routes pass the verified user's identity (user.id, falling back to JWT sub) from the middleware's authenticatedUser context into those handlers
  • when auth middleware is not configured (authenticatedUser undefined, the default deployment), the checks degenerate to the historical behavior — nothing breaks for unauthenticated local use
  • OwnershipConflict mismatches return 404 rather than 403 so an attacker cannot distinguish "not mine" from "not found"

Evidence

  • new packages/server-core/src/handlers/memory.handlers.spec.ts: 10 cases covering owner-pass 200, cross-user 404 on read/update/delete, the list scoping override, and the no-auth passthrough for every path
  • vitest run packages/server-core — 135 passed (12 files); vitest run packages/server-hono — 78 passed (5 files)
  • changeset included for @voltagent/server-core + @voltagent/server-hono

Fixes #1371


Summary by cubic

Fixes an authorization vulnerability in the memory REST handlers where any authenticated user could read, modify, or delete another user's memory conversations, and could list another user's conversations by passing their userId to GET /api/memory/conversations.

  • Conversation get, messages, update, and delete now verify the authenticated user's identity against the conversation's stored userId, masking mismatches as 404 so the conversation's existence stays hidden.
  • The conversation list scopes queries to the authenticated user's identity instead of a client-supplied userId.
  • Unauthenticated deployments (no auth middleware configured) keep the historical behavior.
  • Adds tests covering owner access, cross-user denial, and the no-auth passthrough for every affected path, plus a changeset for @voltagent/server-core and @voltagent/server-hono.

Fixes #1371.

Summary by CodeRabbit

  • Bug Fixes
    • Authenticated users can access, update, and delete only their own memory conversations. Attempts to access another user’s conversation return a not-found response.
    • Conversation and message listings use the authenticated identity when it conflicts with a client-supplied user ID.
    • Unauthenticated access retains its existing behavior.