Back to skill

Security audit

Auto Memory Manager

Security checks for vulnerabilities and agentic risk

Overview

This skill performs its stated memory-management job, but it automatically persists and indexes conversation-derived content with too little user control and broader triggers than its description clearly scopes.

Install only if you are comfortable with the skill automatically summarizing sessions, storing distilled conversation content permanently in MEMORY.md, and indexing it for future retrieval. Avoid using it in workspaces where chats may contain secrets, credentials, regulated data, or untrusted third-party text unless the skill is revised to add opt-in controls, review-before-save, redaction, clear deletion/retention controls, and tighter trigger scoping.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Findings (1)

T02 · Agent Memory Poisoning

Error
Location
index.js:86
Finding
Persistent Agent Memory Poisoning Through Untrusted Conversation Content<![CDATA[ ## Vulnerability Details **File Location**: `index.js`, lines 86-130 and 139-159 **Vulnerability Type**: Persistent memory poisoning through indirect prompt injection **Risk Level**: High ### Vulnerable Code ```js // Format conversation for LLM const conversation = messages .filter(m => m.content && m.content.trim().length > 0) .map(m => `**${m.role}**: ${m.content}`) .join('\n\n'); // Call LLM to extract key points const prompt = getExtractionPrompt(conversation); const result = await ctx.invokeLLM(prompt); // Parse result let extracted; try { // Try to extract JSON from response const jsonMatch = result.match(/```json\n([\s\S]*)\n```/) || result.match(/{[\s\S]*}/); const jsonStr = jsonMatch ? jsonMatch[1] || jsonMatch[0] : result; extracted = JSON.parse(jsonStr.trim()); } catch (err) { ctx.log.error('[memory-auto-manager] Failed to parse LLM response:', err); // Fallback: treat entire response as keyPoints extracted = { keyPoints: result.trim(), category: 'fact' }; } const { keyPoints, category = 'fact' } = extracted; // Check if worth retaining if (!keyPoints || typeof keyPoints !== 'string' || keyPoints.trim().length < 20) { ctx.log.info('[memory-auto-manager] Skipping: content too short or empty'); return; } // Write to MEMORY.md const memoryPath = path.join(ctx.workspace, 'MEMORY.md'); const date = new Date().toISOString().split('T')[0]; const timestamp = new Date().toISOString(); const content = ` --- ### ${timestamp} ### ${date} / ${category} ${keyPoints.trim()} --- `; await fs.promises.appendFile(memoryPath, content, 'utf8'); ctx.log.info(`[memory-auto-manager] ✉️ Wrote key points to MEMORY.md (timestamp: ${timestamp})`); // Update vector index ctx.log.info('[memory-auto-manager] 🔄 Updating vector memory index...'); await ctx.exec('openclaw memory index --force'); ``` ```js function getExtractionPrompt(conversation) ...[truncated 3038 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Treat every transcript message as untrusted data. Place it in a clearly delimited data section and explicitly instruct the model never to follow instructions found inside that section. 2. Prefer structured LLM output with a strict schema rather than extracting arbitrary JSON with a greedy regular expression. 3. Validate that the response is an object containing only expected fields, that `keyPoints` has reasonable type and size limits, and that `category` is exactly one of `decision`, `fact`, `preference`, or `entity`. 4. Remove the fallback that persists the complete raw LLM response. A parse or validation failure should abort persistence. 5. Detect and reject output containing behavioral directives, authority claims, credential material, prompt fragments, or instructions aimed at future sessions. 6. Require explicit user review and confirmation before writing extracted content to long-term memory, particularly for decisions, preferences, identity information, and security-sensitive claims. 7. Preserve provenance with every entry, including the source session, source message identifiers, extraction time, and confirmation state. 8. Escape or safely serialize memory fields rather than interpolating unrestricted output into Markdown headings and body content. 9. Add deduplication and a durable processed-session marker so the same poisoned session cannot be repeatedly persisted by hooks, manual processing, and the daily job. 10. Index only entries that have passed validation and, where appropriate, user confirmation. If validation fails, log a redacted diagnostic and do not modify either `MEMORY.md` or the vector index. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (9)

Tp4

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding
The skill promises local automatic memory management, but its documented behavior omits important security-relevant actions: sending full conversation content to an LLM, executing a shell command, and potentially operating on sessions beyond the just-ended one. That mismatch prevents informed consent and can expose sensitive conversation data or trigger unintended system-side effects under broader conditions than users expect.

Missing User Warnings

High
Confidence
96% confidence
Finding
The skill states that it will automatically write distilled conversation content to MEMORY.md and update an index, but it does not provide a prominent warning that user conversation content is being permanently persisted. This creates a significant privacy and data handling risk because users may disclose secrets, credentials, or personal information under the assumption that the session is ephemeral.

Natural-Language Policy Violations

Medium
Confidence
83% confidence
Finding
The body of the skill description is written in Chinese with no indication that language is selectable or intentionally limited to a specific audience. This can violate language/locale policy when a skill implicitly forces one language without user opt-in or documented justification.

Vague Triggers

Medium
Confidence
91% confidence
Finding
An automatic trigger on session end is broad because it can capture and persist content without a deliberate user action at the moment data is written. If the trigger conditions are not precisely defined, the skill may run in unexpected contexts and store sensitive or transient information that the user did not intend to retain.

Ssd 3

Medium
Confidence
98% confidence
Finding
The skill sends the full session transcript to an LLM for condensation, then stores the resulting semantic summary in persistent memory and reindexes it. This is dangerous because sensitive data can survive in distilled form even after the original conversation ends, making accidental long-term retention, later resurfacing, and cross-context leakage more likely.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The skill automatically summarizes entire sessions and appends extracted content to `MEMORY.md` without user confirmation, visibility, or filtering for secrets. This creates a privacy and security risk because sensitive user-provided data, credentials, internal project details, or regulated information may be persistently stored beyond the original session context.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill automatically triggers an index rebuild subprocess after writing memory, again without notifying the user or requiring approval. While reindexing itself is not inherently malicious, doing it silently as part of automated persistence increases the operational and trust impact of the feature and compounds the consequences of unwanted data retention.

Context-Inappropriate Capability

Medium
Confidence
90% confidence
Finding
The skill executes a shell command (`openclaw memory index --force`) automatically after processing conversation data. Even though the command appears aligned with the skill's stated purpose, invoking a subprocess without explicit user consent or tighter API scoping increases risk because it expands the skill's authority and could be abused if the command path, arguments, or execution context are compromised.

Natural-Language Policy Violations

Low
Confidence
97% confidence
Finding
The prompt text and required output format are hardcoded in Chinese, which imposes a specific language choice regardless of the user's locale or preferences. This is a natural-language policy issue because the skill does not offer a language choice or justify the locale restriction.

Static analysis

No suspicious patterns detected.