T05 · Unauthorized Access and Privilege Escalation
Error
- Location
- server.ts:22
- Finding
- Memory Tools Lack Authorization and Tenant Isolation<![CDATA[ ## Vulnerability Details **File Location**: `server.ts:22-102`; related schema at `supabase-schema.sql:66-88` **Vulnerability Type**: Missing authorization and object-level access control **Risk Level**: High ### Vulnerable Code ```typescript server.tool( 'recall_memories', 'Search Clude\'s memory system. Returns scored memories ranked by relevance, importance, recency, and decay.', { query: z.string().optional().describe('Text to search against memory summaries'), tags: z.array(z.string()).optional().describe('Tags to filter by (matches any)'), related_user: z.string().optional().describe('Filter by related user/agent ID'), memory_types: z.array(z.enum(['episodic', 'semantic', 'procedural', 'self_model'])).optional() .describe('Filter by memory type'), limit: z.number().min(1).max(20).optional().describe('Max results (default 5)'), min_importance: z.number().min(0).max(1).optional().describe('Minimum importance threshold'), }, async (args) => { const memories = await recallMemories({ query: args.query, tags: args.tags, relatedUser: args.related_user, memoryTypes: args.memory_types as MemoryType[] | undefined, limit: args.limit, minImportance: args.min_importance, }); return { content: [{ type: 'text' as const, text: JSON.stringify({ count: memories.length, memories: memories.map(m => ({ id: m.id, type: m.memory_type, summary: m.summary, content: m.content, tags: m.tags, importance: m.importance, decay_factor: m.decay_factor, created_at: m.created_at, access_count: m.access_count, })), }, null, 2), }], }; } ); ``` ```typescript server.tool( 'store_memory', 'Store a new memory in Clude\'s cognitive system. Memories persist across conversations and decay over time if not accessed.', ...[truncated 4406 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Require authenticated MCP sessions before exposing any memory operation. 2. Derive the user and tenant identity from trusted session credentials; never accept ownership identity directly from tool arguments. 3. Modify retrieval queries so every operation contains a mandatory server-derived tenant and owner predicate. 4. On insertion, overwrite any caller-provided ownership field with the authenticated identity. 5. Enable row-level security on `memories`, `memory_fragments`, `memory_links`, and related tables. 6. Add restrictive `SELECT`, `INSERT`, `UPDATE`, and `DELETE` policies that validate ownership or explicit sharing. 7. Do not use the Supabase service-role key in a caller-facing process. Use a least-privileged role and isolate administrative operations in a separate trusted service. 8. Return only the fields required by the caller, and avoid returning full memory content when summaries are sufficient. 9. Add authorization tests covering omitted identifiers, forged identifiers, cross-tenant searches, and unauthorized writes. ]]>
