Back to skill

Security audit

Openclaw Skills Smart Agent Memory

Security checks for vulnerabilities and agentic risk

Overview

This is a legitimate memory tool, but it needs Review because it stores long-term searchable user data and can generate persistent skills without enough containment.

Install only if you are comfortable with agents writing durable, searchable memory under ~/.openclaw/workspace/memory. Avoid storing secrets, credentials, regulated personal data, or sensitive business details. Do not enable the suggested cron jobs or use the extract command until the path traversal issues are fixed and generated skills are reviewed in a non-loaded draft location before installation.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • 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
  • 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
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
lib/store.js:323
Finding

Path Traversal Through Entity Names Allows Writes Outside the Entity Directory

Content
View full analysis
`- **${k}:** ${v}`).join('\n'); const md = [ `# ${entity.name}`, `**Type:** ${entity.entityType}`, `**First seen:** ${entity.firstSeen.slice(0, 10)}`, `**Last updated:** ${entity.lastUpdated.slice(0, 10)}`, '', attrs || '_(no attributes)_', ].join('\n'); try { const dirPath = path.join(this.memoryDir, dir); this._ensureDir(dirPath); fs.writeFileSync(path.join(dirPath, filename), md); } catch {} } ``` SQLite backend: ```js _writeEntityMd(entity) { const dir = entity.entityType === 'person' ? 'people' : 'decisions'; const dirPath = path.join(this.memoryDir, dir); this._ensureDir(dirPath); const filename = `${entity.name.toLowerCase().replace(/\s+/g, '-')}.md`; const attrs = Object.entries(entity.attributes).map(([k, v]) => `- **${k}:** ${v}`).join('\n'); const md = `# ${entity.name}\n**Type:** ${entity.entityType}\n**First seen:** ${entity.firstSeen.slice(0, 10)}\n**Last updated:** ${entity.lastUpdated.slice(0, 10)}\n\n${attrs || '_(no attributes)_'}\n`; try { fs.writeFileSync(path.join(dirPath, filename), md); } catch {} } ``` CLI entry point: ```js case 'entity': { const name = args[1]; const type = args[2]; if (!name || !type) return usage('entity [--attr key=value ...]'); const attrs = {}; for (let i = 3; i < args.length; i++) { if (args[i] === '--attr' && args[i + 1]) { const [k, ...v] = args[i + 1].split('='); if (k) attrs[k] ...[truncated 2131 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/memory-cli.js:389
Finding

Unsanitized Skill Name Allows SKILL.md Path Traversal

Content
View full analysis
[--skill-name my-skill]'); // Support both JSON store (.lessons array) and SQLite store (getLessons method) const allLessons = store.lessons || store.getLessons({ limit: 9999 }); const lesson = allLessons.find(l => l.id === lessonId); if (!lesson) return console.log(c.red(`Lesson ${lessonId} not found.`)); const skillDir = path.join(os.homedir(), '.openclaw', 'skills', skillName); const outFile = extractSkill(lesson, skillDir, skillName); console.log(`${c.green('✓')} Skill extracted: ${outFile}`); console.log(` From lesson: ${lesson.action}`); break; } ``` File creation sink: ```js function extractSkill(lesson, outputDir, skillName) { fs.mkdirSync(outputDir, { recursive: true }); const skillMd = `--- name: ${skillName} description: "Auto-extracted from lesson: ${lesson.action}" metadata: openclaw: trust: low --- # ${skillName} > Auto-generated from lesson **${lesson.id}** on ${lesson.createdAt.slice(0, 10)} ## Context ${lesson.context} ## What Happened ${lesson.action} ## Outcome **${lesson.outcome}** ## Insight / Best Practice ${lesson.insight} ## When to Use Apply this skill when you encounter a similar situation: - Context matches: ${lesson.context} - To avoid repeating: ${lesson.outcome === 'negative' ? 'the same mistake' : 'missing the opportunity'} --- *Extracted by smart-agent-memory skill extraction.* `; fs.writeFileSync(path.join(outputDir, 'SKILL.md'), skillMd); return path.join(outputDir, 'SKILL.md'); } ``` ### Technical Analysis The value supplied ...[truncated 1644 chars]
Remediation
View remediation

T02 · Agent Memory Poisoning

Error
Location
lib/extract.js:15
Finding

Untrusted Lesson Content Is Converted Into a Persistent Agent Skill Without Sanitization or Review

Content
View full analysis
Auto-generated from lesson **${lesson.id}** on ${lesson.createdAt.slice(0, 10)} ## Context ${lesson.context} ## What Happened ${lesson.action} ## Outcome **${lesson.outcome}** ## Insight / Best Practice ${lesson.insight} ## When to Use Apply this skill when you encounter a similar situation: - Context matches: ${lesson.context} - To avoid repeating: ${lesson.outcome === 'negative' ? 'the same mistake' : 'missing the opportunity'} --- *Extracted by smart-agent-memory skill extraction.* `; fs.writeFileSync(path.join(outputDir, 'SKILL.md'), skillMd); return path.join(outputDir, 'SKILL.md'); } ``` The lesson fields originate from CLI input and are stored without trust labeling or content validation: ```js case 'learn': { const action = flagVal('--action'); const context = flagVal('--context'); const outcome = flagVal('--outcome'); const insight = flagVal('--insight'); if (!action || !context || !outcome || !insight) { return usage('learn --action "..." --context "..." --outcome positive|negative|neutral --insight "..."'); } const lesson = store.learn(action, context, outcome, insight); console.log(`${c.green('✓')} Lesson recorded: ${c.bold(lesson.id)}`); console.log(` Action: ${action}`); console.log(` Context: ${context}`); console.log(` Outcome: ${ ...[truncated 2776 chars]
Remediation
View remediation
/SKILL.md ``` 3. Clearly delimit lesson values as untrusted quoted data rather than operative instructions. Do not copy them into sections that tell the Agent what to do. 4. Serialize YAML metadata with a proper YAML serializer. At minimum, reject newlines and safely escape quotes in metadata values. 5. Validate `outcome` against the documented finite set: `positive`, `negative`, or `neutral`. 6. Add provenance metadata identifying the source lesson, originating session, and whether the content has received human approval. 7. Scan generated content for instruction-like patterns, tool invocation requests, secret-access requests, role overrides, and attempts to alter safety constraints. 8. Separate historical evidence from generated recommendations. Derive recommendations only through a constrained transformation, and present the original lesson as fenced or escaped text. 9. Do not automatically enable or register the generated Skill. Require a distinct approval or installation action. 10. Preserve the `trust: low` marker, but enforce it through platform policy so low-trust generated Skills cannot receive sensitive tools without explicit authorization. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (30)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The description is broadly aligned with a long-term agent memory system: the code supports facts, lessons, entities, layered context/indexing, skill experience memory, Markdown + JSON persistence, and temperature-like hot/warm/cold stats. However, there are material gaps versus the declared capabilities. First, the description states a three-layer storage system including SQLite/FTS5, but this file only implements JSON/Markdown directly and conditionally loads an external sqlite-store backend; the SQLite/FTS5 functionality is not present in the supplied chunk. Second, the declared 'high-performance full-text search' is not reflected here: recall() uses straightforward substring matching and scoring, not FTS5. Third, 'automatic archiving' is declared, but this code merely defines archive paths and counts archived files in stats(); there is no archive operation shown. These are not just implementation details—they are named product capabilities that are absent or only indirectly referenced in the provided code. Therefore the description overstates what the supplied code chunk actually does.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill explicitly encourages storing long-term memories and entity attributes, including potentially personal data such as names, roles, emails, and user-provided facts, without any prominent privacy, minimization, retention, or consent guidance. In an agent context, this can lead to silent accumulation of sensitive data across conversations, increasing exposure risk if the workspace is shared, backed up, searched, or later exfiltrated.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The README documents deletion and garbage-collection behaviors, including forget and GC cleanup of older low-frequency facts, without prominent warnings, confirmations, backup recommendations, or restore procedures adjacent to those commands. In a memory system, users or agents may trigger destructive operations assuming they are routine maintenance, causing unintended loss of conversational history or structured data.

Content

No source excerpt is available for this finding.

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · README.md (reported line 283)May include surrounding context.

提炼

node scripts/memory-cli.js extract --skill-name deploy-checklist

→ 生成 ~/.openclaw/skills/deploy-checklist/SKILL.md

text

把一条教训自动生成 SKILL.md 模板,包含背景、问题、解决方案、使用场景。你可以在此基础上完善,变成一个真正可复用的 Agent 技能。

Ssd 3

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The workflow guidance instructs the agent to persist user-provided information, corrections, and conversation-derived facts across sessions, including when the user simply says 'remember this,' without any guardrails for sensitivity, necessity, or consent boundaries. In a multi-agent shared workspace, this makes overcollection and long-term retention more dangerous because stored data becomes searchable, reusable, and potentially visible to other agents or operators.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill explicitly encourages agents to persist conversational content frequently and automatically, but does not pair that with strong guidance on consent, minimization, or sensitive-data filtering. This creates a real privacy and data-retention risk because user-provided secrets, personal data, or regulated content may be written to durable local storage and later resurfaced.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The instructions encourage writing facts, lessons, and session summaries in natural language, which can easily capture credentials, personal information, business-sensitive decisions, or other confidential user content. Once stored in searchable Markdown/JSON memory, that information becomes easier to rediscover and potentially expose to future agent actions or users.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The recommended cron jobs schedule unattended reflection, archival, and summary generation over stored conversations without warning about autonomous processing of potentially sensitive content. This increases exposure because data can be revisited, transformed, and retained even when no human is actively supervising or approving the processing step.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The daily session-check workflow instructs the agent to revisit past conversations and backfill missing summaries, creating a second opportunity to persist sensitive material that may previously have remained ephemeral. That amplification step increases privacy risk because historical user content is deliberately reprocessed and converted into durable searchable memory.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The compressLogs function modifies and truncates existing memory markdown files in place once they exceed a size threshold, while archiving the original separately. Even though it creates a backup, this is still a destructive transformation of user memory state without any built-in confirmation, dry-run mode, or explicit safeguard, which can lead to silent data loss from the user's active working set and altered downstream agent behavior.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The returned prompt is written entirely in Chinese and instructs the agent to format and write logs according to Chinese-language requirements, including spacing Chinese keywords. This imposes a language/locale constraint without offering the user a choice or documenting that the skill is intentionally limited to a Chinese-only context.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · lib/extract.js (reported line 12)May include surrounding context.

js
/**
 * Extract a lesson into a skill template.
 * @param {object} lesson - Lesson object from store
 * @param {string} outputDir - Where to write the skill (e.g., ~/.openclaw/skills/<name>)
 * @param {string} skillName - Skill name (slug)
 */
function extractSkill(lesson, outputDir, skillName) {

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The header comment explicitly says 'No external dependencies', but the implementation imports child_process and later runs execFileSync('qmd', ...). That is an active contradiction between the file's documentation and its actual behavior, because successful operation of the preferred search path depends on an external binary being present.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The code persists remembered content not only in SQLite but also into human-readable Markdown logs and per-skill memory files without any consent, disclosure, or data-classification checks. In a long-term agent memory system, this can silently retain sensitive prompts, secrets, or personal data far beyond user expectations, increasing privacy and secret-exposure risk if the filesystem is later accessed, synced, or backed up.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

Lesson records are written directly to Markdown files containing action, context, outcome, and insight, which may include sensitive conversation content or internal workflow details. Because this happens automatically and without any user-warning path in this file, users may not realize their data is being duplicated into easily readable files outside the database.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

Entity information is exported to Markdown files automatically, including names and arbitrary attributes, which can expose personal or sensitive metadata in plain text. In the context of a cross-platform persistent memory skill, this broadens the attack surface because readable files are easier to discover, inspect, sync, or accidentally commit than structured database records alone.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The remember() path persists arbitrary memory content to multiple local files, including human-readable Markdown logs and per-skill history, with no consent gate, redaction, or classification check. In an agent memory system, inputs may include secrets, personal data, tokens, or proprietary prompts, so duplicating them on disk materially increases disclosure risk if the host is shared, backed up, synced, or later exfiltrated.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

learn() writes action, context, outcome, and insight into Markdown files directly, which can capture sensitive operational context, incident details, or personal information. Because this skill is specifically designed for long-term agent memory, the skill context makes the issue more dangerous: users may assume transient conversational state while the system silently creates durable, readable artifacts.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

Entity tracking stores names and arbitrary attributes as Markdown, which can create a local directory of personal or sensitive data without any disclosure or minimization. Since the feature is expressly intended to track people and decisions over time, it raises privacy and confidentiality risk beyond incidental logging, especially on multi-user systems or machines with cloud backup/sync enabled.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The reflect command aggregates facts, entities, tags, lessons, and skill memory into a Markdown file on disk without any privacy notice or data-minimization controls. This can unintentionally materialize sensitive derived information in a single easy-to-read artifact, increasing exposure to local users, backups, indexing tools, or other processes that can read the memory directory.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The manifest describes a long-term memory system focused on layered context, structured storage, search, and archiving. The extract command goes beyond memory management by materializing a lesson into a skill under ~/.openclaw/skills, introducing code-generation/scaffolding capability not justified by the stated memory purpose.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

session-end persists arbitrary session summaries directly into long-term storage with no consent prompt, sensitivity screening, redaction, or visibility warning. In an agent context, summaries can easily contain secrets, personal data, credentials, or proprietary conversation content, creating durable local exposure and expanding the blast radius of later compromise or accidental disclosure.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

The title and the entire instructional content are presented in Chinese, and examples and workflow guidance assume Chinese-language usage, but the document does not offer an alternative language or indicate that the skill is intentionally region-specific. Per the policy category, forcing a specific language without user opt-in can be a locale-policy concern.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest description presents the skill as '纯 Node.js 原生模块,零外部依赖', which implies the skill's functionality is self-contained. However, the README states that the search command can invoke an external qmd tool for BM25/vector/rerank search, meaning some advertised behavior relies on software outside native Node.js modules.

Content

No source excerpt is available for this finding.