Back to skill

Security audit

🦞 龙虾记忆备份同步技能 / Lobster Memory Backup & Sync

Security checks for vulnerabilities and agentic risk

Overview

This skill is a coherent memory backup tool, but it can automatically push sensitive memory files to a Git remote without reliable user confirmation.

Install only if you are comfortable with conversation memory, profile files, and workflow notes being committed to a user-configured Git remote. Use a private repository, a dedicated least-privilege SSH key, review diffs before every push, avoid cron until the script fails closed without approval, and do not rely on the built-in secret scanner as complete protection.

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 (5)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/memory-backup.sh:29
Finding
Shell Command Injection Through GIT_SSH_COMMAND<![CDATA[ ## Vulnerability Details **File Location**: `scripts/memory-backup.sh:29-40` **Vulnerability Type**: Shell command injection through environment-controlled command construction **Risk Level**: High ### Vulnerable Code ```bash # TODO: Replace with your SSH private key path MEMORY_BACKUP_KEY="${MEMORY_BACKUP_KEY:-~/.ssh/id_rsa}" # ---- SSH configuration (secure mode) ---- KNOWN_HOSTS="${HOME}/.ssh/known_hosts" export GIT_SSH_COMMAND="ssh -i ${MEMORY_BACKUP_KEY} -o IdentitiesOnly=yes -o UserKnownHostsFile=${KNOWN_HOSTS}" ``` ### Technical Analysis `MEMORY_BACKUP_KEY` and the path derived from `HOME` are interpolated into `GIT_SSH_COMMAND` without validation or shell-safe quoting. Git invokes the value of `GIT_SSH_COMMAND` through shell command parsing when it starts SSH. Consequently, a value containing shell syntax can alter the intended command. For example, if an attacker can control the backup process environment, a malicious `MEMORY_BACKUP_KEY` value containing a command separator can cause an additional command to execute when `git push` invokes SSH. Placing quotes inside the string is not a sufficient fix because embedded quotes and other shell constructs could still manipulate parsing. The underlying problem is treating untrusted data as part of an executable command string. ### Attack Path 1. An attacker gains the ability to set or influence `MEMORY_BACKUP_KEY` or `HOME` for the backup process, such as through an unsafe service configuration, CI variable, Agent-controlled environment, or wrapper script. 2. The attacker supplies shell metacharacters and a command in the affected value. 3. The user, Agent, or scheduled task runs `scripts/memory-backup.sh`. 4. The script exports the constructed `GIT_SSH_COMMAND`. 5. A staged change causes the script to execute `git push origin master`. 6. Git invokes the SSH command through shell parsing. 7. The injected command executes with the operating-system privileges of the backup process. ### Impac ...[truncated 449 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Do not construct an executable SSH command from unvalidated environment values. - Require `MEMORY_BACKUP_KEY` to be an explicitly configured absolute path. - Resolve the key and known-hosts paths canonically and verify that each points to an expected regular file. - Reject control characters, whitespace, quotes, command separators, substitutions, and option-like values. - Prefer a fixed SSH wrapper whose executable content is not derived from environment variables. Pass validated paths as positional parameters or through a tightly controlled configuration file. - Clear or strictly allowlist the environment when backups are started by an Agent, service, or scheduled task. - Run the backup under a dedicated unprivileged operating-system account. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/memory-backup.sh:70
Finding
Non-Interactive Execution Bypasses Push Confirmation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/memory-backup.sh:70-88` **Vulnerability Type**: Fail-open authorization for remote data upload **Risk Level**: High ### Vulnerable Code ```bash # ---- Confirmation before commit (interactive mode) ---- if [ -t 0 ]; then echo "[memory-backup] About to commit the following files:" git diff --cached --name-only | sed 's/^/ - /' echo "" read -p "[memory-backup] Confirm push? [y/N] " -r if [[ ! "$REPLY" =~ ^[Yy]$ ]]; then echo "[memory-backup] Cancelled." git reset HEAD exit 0 fi fi git commit -m "$MSG" git push origin master echo "[memory-backup] Backup pushed: ${MSG}" ``` ### Technical Analysis The confirmation prompt is executed only when standard input is attached to a terminal. When the script runs from an AI Agent, cron, CI pipeline, redirected process, or another non-interactive context, `[ -t 0 ]` is false and the script proceeds directly to commit and push. This behavior contradicts the Skill documentation's claim that the script pushes only after interactive confirmation. The check is fail-open: the context where confirmation cannot be obtained is treated as approval rather than refusal. The files staged by the script can include conversation memory, user-profile information, identity settings, personality configuration, workflow documents, and other persistent state. A non-interactive invocation can therefore transmit sensitive material without contemporaneous user review. ### Attack Path 1. `GIT_REMOTE` is configured, whether by the user or by an actor capable of influencing the execution environment. 2. Sensitive or private information is present in one of the tracked paths. 3. The backup script is invoked without a terminal, such as through `memory-sync.sh`, cron, an Agent tool, CI, or redirected standard input. 4. The terminal check evaluates to false. 5. No file list or confirmation prompt is presented to the user. 6. The script commits the staged files a ...[truncated 505 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Fail closed when no terminal is available. - Require an explicit authorization mechanism, such as a `--yes` flag supplied only after user approval or a short-lived approval token. - Separate staging, review, commit, and push into distinct operations. - Before approval, show both the staged file list and an appropriately redacted diff. - Make scheduled backups an explicit opt-in mode with a narrowly scoped file allowlist and independent secret scanning. - Validate the destination remote against a pinned, user-approved repository rather than silently accepting a changed environment value. - Document clearly that non-interactive backup is an external data transfer. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/memory-sync.sh:41
Finding
Incomplete Secret Detection Allows Credentials to Be Backed Up<![CDATA[ ## Vulnerability Details **File Locations**: `scripts/memory-sync.sh:41-57` and `scripts/memory-backup.sh:53-67` **Vulnerability Type**: Insufficient sensitive-data validation before remote upload **Risk Level**: High ### Vulnerable Code ```bash # scripts/memory-sync.sh SENSITIVE_PATTERNS=( "PRIVATE KEY" "-----BEGIN PRIVATE KEY-----" "-----BEGIN RSA PRIVATE KEY-----" "-----BEGIN OPENSSH PRIVATE KEY-----" "aws_access_key_id" "aws_secret_access_key" "password\s*=\s*['\"][^'\"]{8,}" ) for pattern in "${SENSITIVE_PATTERNS[@]}"; do if grep -iE "$pattern" "$INPUT_FILE" &>/dev/null; then echo "[memory-sync] Refused: file contains sensitive content pattern (${pattern})" echo "[memory-sync] Check the file and remove sensitive information before retrying" exit 1 fi done ``` ```bash # scripts/memory-backup.sh TRACKED_PATHS=( "MEMORY.md" "memory" "SOUL.md" "USER.md" "IDENTITY.md" "HEARTBEAT.md" ) for path in "${TRACKED_PATHS[@]}"; do if [ -e "$path" ]; then git add -A "$path" fi done ``` ### Technical Analysis The content scanner recognizes only a small set of private-key markers, AWS field names, and one narrowly formatted password assignment. It does not reliably detect many common secret forms, including: - Bearer tokens and session tokens - GitHub, GitLab, Slack, messaging, or cloud-provider tokens - Database connection strings containing credentials - Cookies and session identifiers - Passwords written in Markdown or formats other than the specific assignment expression - Client secrets, webhook secrets, recovery codes, or private data without recognizable labels - Encoded or multiline credentials More importantly, `memory-backup.sh` does not run this scanner against the actual staged Git content. A user or Agent can invoke the backup script directly, and all files under `memory/` plus several root-level profile files are staged without content inspection. Filename exclusions in `.gitignore` do not p ...[truncated 1230 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Scan the complete staged Git index immediately before every commit, rather than scanning only the input to `memory-sync.sh`. - Use a maintained secret-detection tool with entropy checks and provider-specific patterns. - Treat detection as defense in depth; do not represent it as a guarantee that files are safe. - Use a strict content and path allowlist for backup rather than recursively staging all of `memory/`. - Present a redacted staged diff and require explicit authorization before external transmission. - Prevent previously tracked sensitive files from bypassing ignore rules by checking `git ls-files` and the staged index. - Add repository-side secret scanning and push protection where supported. - If a secret is committed, revoke and rotate it immediately, then purge repository history and relevant mirrors. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/memory-sync.sh:22
Finding
Symbolic-Link Bypass Permits Reading Files Outside the Workspace<![CDATA[ ## Vulnerability Details **File Location**: `scripts/memory-sync.sh:22-77` **Vulnerability Type**: Path validation bypass through symbolic links **Risk Level**: High ### Vulnerable Code ```bash INPUT_FILE="${1:-}" # ---- Security validation: path checking ---- if [ -z "$INPUT_FILE" ] || [ ! -f "$INPUT_FILE" ]; then echo "Usage: bash scripts/memory-sync.sh <source-file>" echo "Example: bash scripts/memory-sync.sh /tmp/my-notes.md" exit 1 fi # Reject absolute paths if [[ "$INPUT_FILE" == /* ]]; then echo "[memory-sync] Refused: absolute paths are not allowed" exit 1 fi # Reject directory traversal if [[ "$INPUT_FILE" == *..* ]]; then echo "[memory-sync] Refused: path cannot contain .." exit 1 fi ``` ```bash { echo "# Automatically Synchronized Memory" echo echo "- Source file: ${INPUT_FILE}" echo "- Synchronization time: ${STAMP}" echo echo "## Original Content" echo cat "$INPUT_FILE" } > "$TARGET" ``` ### Technical Analysis The script validates only the textual form of the supplied path. A relative path without `..` passes the checks even if it is a symbolic link resolving to an absolute file outside `WORKDIR`. The `-f` test follows symbolic links, and the later `cat` operation also follows them. The script never resolves the canonical path, verifies containment under the workspace, or rejects symbolic links. Therefore, its stated protection against reading `/etc`, `/root`, and other external paths is incomplete. The copied content is written beneath `memory/channels/custom/`, after which `memory-backup.sh` is invoked automatically. This connects a local-file read primitive to a remote Git upload path. ### Attack Path 1. An attacker or compromised process with write access to the workspace creates a relative symlink, such as `notes.md`, pointing to a sensitive file readable by the Skill account. 2. The attacker causes the Agent or user to run `bash scripts/memory-sync.sh notes.md`. 3. The argument is relative, c ...[truncated 931 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Resolve both `WORKDIR` and the input with `realpath` or `realpath -e`. - Verify that the canonical input path is strictly contained beneath the canonical workspace path. - Reject symbolic links explicitly with `[ -L "$INPUT_FILE" ]`. - Open and validate the file in a manner resistant to check-to-use races; where practical, use a small helper that opens with `O_NOFOLLOW`. - Restrict accepted inputs to a dedicated import directory rather than the entire workspace. - Run the synchronization process as a dedicated unprivileged account. - Revalidate the file immediately before reading it and scan the actual copied output before backup. ]]>

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/memory-backup.sh:29
Finding
General-Purpose SSH Private Key Is Used as the Default Backup Identity<![CDATA[ ## Vulnerability Details **File Location**: `scripts/memory-backup.sh:29-30` **Vulnerability Type**: Violation of least privilege through an over-broad default credential **Risk Level**: Medium ### Vulnerable Code ```bash # TODO: Replace with your SSH private key path MEMORY_BACKUP_KEY="${MEMORY_BACKUP_KEY:-~/.ssh/id_rsa}" ``` ### Technical Analysis When `MEMORY_BACKUP_KEY` is unset, the script attempts to use the account's conventional general-purpose RSA private key. Such a key may authorize access to multiple repositories, servers, or administrative systems and is not necessarily scoped to the memory-backup repository. Using this identity is not required for the declared functionality. The setup guide already recommends a dedicated Ed25519 backup key, making the fallback inconsistent with the least-privilege design. The literal tilde in the parameter-expanded value may also fail to expand as intended, but that reliability defect does not remove the security risk of automatically selecting a broadly privileged identity when path handling permits it. The script does not modify or overwrite the private key. The risk is unauthorized or unintended use of a pre-existing identity, not direct key-file corruption. ### Attack Path 1. The backup is executed without an explicitly configured `MEMORY_BACKUP_KEY`. 2. The process account has a conventional `~/.ssh/id_rsa` identity. 3. The script selects that identity for Git SSH authentication. 4. A configured or modified Git remote causes the identity to be presented to an SSH endpoint. 5. The operation uses whatever repository or server permissions are attached to the general-purpose key rather than a repository-scoped backup identity. ### Impact Assessment The backup process receives the effective authentication scope of the general-purpose SSH key. This can exceed the single-repository write access needed for memory backup. The vulnerability does not reveal the private-key bytes by itself, and actual ...[truncated 184 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove the `~/.ssh/id_rsa` fallback and fail closed when no dedicated key is configured. - Require an explicit, canonical absolute path to a dedicated backup key. - Use a repository-scoped deploy key with only the minimum required permission. - Do not reuse personal, administrative, or server-login keys. - Verify secure ownership and permissions on the selected key before use. - Pin the approved Git remote and SSH host key. - Run backup operations under a dedicated unprivileged account whose SSH configuration contains only the backup identity. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
Findings (20)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
声明描述的是一个较完整的“记忆管理与同步”技能,包含写入、同步、备份、恢复和对话触发等能力。但提供的代码只是单一的 Git 备份脚本:追踪固定路径,提交并推送到 Git 远程仓库。虽然其中“通过 Git 推送到远程仓库备份”这一点与声明部分一致,但其余核心能力并未在代码中体现。代码也没有解析对话内容、自动写入记忆、恢复文件、或任何跨渠道接口/同步实现。因此描述明显宽于实际行为,存在实质性不匹配。

Missing User Warnings

High
Confidence
97% confidence
Finding
The description does not prominently warn that conversation content may be synchronized across channels and pushed to a remote Git repository, which is a significant data handling and exfiltration concern. Users may invoke the skill for local memory persistence without realizing the content could be replicated and transmitted off-host, including potentially sensitive cross-channel context.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
ls docs/<名称>-workflow.md 2>/dev/null && echo "旧版存在,需删除"

# 3. 确认新版内容已包含旧版所有有价值信息后,删除旧版
rm memory/<名称>-workflow.md
rm docs/<名称>-workflow.md

# 4. 推送备份
Confidence
95% confidence
Finding
The workflow includes a raw rm command using a templated path, which is dangerous because the substituted name may be wrong, ambiguous, or attacker-influenced, leading to unintended deletion. In a memory backup skill, file operations are part of the core behavior, so unsafe deletion guidance is more dangerous than in passive documentation because an agent or user may execute it during routine maintenance.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
# 3. 确认新版内容已包含旧版所有有价值信息后,删除旧版
rm memory/<名称>-workflow.md
rm docs/<名称>-workflow.md

# 4. 推送备份
bash scripts/memory-backup.sh
Confidence
95% confidence
Finding
This second rm command targets the docs path and has the same tool-parameter abuse risk: a templated filename can cause deletion of the wrong document or removal of legitimate files during migration. Because the skill promotes automatic backup/sync workflows, destructive commands embedded in the process can propagate operational mistakes and cause irreversible loss of documentation.

Credential Access

High
Category
Privilege Escalation
Content
GIT_REMOTE="${GIT_REMOTE:-}"

# TODO: 替换为你的 SSH 私钥路径
MEMORY_BACKUP_KEY="${MEMORY_BACKUP_KEY:-~/.ssh/id_rsa}"

# ---- 配置校验 ----
if [ -z "$GIT_REMOTE" ]; then
Confidence
90% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
fi

# ---- SSH 配置(安全模式)----
KNOWN_HOSTS="${HOME}/.ssh/known_hosts"
export GIT_SSH_COMMAND="ssh -i ${MEMORY_BACKUP_KEY} -o IdentitiesOnly=yes -o UserKnownHostsFile=${KNOWN_HOSTS}"

# ---- 确保 git remote 已配置 ----
Confidence
90% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
exit 1
fi

# 拒绝目录遍历(防止 ../etc/passwd 这类路径)
if [[ "$INPUT_FILE" == *..* ]]; then
  echo "[memory-sync] 拒绝:路径不能包含 .. (目录遍历)"
  exit 1
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
exit 1
fi

# 拒绝目录遍历(防止 ../etc/passwd 这类路径)
if [[ "$INPUT_FILE" == *..* ]]; then
  echo "[memory-sync] 拒绝:路径不能包含 .. (目录遍历)"
  exit 1
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Vague Triggers

Medium
Confidence
95% confidence
Finding
Allowing the skill to 'proactively' persist memory after 'important conversations' creates an ambiguous, agent-defined activation boundary for a data-exporting workflow. Because the skill stores conversation data and can push it to Git, vague autonomous triggering materially increases the risk of silent collection, retention, and remote disclosure without informed user approval.

Vague Triggers

Medium
Confidence
91% confidence
Finding
Allowing the skill to 'proactively' persist memory after 'important conversations' creates an ambiguous, agent-defined activation boundary for a data-exporting workflow. Because the skill stores conversation data and can push it to Git, vague autonomous triggering materially increases the risk of silent collection, retention, and remote disclosure without informed user approval.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The document explicitly states that core memory files are automatically backed up to a remote Git repository every day, but it does not require informed user consent, destination transparency, or a warning about privacy consequences. In the context of a memory backup skill that stores conversation-derived notes, this can lead to unintentional exfiltration of personal, project, or sensitive contextual data to external infrastructure.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
This guide operationalizes automatic backup of conversation-derived memory files to a remote Git repository, but its warning only mentions API keys and passwords. In this skill's context, the memory store is likely to contain personal data, confidential workflow notes, and cross-channel conversation content, so encouraging routine remote sync without strong data-classification, minimization, or encryption guidance creates a real privacy and data-exfiltration risk.

Session Persistence

Medium
Category
Rogue Agent
Content
```bash
# 编辑 crontab
crontab -e

# 每天早上 9 点自动备份
0 9 * * * cd /root/.openclaw/workspace && bash scripts/memory-backup.sh >> /root/.openclaw/logs/backup.log 2>&1
Confidence
85% confidence
Finding
The cron-based scheduled backup creates persistent, unattended exfiltration of memory contents to a remote repository. In the context of a memory-backup skill, this increases risk because newly stored sensitive conversation content may be pushed automatically without human review, and the log redirection may also leave traces of backup activity or errors on disk.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The document instructs operators to run destructive rm commands as part of a normal backup workflow, but it lacks explicit safety warnings, path validation steps, or safer alternatives. In an agent skill that may operationalize shell instructions, this creates a realistic risk of accidental data loss if filenames are mistyped, expanded unexpectedly, or applied to the wrong file.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The recovery phrase "从备份继续" is broad and can trigger loading and acting on backed-up workflow content without clear confirmation, scope checks, or exclusions. In a memory/backup skill, that increases the chance of unintended restoration of stale, sensitive, or adversarially planted instructions across conversations and channels.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The header comments, usage text, and operational messages are written only in Chinese, which imposes a specific language/locale on users. Under the policy, locale constraints should either offer user choice or be clearly documented as justified for a region-specific tool, which is not present here.

Natural-Language Policy Violations

Low
Confidence
76% confidence
Finding
SQP-3 applies to all file types and includes language or locale policy violations. This setup guide is entirely Chinese and does not indicate that other languages are supported or that Chinese is a justified region-specific requirement, which can be interpreted as forcing a language without user opt-in.

Natural-Language Policy Violations

Low
Confidence
83% confidence
Finding
The file is written as an instruction guide entirely in Chinese and provides a fixed Chinese recovery phrase, but it does not indicate that language selection is optional or limited to a China-specific context. This can constitute a locale-policy issue when a skill effectively forces one language without user opt-in.

Natural-Language Policy Violations

Low
Confidence
94% confidence
Finding
The script's descriptive comments, usage guidance, environment variable explanations, and later user-facing prompts are written only in Chinese. Under the policy, forcing a specific language without offering a choice or documenting a justified locale constraint is a natural-language policy violation.

Intent-Code Divergence

Low
Confidence
97% confidence
Finding
The inline documentation at L26 presents `/tmp/my-notes.md` as an example source file, while the enforced validation at L31-L35 rejects all absolute paths. This is an active contradiction between the script's documented usage and its actual behavior, which can mislead operators about what inputs are permitted.

Static analysis

No suspicious patterns detected.