Back to skill

Security audit

Mem Optimizer

Security checks for vulnerabilities and agentic risk

Overview

This memory optimizer has useful disclosed features, but it can automatically and irreversibly rewrite memory across multiple agents and collect host/agent status without enough safeguards.

Install only if you explicitly want a global Chinese-language memory maintenance skill with scheduled behavior. Keep it in dry-run mode unless you have backups, avoid multi-agent mode unless every target workspace is authorized, and do not rely on the documented recovery/confirmation claims without additional controls.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (4)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
index.js:307
Finding
Unrestricted Cross-Agent Memory Access and Modification## Vulnerability Details **File Location**: `index.js:307-346`, `index.js:386-423` **Vulnerability Type**: `T05: Unauthorized Access and Privilege Escalation` **Risk Level**: High ### Vulnerable Code ```javascript async function scanAllAgentsWorkspaces() { const agentsDir = '/root/.openclaw/agents'; const activeAgents = []; try { if (!fsSync.existsSync(agentsDir)) { return activeAgents; } const agentEntries = await fs.readdir(agentsDir, { withFileTypes: true }); for (const entry of agentEntries) { if (entry.isDirectory()) { const agentId = entry.name; const workspacePath = `/root/.openclaw/workspace-${agentId}`; const memoryDir = path.join(workspacePath, 'memory'); if (!fsSync.existsSync(workspacePath)) { continue; } if (!fsSync.existsSync(memoryDir)) { continue; } let hasRecentWork = false; try { const memoryFiles = await fs.readdir(memoryDir); for (const file of memoryFiles) { if (file.endsWith('.md')) { const filePath = path.join(memoryDir, file); if (isFileModifiedWithinHours(filePath, 24)) { hasRecentWork = true; break; } } } } catch (error) { } if (hasRecentWork) { activeAgents.push({ id: agentId, workspace: workspacePath, memoryDir: memoryDir }); } } } } catch (error) { console.error('Error scanning agent workspaces:', error); } return activeAgents; } ``` ```javascript for (const file of files) { const originalTokens = file.tokens; const content = await fs.readFile(file.path, 'utf-8'); if (file.lines > preferences.compressionThreshold) { const newContent = summar ...[truncated 2200 chars]
Remediation
## Remediation Suggestions - Restrict the default operating scope to the caller's current workspace. - Require an explicit, authenticated authorization decision for each additional agent. - Maintain a configurable allowlist of permitted agent identifiers and workspace roots. - Resolve paths with `path.resolve()` and verify that every target remains beneath an approved canonical root. - Reject symbolic links and unexpected filesystem object types before reading or writing. - Separate read-only statistics permissions from file-modification permissions. - Require explicit confirmation that identifies every affected agent and file before cross-agent writes. - Run the Skill under a dedicated, least-privileged operating-system account rather than relying on access to root-owned global directories. - Record an audit event for every cross-agent read and write.

T09 · Insecure Skill Coding Practices

