Back to skill

Security audit

Team Shared Memory

Security checks for vulnerabilities and agentic risk

Overview

This skill is a local OpenClaw memory-sharing utility, but it automatically moves persistent memory files without strong boundaries or approval checks.

Review this before installing if team memory may be writable by other users, workspaces, or agents. Do not rely on the advertised secret scan to protect sync operations, and avoid running this under a privileged account. Use only with trusted local memory directories, restrictive filesystem permissions, and a manual review process for shared Markdown until symlink rejection, enforced scanning, and approval/quarantine controls are added.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (3)

T02 · Agent Memory Poisoning

Error
Location
scripts/sync.js:124
Finding

Untrusted Shared Files Can Poison Persistent Agent Memory

Content
View full analysis
f.endsWith('.md') && !f.startsWith('.')); for (const file of files) { const srcFile = path.join(srcDir, file); const destFile = path.join(destDir, file); if (!fs.existsSync(destFile)) { fs.copyFileSync(srcFile, destFile); syncReport.pulled.push(`${type}/${file}`); state.lastHash[file] = fileHash(srcFile); } } } ``` ### Technical Analysis The synchronization process treats every non-hidden Markdown file in the shared `team/project` and `team/reference` directories as trusted persistent memory. It copies those files into the Agent's `auto` memory directories without verifying the writer, validating provenance, inspecting the content, or obtaining user approval. If another workspace, user, process, or compromised Agent can write to the team directory, it can insert Markdown containing false facts, adversarial instructions, or persistent behavioral directives. The next synchronization imports that content into the Agent's long-term memory area, where it may influence future sessions. The filename restrictions only require the `.md` suffix and reject hidden names. They do not provide an authorization or content-integrity boundary. ### Attack Path 1. An attacker obtains write access to `~/.openclaw/workspace/memory/team/project` or `team/reference`, directly or through another synchronized Agent. 2. The attacker creates a file such as `project-policy.md` containing malicious instructions or deli ...[truncated 935 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/sync.js:74
Finding

Secret Scanning Is Not Enforced During Memory Synchronization

Content
View full analysis
f.endsWith('.md') && !f.startsWith('.')); for (const file of files) { const srcFile = path.join(srcDir, file); const destFile = path.join(destDir, file); const hash = fileHash(srcFile); // 检查是否变更 if (state.lastHash[file] === hash && fs.existsSync(destFile)) { continue; // 未变更,跳过 } // 目标存在且不同 → 冲突 if (fs.existsSync(destFile)) { const destHash = fileHash(destFile); if (hash !== destHash) { // 以较新的为准 const srcMtime = fs.statSync(srcFile).mtimeMs; const destMtime = fs.statSync(destFile).mtimeMs; if (srcMtime > destMtime) { fs.copyFileSync(srcFile, destFile); syncReport.pushed.push(`${type}/${file}`); } else { fs.copyFileSync(destFile, srcFile); syncReport.pulled.push(`${type}/${file}`); } syncReport.conflicts.push(`${type}/${file}`); } } else { fs.copyFileSync(srcFile, destFile); syncReport.pushed.push(`${type}/${file}`); } state.lastHash[file] = hash; } } ...[truncated 3696 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/sync.js:87
Finding

Symbolic Links Can Cause Unauthorized File Disclosure or Overwrite

Content
View full analysis
f.endsWith('.md') && !f.startsWith('.')); for (const file of files) { const srcFile = path.join(srcDir, file); const destFile = path.join(destDir, file); const hash = fileHash(srcFile); // 检查是否变更 if (state.lastHash[file] === hash && fs.existsSync(destFile)) { continue; // 未变更,跳过 } // 目标存在且不同 → 冲突 if (fs.existsSync(destFile)) { const destHash = fileHash(destFile); if (hash !== destHash) { // 以较新的为准 const srcMtime = fs.statSync(srcFile).mtimeMs; const destMtime = fs.statSync(destFile).mtimeMs; if (srcMtime > destMtime) { fs.copyFileSync(srcFile, destFile); syncReport.pushed.push(`${type}/${file}`); } else { fs.copyFileSync(destFile, srcFile); syncReport.pulled.push(`${type}/${file}`); } syncReport.conflicts.push(`${type}/${file}`); } } else { fs.copyFileSync(srcFile, destFile); syncReport.pushed.push(`${type}/${file}`); } state.lastHash[file] = hash; } ``` The pull path has the same issue: ```javascript const files = fs.readdirSync(srcDir).filter(f => f.endsWith('.md') && !f.startsWith('.')); for (const file of files) { const srcFile = path.join(srcDir, file); const destFile = path.join(destDir, file); if (!fs.existsSync(destFile)) { fs.copyFileSync(srcFile, destFile); syncReport.pulled.push(`${type}/${file}`); state.lastHash[file] = fileHash(srcFile); } } ``` State and lock files are also written without rejecting symbolic links: ```javascript function saveState(state) { fs.writeFileSync(STATE_FILE, JSON.stringi ...[truncated 3460 chars]
Remediation
View remediation
Vulnerability Patterns
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (7)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill claims cross-agent or cross-instance memory synchronization, but the implementation reportedly only synchronizes local filesystem directories and exposes undeclared status-enumeration behavior. Such interface and behavior drift is risky because users may trust it as a scoped sync utility while it actually enumerates local data and provides misleading security-related options that are undocumented or unimplemented.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The skill claims cross-agent or cross-instance memory synchronization, but the implementation reportedly only synchronizes local filesystem directories and exposes undeclared status-enumeration behavior. Such interface and behavior drift is risky because users may trust it as a scoped sync utility while it actually enumerates local data and provides misleading security-related options that are undocumented or unimplemented.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
82% confidence
Finding

The skill declares capabilities consistent with environment access but does not define any explicit tool scope or permissions boundary. In a memory-sharing skill that also references scanning and synchronization behavior, missing scope declarations increase the chance of unintended access to local state or sensitive configuration during execution.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The file presents the skill description and primary documentation in Chinese, with no indication that users can opt into another language or that the skill is intentionally region-specific. This can violate language/locale policy when a skill imposes a language preference by default.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This code file contains natural-language comments and CLI output exclusively in Chinese, including usage/help text shown to users. Under the policy rule, forcing a specific language without user opt-in is a locale-policy violation unless the constraint is explicitly justified, which is not present here.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The file’s user-facing natural-language content, including the header usage instructions and later console messages, is exclusively in Chinese. For a general sync utility with no documented region-specific purpose or opt-in, this imposes a specific language on users and matches the locale-policy violation criteria.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill description is written entirely in Chinese, which imposes a specific language/locale choice in user-facing natural language without indicating that users can select another language. The provided metadata does not document any region-specific justification for this constraint.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.