- Location
- index.ts:659
- Finding
- Memory Tools Lack User-Scope and Ownership Authorization<![CDATA[
## Vulnerability Details
**File Location**: `index.ts:659-722`, `index.ts:782-819`, `index.ts:867-879`, `index.ts:906-956`, `index.ts:1011-1046`
**Vulnerability Type**: Cross-user memory access, modification, and deletion
**Risk Level**: High
### Vulnerable Code
```ts
// index.ts:672-722
userId: Type.Optional(
Type.String({
description:
"User ID to scope search (default: configured userId)",
}),
),
...
const { query, limit, userId, scope = "all" } = params as {
query: string;
limit?: number;
userId?: string;
scope?: "session" | "long-term" | "all";
};
...
results = await provider.search(
query,
buildSearchOptions(userId, limit),
);
```
```ts
// index.ts:790-819
userId: Type.Optional(
Type.String({
description: "User ID to scope this memory",
}),
),
...
const { text, userId, longTerm = true } = params as {
text: string;
userId?: string;
metadata?: Record<string, unknown>;
longTerm?: boolean;
};
...
const result = await provider.add(
[{ role: "user", content: text }],
buildAddOptions(userId, runId),
);
```
```ts
// index.ts:869-879
name: "memory_get",
label: "Memory Get",
description: "Retrieve a specific memory by its ID from Mem0.",
parameters: Type.Object({
memoryId: Type.String({ description: "The memory ID to retrieve" }),
}),
async execute(_toolCallId, params) {
const { memoryId } = params as { memoryId: string };
try {
const memory = await provider.get(memoryId);
```
```ts
// index.ts:913-956
userId: Type.Optional(
Type.String({
description:
"User ID to list memories for (default: configured userId)",
}),
),
...
const { userId, scope = "all" } = params as {
userId?: string;
scope?: "session" | "long-term" | "all";
};
try {
let memories: MemoryItem[] = [];
const uid = userId || cfg.userId;
...
memories = await provider.getAll({ user_id: uid });
```
```ts
// index.ts:1034-1040
if (memoryId) {
await provider.delete(memoryId);
return {
content: [
{ ty
...[truncated 2314 chars]
- Remediation
- <![CDATA[
## Remediation Suggestions
1. Remove `userId` from all Agent-callable tool schemas.
2. Derive the user identifier from authenticated request or session context.
3. Pass session identity through each tool invocation rather than storing it in a shared mutable variable.
4. Before `get` or `delete`, fetch metadata using a privileged internal path and verify that the record belongs to the current authenticated user.
5. Reject operations where the requested record has no verifiable owner.
6. Use distinct backend credentials or enforced tenant scopes where possible.
7. Separate administrative cross-user tools from normal Agent tools and require explicit administrator authorization.
8. Require user confirmation for destructive deletion.
9. Record security audit logs for read, write, and delete operations without logging memory contents or credentials.
10. Add multi-user tests proving that one session cannot list, search, retrieve, modify, or delete another user's records.
]]>