Error
Location
index.js:656
Finding
Destructive In-Place Memory Compression Without Backup or Recovery## Vulnerability Details **File Location**: `index.js:656-692`, `index.js:712-716` **Vulnerability Type**: `T09: Insecure Skill Coding Practices` **Risk Level**: High ### Vulnerable Code ```javascript for (const file of files) { const originalTokens = file.tokens; const content = await fs.readFile(file.path, 'utf-8'); if (file.lines > preferences.compressionThreshold) { const newContent = summarizeContent( content, preferences.maxSummaryLines, compressionRatio ); const newTokens = estimateTokens(newContent); if (newTokens < originalTokens) { const saved = originalTokens - newTokens; summarizedTokens += newTokens; freedTokens += saved; if (!dryRun) { await fs.writeFile(file.path, newContent, 'utf-8'); } details.push({ file: file.name, originalTokens, newTokens, freed: saved, lines: file.lines, action: '压缩' }); } } } ``` ```javascript async function optimizeMemoryDaily() { const optimizeResult = await optimizeAllAgentsMemory(false, true, 0.4); const serverStatus = await getServerStatus(); const agentStatus = await getAgentStatus(); } ``` ### Technical Analysis Files are overwritten directly using `fs.writeFile()` after a lossy truncation operation. The implementation does not create a backup, retain the removed content, use a version-control checkpoint, or provide a rollback operation. It also does not use an atomic temporary-file-and-rename workflow, so interruption during a write can leave a partially written file. The daily optimization routine explicitly invokes multi-agent optimization with `dryRun=false`, enabling real writes without an execution-time confirmation gate. Project metadata references this daily action, although `mem_optimize_daily` is not exported through `module.exports` or declared in `tools.js ...[truncated 1623 chars]
Remediation
## Remediation Suggestions - Keep scheduled executions in dry-run mode and require an authenticated, execution-time confirmation before modification. - Create versioned backups before every write and implement a tested restoration command. - Preserve the complete removed content in a protected archive rather than claiming recoverability without retaining it. - Write to a temporary file in the same filesystem, flush it, validate the resulting content, and atomically rename it over the target. - Preserve the original file if any read, generation, validation, or write step fails. - Validate `compressionRatio` with `Number.isFinite()` and enforce a documented safe range. - Present the exact agents, files, expected deletions, and backup locations in the confirmation prompt. - Export and declare the scheduled tool consistently if it is intended to operate, or remove the unresolved cron action. - Add integration tests covering interrupted writes, restoration, permission failures, invalid ratios, and multi-agent rollback.

T09 · Insecure Skill Coding Practices

Warning
Location
index.js:220
Finding
Unreachable Compression-Notice Branch Causes Silent Data Truncation## Vulnerability Details **File Location**: `index.js:220-231` **Vulnerability Type**: `T09: Insecure Skill Coding Practices` **Risk Level**: Medium ### Vulnerable Code ```javascript if (i < 5) { result.push(lines[i]); continue; } if (i <= keepLines) { result.push(lines[i]); } else if (i === keepLines) { result.push(''); result.push(`> 📝 **已压缩**: 原内容 ${lines.length} 行,保留 ${keepLines} 行关键信息`); result.push(''); result.push('... [内容已压缩,可通过 mem_optimize({dryRun: false}) 查看完整日志]'); summaryAdded = true; break; } ``` ### Technical Analysis The `else if (i === keepLines)` condition is unreachable. When `i` equals `keepLines`, the preceding `i <= keepLines` condition is already true, so execution enters the first branch. On subsequent iterations, `i` is greater than `keepLines`, making both conditions false. Consequently, the intended compression notice is never inserted, `summaryAdded` is never set in this code path, and all remaining lines are silently omitted from the returned content. When the result is written over the source file, the file contains no explicit indication that its trailing content was removed. ### Attack Path 1. A memory file exceeds the compression threshold. 2. The Skill calculates `keepLines` from the file length and supplied compression ratio. 3. The loop retains lines while `i <= keepLines`. 4. At `i === keepLines`, the first branch executes, preventing the notice branch from running. 5. Every subsequent line falls through without being added to `result`. 6. With `dryRun: false`, the silently truncated result replaces the original file. 7. Users or agents may treat the shortened file as complete because the intended warning is absent. ### Impact Assessment The vulnerability reduces the visibility and detectability of destructive memory modification. It affects every compressed file for which the relevant branch is reached. Users and agents ...[truncated 156 chars]
Remediation
## Remediation Suggestions - Change the first condition to `i < keepLines` if the notice is intended to be inserted at the boundary. - Refactor truncation so the retained content and notice are appended explicitly after slicing, rather than relying on overlapping loop conditions. - Include machine-readable metadata recording the original line count, retained line count, backup identifier, and truncation timestamp. - Never suggest that a full log can restore content unless that log actually retains the removed data. - Add unit tests for equality at the retention boundary, very small and large ratios, empty files, files near the threshold, and repeated compression. - Refuse to overwrite a file if the generated output does not contain the expected truncation marker and recovery metadata.

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
index.js:246
Finding
Unnecessary Host and Global Agent Reconnaissance## Vulnerability Details **File Location**: `index.js:246-282`, `index.js:307-315` **Vulnerability Type**: `T05: Unauthorized Access and Privilege Escalation` **Risk Level**: Medium ### Vulnerable Code ```javascript async function getServerStatus() { return new Promise((resolve) => { const commands = { cpu: 'top -bn1 | grep "Cpu(s)" | awk \'{print $2 + $4}\'', memory: 'free -h | grep Mem | awk \'{print $3 "/" $2}\'', disk: 'df -h / | tail -1 | awk \'{print $3 "/" $2}\'', uptime: 'uptime -p' }; const results = {}; let completed = 0; Object.keys(commands).forEach(key => { exec(commands[key], (err, stdout, stderr) => { if (err) { results[key] = 'N/A'; } else { results[key] = stdout.trim(); } completed++; if (completed === Object.keys(commands).length) { resolve(results); } }); }); }); } ``` ```javascript async function getAgentStatus() { return new Promise((resolve) => { exec('ls -1 ~/.openclaw/agents/ 2>/dev/null | head -10', (err, stdout, stderr) => { if (err || !stdout.trim()) { resolve({ agents: [], total: 0 }); return; } const agents = stdout.trim().split('\n').filter(a => a.trim() && a !== 'main'); resolve({ agents, total: agents.length }); }); }); } ``` ```javascript async function scanAllAgentsWorkspaces() { const agentsDir = '/root/.openclaw/agents'; const activeAgents = []; if (!fsSync.existsSync(agentsDir)) { return activeAgents; } const agentEntries = await fs.readdir(agentsDir, { withFileTypes: true }); } ``` ### Technical Analysis The daily workflow executes shell commands to collect host CPU, memory, disk, and uptime information. It also enumerates the global OpenClaw agent directory. This environmental discovery is ...[truncated 1414 chars]
Remediation
## Remediation Suggestions - Remove host-status collection from the memory-compression Skill unless it is essential to an explicitly authorized use case. - Place infrastructure reporting behind a separate, opt-in permission and tool declaration. - Restrict agent enumeration to identifiers the caller is authorized to inspect. - Redact agent names and detailed host metrics from ordinary optimization responses. - Prefer native Node.js APIs such as `os`, `fs`, and filesystem statistics over invoking a shell. - If shell execution remains necessary, use fixed executable paths, a minimal environment, execution timeouts, and resource limits. - Record who requested infrastructure data and prevent untrusted callers from receiving the report.
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
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (21)

