T02 · Agent Memory Poisoning
- Location
scripts/mem0-add.js:26- Finding
Caller-Controlled User Identifiers Permit Cross-User Memory Poisoning, Disclosure, and Deletion
- Content
View full analysis
Vulnerability Details
File Location:
scripts/mem0-add.js:26-29, 45-49;scripts/mem0-search.js:23-35;scripts/mem0-list.js:13-21;scripts/mem0-delete.js:22-41
Vulnerability Type: Missing authorization and insecure object ownership enforcement
Risk Level: HighVulnerable Code
scripts/mem0-add.js:26-29, 45-49:javascript if (arg.startsWith("--messages=")) { try { messages = JSON.parse(arg.substring(11)); } catch (e) { console.error("Error parsing messages JSON:", e.message); process.exit(1); } } else if (arg.startsWith("--user=")) { userId = arg.split("=")[1]; } else if (!arg.startsWith("--")) { text = arg; } let result; if (messages) { result = await memory.add(messages, { userId }); } else { result = await memory.add(text, { userId }); }scripts/mem0-search.js:23-35:javascript for (const arg of args.slice(1)) { if (arg.startsWith("--limit=")) { limit = parseInt(arg.split("=")[1]); } else if (arg.startsWith("--user=")) { userId = arg.split("=")[1]; } } try { const memory = getMem0Instance(); const results = await memory.search(query, { userId, limit });scripts/mem0-list.js:13-21:javascript for (const arg of args) { if (arg.startsWith("--user=")) { userId = arg.split("=")[1]; } } try { const memory = getMem0Instance(); const response = await memory.getAll({ userId });scripts/mem0-delete.js:22-41:javascript for (const arg of args) { if (arg === "--all") { deleteAll = true; } else if (arg.startsWith("--user=")) { userId = arg.split("=")[1]; } else if (!arg.startsWith("--")) { memoryId = arg; } } try { const memory = getMem0Instance(); if (deleteAll) { await memory.deleteAll({ userId }); console.log(`✓ All memories deleted for user: ${userId}`); } else i ...[truncated 2794 chars]- Remediation
View remediation
Remediation Suggestions
- Remove the caller-controlled
--useroption from normal Agent-facing commands. - Derive the user identifier from authenticated, trusted session context.
- Enforce ownership checks inside the storage layer rather than relying only on CLI argument handling.
- Scope individual deletion by both memory ID and authenticated owner.
- Reject empty, malformed, unknown, or unauthorized user identifiers.
- Maintain physically or cryptographically separated stores for different users where possible.
- Require explicit confirmation or a separate privileged capability for bulk deletion.
- Treat retrieved memory as untrusted data and prevent it from overriding system or developer instructions.
- Record security audit events for memory creation, enumeration, and deletion without logging sensitive memory content.
- Add tests proving that one authenticated user cannot add, read, search, or delete another user's records.
- Remove the caller-controlled
