Back to skill

Security audit

Clude Memory MCP

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed memory MCP server, but it asks for highly privileged database access and exposes persistent full-memory storage and retrieval without clear user or tenant controls.

Install only in a tightly scoped personal or test environment unless the publisher adds least-privilege Supabase credentials, authentication and tenant isolation, enforced input limits, retention and deletion controls, and a pinned reviewed package version. Do not store secrets, regulated personal data, or cross-user memories in it as currently documented.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
Findings (3)

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. ]]>

T08 · Insecure Dependencies

Warning
Location
SKILL.md:48
Finding
Setup Installs an Unpinned and Unaudited External Package<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:48-50` **Vulnerability Type**: Unpinned third-party dependency and mutable supply-chain source **Risk Level**: Medium ### Vulnerable Code ```markdown ## Setup ```bash npm install clude-bot ``` ``` ### Technical Analysis The setup instructions install `clude-bot` without an exact version, lockfile, registry integrity value, or verified source reference. The resolved package can therefore change between installations even though the reviewed Skill files remain unchanged. The supplied `server.ts` also imports several modules that are absent from the audited artifact: ```typescript import { config } from '../config'; import { recallMemories, storeMemory, getMemoryStats, type MemoryType } from '../core/memory'; import { getCurrentMood, getPriceState } from '../core/price-oracle'; import { getMoodModifier } from '../character/mood-modifiers'; import { generateResponse } from '../core/claude-client'; ``` As a result, significant runtime behavior cannot be mapped to reviewed source. If the external package supplies the missing implementation, installation and execution introduce code that is outside the audit boundary. npm packages may also execute lifecycle scripts during installation unless that behavior is explicitly disabled. ### Attack Path 1. A user follows the documented setup command. 2. npm resolves the current registry version of `clude-bot`, rather than a fixed reviewed release. 3. A compromised publisher account, malicious new release, registry substitution, or package takeover causes different code to be downloaded. 4. npm executes permitted package lifecycle scripts or the host later imports and runs package code. 5. The package executes with the privileges of the host process. 6. The process is expected to have access to `SUPABASE_URL` and `SUPABASE_SERVICE_KEY`, so malicious dependency code could access those environment variables and associated data. ### Impact Assessment Exploi ...[truncated 500 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin the dependency to an exact reviewed version, without a range specifier. 2. Include a committed lockfile containing registry URLs and integrity hashes. 3. Install through a reproducible command such as `npm ci` rather than resolving current versions dynamically. 4. Review the package publisher, source repository, release provenance, dependency tree, and lifecycle scripts. 5. Disable lifecycle scripts with `--ignore-scripts` when they are not required. 6. Use npm provenance or equivalent signed build metadata where available. 7. Include all runtime source required by the Skill in the audited artifact, or provide immutable references for every external component. 8. Run third-party code in a sandbox with minimal filesystem, network, and environment-variable access. 9. Avoid exposing a Supabase service-role key to dependency code; use narrowly scoped credentials and rotate them if dependency integrity is uncertain. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
server.ts:72
Finding
Documented Memory Size Limits Are Not Enforced<![CDATA[ ## Vulnerability Details **File Location**: `server.ts:72-82` **Vulnerability Type**: Missing input-size validation and resource-consumption controls **Risk Level**: Medium ### Vulnerable Code ```typescript { type: z.enum(['episodic', 'semantic', 'procedural', 'self_model']) .describe('Memory type: episodic (events), semantic (knowledge), procedural (behaviors), self_model (self-awareness)'), content: z.string().describe('Full memory content (max 5000 chars)'), summary: z.string().describe('Short summary for recall matching (max 500 chars)'), tags: z.array(z.string()).optional().describe('Tags for filtering'), importance: z.number().min(0).max(1).optional().describe('Importance score 0-1 (default 0.5)'), emotional_valence: z.number().min(-1).max(1).optional().describe('Emotional tone: -1 (negative) to 1 (positive)'), source: z.string().describe('Where this memory came from (e.g. "mcp:agent-name")'), related_user: z.string().optional().describe('Associated user or agent ID'), } ``` ### Technical Analysis The descriptions state that `content` is limited to 5,000 characters and `summary` to 500 characters, but the Zod schemas only use `z.string()`. Descriptive text does not enforce validation, so arbitrarily large strings are accepted. The `tags` array also has no maximum item count, and its individual strings have no length restrictions. `source` and `related_user` are similarly unbounded. Accepted values are passed into `storeMemory`, where they may trigger database writes, embedding generation, fragment decomposition, or on-chain commitment described by the project documentation. The absent implementation prevents precise measurement of downstream amplification, but the exposed handler itself demonstrably lacks the limits it claims to enforce. ### Attack Path 1. An attacker invokes `store_memory`. 2. The request includes an extremely large `content` or `summary`, a very large tag array, or oversized individual metadata field ...[truncated 719 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Enforce limits in the executable schema rather than only documenting them: ```typescript { type: z.enum(['episodic', 'semantic', 'procedural', 'self_model']), content: z.string().min(1).max(5000), summary: z.string().min(1).max(500), tags: z.array(z.string().min(1).max(64)).max(20).optional(), importance: z.number().min(0).max(1).optional(), emotional_valence: z.number().min(-1).max(1).optional(), source: z.string().min(1).max(128), related_user: z.string().min(1).max(128).optional(), } ``` Additionally: 1. Configure a maximum MCP message size at the transport or host boundary. 2. Apply per-caller request-rate limits and storage quotas. 3. Set timeouts and cost limits for embedding, Claude, Solana, and database operations. 4. Reject oversized requests before invoking downstream APIs. 5. Add database constraints where practical to provide defense in depth. 6. Monitor per-user storage growth, processing latency, and external API consumption. 7. Test boundary values and repeated oversized requests to confirm that rejection occurs before expensive processing. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (8)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill description and documented behavior do not cleanly match: it presents itself as a memory-focused MCP server but also exposes unrelated market-mood retrieval and external Claude-powered chat features, while advertised capabilities like dreaming, Solana commitment, and association graphs are not evidenced here. This kind of overclaiming and scope drift is dangerous because users and downstream agents may grant trust, permissions, or sensitive data based on an inaccurate understanding of what the skill actually does.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The skill explicitly states that memories persist across conversations and that `ask_clude` calls the Claude API, but it does not provide a clear user-facing warning that submitted content may be stored long-term and transmitted to third-party services. In a memory system, this increases the risk of users or agents sending secrets, personal data, or regulated information under the false assumption that data is ephemeral or local-only.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The recall_memories tool returns full memory content, not just summaries or metadata, and does so through plain-language search filters. That creates a straightforward disclosure path for previously stored user or agent data, especially if sensitive content was persisted earlier and access controls are weak or absent.

Ssd 3

Medium
Confidence
88% confidence
Finding
The tool description explicitly advertises retrieval of stored memories via natural-language search, and the implementation includes full content in results. In the context of a persistent cognitive memory system, this materially raises the chance of broad retrieval of prior user/agent data beyond the immediate session.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The store_memory tool is designed to persist arbitrary content across conversations, including related user identifiers and free-form text, without any visible retention notice, consent mechanism, or data-minimization control at this interface. In a memory skill, this makes privacy risk more acute because users and integrating agents may treat conversational text as ephemeral when it is actually stored long-term.

Ssd 3

Medium
Confidence
90% confidence
Finding
The storage interface encourages saving arbitrary conversation content as durable memory across sessions, which can normalize over-collection and retention of personal, confidential, or regulated data. Because the skill’s core purpose is long-lived memory, the danger is amplified rather than reduced: persistence is intentional, so misuse or overreach has lasting impact.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The skill is presented as a memory-system MCP server, but it also exposes market-state retrieval and a general-purpose LLM interaction tool. This scope expansion increases attack surface and can let an integrating agent invoke capabilities the user or operator may not expect, including external model calls and unrelated data access.

Context-Inappropriate Capability

Medium
Confidence
93% confidence
Finding
The ask_clude tool enables general external LLM querying, which is not necessary for a memory server and introduces data egress to a third-party API. An upstream agent may forward sensitive prompts or recalled memory content into this tool, creating confidentiality, cost, and policy-boundary risks.

Static analysis

No suspicious patterns detected.