Describe the bug
The memory REST API handlers in @voltagent/server-core perform object lookup by caller-supplied conversationId and optional query/body values, but they do not receive or enforce the authenticated principal from the server auth middleware.
As a result, an authenticated caller who knows or guesses another user's conversationId can read that conversation, list its messages, read conversation-scoped working memory, and delete the conversation. This is an object-level authorization issue / IDOR affecting the memory API surface.
Relevant code paths:
packages/server-core/src/handlers/memory.handlers.ts
handleGetMemoryConversation() fetches resolved.memory.getConversation(conversationId) and returns it without owner/resource authorization.
handleListMemoryConversationMessages() fetches the conversation, then falls back to conversation.userId when query.userId is omitted, which returns the victim's messages.
handleGetMemoryWorkingMemory() fetches by conversationId and falls back to conversation.userId.
handleDeleteMemoryConversation() deletes by conversationId only.
packages/server-hono/src/routes/memory.routes.ts, packages/server-elysia/src/routes/memory.routes.ts, and packages/serverless-hono/src/routes.ts pass query/body data into these handlers, but do not pass the authenticated principal for object-level authorization checks.
Steps To Reproduce
-
Use a VoltAgent app exposing the memory REST API with any memory adapter and authentication enabled.
-
Create a conversation as victim-user, for example conv-victim-001, and store at least one message or conversation-scoped working memory entry.
-
Authenticate as a different user, for example attacker-user.
-
Request the victim conversation by ID:
GET /api/memory/conversations/conv-victim-001
Authorization: Bearer <attacker-token>
-
Request the victim messages without providing userId:
GET /api/memory/conversations/conv-victim-001/messages
Authorization: Bearer <attacker-token>
-
Request victim working memory:
GET /api/memory/conversations/conv-victim-001/working-memory
Authorization: Bearer <attacker-token>
-
Optionally delete the victim conversation:
DELETE /api/memory/conversations/conv-victim-001
Authorization: Bearer <attacker-token>
-
Run the included safe local synthetic PoC:
The PoC does not access real services or data. It models the relevant handler behavior and demonstrates cross-user read and delete using synthetic records.
Expected behavior
Memory API handlers should bind every conversation/message/working-memory operation to the authenticated principal and the expected resource/agent scope. A caller authenticated as attacker-user should not be able to read, update, clone, search, or delete a conversation owned by victim-user unless an explicit authorization policy grants that access.
For example:
- GET by
conversationId should verify conversation.userId === authenticatedUser.id or an equivalent policy decision before returning the object.
- Message listing should not fall back to
conversation.userId for a different authenticated caller.
- Delete/update/clone operations should enforce the same owner/resource policy before mutating state.
- Query/body
userId must not be trusted as an authorization source.
Packages
@voltagent/server-core up to 2.1.17
@voltagent/server-hono up to 2.0.13
@voltagent/server-elysia up to 2.0.8
@voltagent/serverless-hono up to the version in the current repository
- Memory adapters used behind the API, including
@voltagent/core, @voltagent/libsql, @voltagent/postgres, @voltagent/supabase, and @voltagent/voltagent-memory
Additional Context
This is security-sensitive. The repository's SECURITY.md requests reporting suspected vulnerabilities via GitHub Security Advisories rather than public issues. This file is formatted according to .github/ISSUE_TEMPLATE/bug_report.yml as requested, but it should be submitted privately unless the maintainers approve public disclosure.
Tested against local commit 39978061763e621c9dea6fd7796488bd2089279b and rechecked against origin/main commit 5be7626632cc7fb8798ec0a06774af6560184e52; the relevant memory handler behavior is still present on origin/main.
Suggested remediation:
- Pass authenticated user context from server middleware into memory route handlers for all methods, including GET/DELETE.
- Enforce object-level authorization in
server-core before returning or mutating conversations, messages, working memory, vector search results, or cloned conversations.
- Treat
userId, resourceId, and agentId query/body values as selectors only after they are validated against the authenticated principal and authorization policy.
- Add regression tests for cross-user read, update, clone, delete, and search attempts.
Describe the bug
The memory REST API handlers in
@voltagent/server-coreperform object lookup by caller-suppliedconversationIdand optional query/body values, but they do not receive or enforce the authenticated principal from the server auth middleware.As a result, an authenticated caller who knows or guesses another user's
conversationIdcan read that conversation, list its messages, read conversation-scoped working memory, and delete the conversation. This is an object-level authorization issue / IDOR affecting the memory API surface.Relevant code paths:
packages/server-core/src/handlers/memory.handlers.tshandleGetMemoryConversation()fetchesresolved.memory.getConversation(conversationId)and returns it without owner/resource authorization.handleListMemoryConversationMessages()fetches the conversation, then falls back toconversation.userIdwhenquery.userIdis omitted, which returns the victim's messages.handleGetMemoryWorkingMemory()fetches byconversationIdand falls back toconversation.userId.handleDeleteMemoryConversation()deletes byconversationIdonly.packages/server-hono/src/routes/memory.routes.ts,packages/server-elysia/src/routes/memory.routes.ts, andpackages/serverless-hono/src/routes.tspass query/body data into these handlers, but do not pass the authenticated principal for object-level authorization checks.Steps To Reproduce
Use a VoltAgent app exposing the memory REST API with any memory adapter and authentication enabled.
Create a conversation as
victim-user, for exampleconv-victim-001, and store at least one message or conversation-scoped working memory entry.Authenticate as a different user, for example
attacker-user.Request the victim conversation by ID:
Request the victim messages without providing
userId:Request victim working memory:
Optionally delete the victim conversation:
Run the included safe local synthetic PoC:
The PoC does not access real services or data. It models the relevant handler behavior and demonstrates cross-user read and delete using synthetic records.
Expected behavior
Memory API handlers should bind every conversation/message/working-memory operation to the authenticated principal and the expected resource/agent scope. A caller authenticated as
attacker-usershould not be able to read, update, clone, search, or delete a conversation owned byvictim-userunless an explicit authorization policy grants that access.For example:
conversationIdshould verifyconversation.userId === authenticatedUser.idor an equivalent policy decision before returning the object.conversation.userIdfor a different authenticated caller.userIdmust not be trusted as an authorization source.Packages
@voltagent/server-coreup to 2.1.17@voltagent/server-honoup to 2.0.13@voltagent/server-elysiaup to 2.0.8@voltagent/serverless-honoup to the version in the current repository@voltagent/core,@voltagent/libsql,@voltagent/postgres,@voltagent/supabase, and@voltagent/voltagent-memoryAdditional Context
This is security-sensitive. The repository's
SECURITY.mdrequests reporting suspected vulnerabilities via GitHub Security Advisories rather than public issues. This file is formatted according to.github/ISSUE_TEMPLATE/bug_report.ymlas requested, but it should be submitted privately unless the maintainers approve public disclosure.Tested against local commit
39978061763e621c9dea6fd7796488bd2089279band rechecked againstorigin/maincommit5be7626632cc7fb8798ec0a06774af6560184e52; the relevant memory handler behavior is still present onorigin/main.Suggested remediation:
server-corebefore returning or mutating conversations, messages, working memory, vector search results, or cloned conversations.userId,resourceId, andagentIdquery/body values as selectors only after they are validated against the authenticated principal and authorization policy.