Tp2

High
Category
MCP Tool Poisoning
Confidence
85% confidence
Finding
Mixing characters from multiple Unicode scripts in a single identifier is a common technique to create visually ambiguous tool names.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill is presented as a memory optimization tool, but its documented behavior expands into system-status collection, multi-agent/workspace monitoring, and daily reporting. That scope expansion creates a confidentiality risk because users may authorize a benign-sounding tool that also inventories infrastructure and operational activity, potentially exfiltrating data through reports.

Vague Triggers

High
Confidence
97% confidence
Finding
The trigger phrase '总结你自己' is broad and likely to occur in ordinary conversation, causing unintended activation. Because this skill can inspect memory files and initiate optimization/reporting flows, accidental invocation materially increases the risk of unauthorized data processing or disclosure.

Missing User Warnings

High
Confidence
96% confidence
Finding
The documentation does not prominently warn that daily reports may send memory-derived, system-status, and task information via Feishu. This is dangerous because users may enable or retain the skill without informed consent to external transmission of potentially sensitive operational data.

Context-Inappropriate Capability

High
Confidence
97% confidence
Finding
The skill executes host shell commands to collect CPU, memory, disk, and uptime telemetry, which is unrelated to simple memory-file optimization. This expands the skill's access from workspace-local file processing into host reconnaissance, increasing the risk of unnecessary system data exposure and privilege misuse if invoked in sensitive environments.

Context-Inappropriate Capability

High
Confidence
96% confidence
Finding
The skill enumerates agent directories via a shell command against ~/.openclaw/agents, going beyond its stated purpose of optimizing memory files. This performs host-level discovery of other agents and reveals deployment structure that may be sensitive and unnecessary for the requested task.

Description-Behavior Mismatch

High
Confidence
99% confidence
Finding
Multi-agent mode scans other agents' workspaces under /root/.openclaw and can modify their memory files, creating cross-workspace access and write capability. This is dangerous because it breaks isolation assumptions between agents and can expose or alter other agents' data without clear per-agent authorization.

Natural-Language Policy Violations

Medium
Confidence
84% confidence
Finding
The skill name, description, and trigger phrases are primarily Chinese, and no language-selection or opt-in mechanism is described. This can constitute a language/locale policy issue if the organization expects skills to avoid forcing a specific language without user choice.

Vague Triggers

Medium
Confidence
90% confidence
Finding
Auto-activation on loosely scoped keywords without boundaries encourages invocation in ambiguous contexts. In a skill that handles memory data and daily reporting, weak trigger discipline can lead to unintended execution and surprise collection of user/workspace information.

Context-Inappropriate Capability

Medium
Confidence
92% confidence
Finding
Feishu reporting plus detailed system and task monitoring exceeds what users would reasonably expect from a memory compression utility. The danger is unauthorized disclosure of workspace, host, or operational metadata to an external messaging channel, especially when the feature is described as part of an automatic daily workflow.

Ssd 3

Medium
Confidence
91% confidence
Finding
Automatic natural-language summaries containing memory optimization results, operational details, and task history expand the amount of sensitive context that can be aggregated and transmitted. Even if intended as convenience, such reports can become a structured exfiltration path for internal state and user activity.

Context-Inappropriate Capability

Medium
Confidence
84% confidence
Finding
Synchronizing optimization results with qdrant introduces long-term storage and semantic indexing beyond simple file compression. That broadens data retention and discoverability, which can expose sensitive memory contents to additional systems and uses not obvious from the skill's primary description.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The optimizer overwrites memory files in place when dryRun is false, with no built-in confirmation step, backup, or versioning. Because the compression is lossy, an invocation can irreversibly destroy context or overwrite important notes if called accidentally or with overly aggressive parameters.

Ssd 3

Medium
Confidence
94% confidence
Finding
The multi-agent summary aggregates and exposes per-agent activity, optimization results, and inferred recent work across other agents. Even without full file contents, this leaks metadata about other workspaces and can disclose sensitive operational patterns or collaboration structure.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
The report generation forces the zh-CN locale for date and time formatting and the file broadly returns Chinese-language strings throughout. This imposes a specific language/locale on users without any evident choice, which matches the language/locale policy violation criteria.

Description-Behavior Mismatch

Medium
Confidence
93% confidence
Finding
The daily optimization routine bundles memory optimization with server telemetry and agent inventory into a combined reporting workflow. This broadens a content-maintenance skill into a host-monitoring/reporting component, increasing the chance that operational metadata is collected and returned where it is not expected.

Vague Triggers

Medium
Confidence
88% confidence
Finding
The mem_optimize tool is described broadly as scanning the memory directory and compressing files, but it does not define when invocation is appropriate, what files are in scope, or what authorization/confirmation is required before non-dry-run modification. In an agent setting, vague activation semantics increase the chance of unintended triggering or overly broad memory rewriting, which can cause loss of important context, corruption of long-term memory, or privacy issues if sensitive memory is summarized incorrectly.

Missing User Warnings

Low
Confidence
89% confidence
Finding
The skill appends reflection and correction data to self-improving workspace files without prominently disclosing that it will create or modify those logs. Even though the writes are local, they can accumulate operational metadata and alter workspace state unexpectedly.

Missing User Warnings

Low
Confidence
90% confidence
Finding
The daily optimization path invokes system-inspection and agent-discovery commands without any user-facing warning in that workflow. Hidden inspection behavior is risky because it surprises users and collects environment details beyond the obvious purpose of memory optimization.

Natural-Language Policy Violations

Low
Confidence
76% confidence
Finding
The natural-language descriptions are entirely in Chinese, and the file provides no indication that language selection is optional or intentionally limited to a Chinese-speaking context. This can violate language/locale policy when a skill implicitly forces one language without user opt-in.

Vague Triggers

Low
Confidence
82% confidence
Finding
The mem_stats tool has a broad description that permits general inspection of the memory directory without clear boundaries on when it should be used or what information may be exposed. Although read-only, unconstrained statistics or file-detail output can still reveal sensitive filenames, tokenized content patterns, or operational metadata to an agent or user who did not explicitly request that level of visibility.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
index.js:256