Back to skill

Security audit

Openclaw Migrate

Security checks for vulnerabilities and agentic risk

Overview

This migration skill has a coherent purpose, but it needs review because its scripts can expose sensitive agent data, overwrite repositories or local state, and execute restore code from a supplied GitHub repository.

Review before installing or running. Use only trusted private repositories, inspect any restore.sh before execution, avoid --pull from untrusted or mutable repos, avoid --full unless session history is intended to move, sanitize and rotate credentials, and do not let the script force-push to repositories with important history.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (4)

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/sync-github.sh:158
Finding
Unverified Remote Restore Script Execution<![CDATA[ ## Vulnerability Details **File Location**: `scripts/sync-github.sh:158-162` **Vulnerability Type**: `T03: Remote Payload Retrieval and Execution` **Risk Level**: Critical ### Vulnerable Code ```bash git clone "$REPO_URL" "$TEMP_DIR/repo" cd "$TEMP_DIR/repo/agent-backup" ./restore.sh ``` ### Technical Analysis The pull workflow accepts a repository URL from the command line, clones the repository, and immediately executes the repository-provided `agent-backup/restore.sh` script. The repository is not restricted to an approved owner or location. The script also performs no commit pinning, cryptographic signature verification, checksum verification, content validation, or interactive confirmation before execution. Consequently, the effective executable payload can be modified after this skill has been reviewed or installed. Although the push workflow creates a legitimate restore script, the pull workflow does not verify that the cloned script is the version generated by this project. Any repository with the expected directory and file structure can provide an arbitrary executable payload. ### Attack Path 1. An attacker creates a Git repository containing `agent-backup/restore.sh`. 2. The malicious restore script contains commands for credential theft, persistence, destructive operations, or arbitrary code execution. 3. The attacker convinces a user or agent to run: ```bash scripts/sync-github.sh <attacker-controlled-repository> --pull ``` 4. The script clones the repository into a temporary directory. 5. It changes into the repository-controlled `agent-backup` directory. 6. It executes `./restore.sh` without validating its origin or contents. 7. The malicious commands run with all privileges available to the user invoking the migration script. The same exploitation path applies if an otherwise trusted backup repository or its associated credentials are compromised. ### Impact Assessment An attacker can obtain arbitrary command execut ...[truncated 617 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Do not execute any script obtained from the cloned repository. - Implement restoration entirely through trusted local code shipped with this project. - Treat repository contents strictly as data and restore only an explicit allowlist of expected files. - Validate file types, names, ownership, permissions, symbolic links, and destination paths before copying data. - Restrict synchronization to explicitly approved repository owners and URLs. - Pin restoration to a known commit and verify its cryptographic signature or a trusted out-of-band checksum. - Require explicit user confirmation that displays the repository URL, commit identifier, and files to be restored. - Run restoration under a dedicated, least-privileged account. - If execution of a downloaded script is unavoidable, display and validate the script, isolate it in a sandbox, deny network access, and limit filesystem access before execution. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/sync-github.sh:72
Finding
Ineffective Credential Redaction Before Repository Upload<![CDATA[ ## Vulnerability Details **File Location**: `scripts/sync-github.sh:72-78` **Vulnerability Type**: `T09: Insecure Skill Coding Practices` **Risk Level**: High ### Vulnerable Code ```bash if [ -f "/home/node/.openclaw/openclaw.json" ]; then jq 'walk(if type == "object" then with_entries(if .value | type == "string" and (contains("key") or contains("token") or contains("secret")) then .value = "***REMOVED***" else . end) else . end)' "/home/node/.openclaw/openclaw.json" > agent-backup/openclaw.json.template 2>/dev/null || \ echo "{}" > agent-backup/openclaw.json.template fi ``` ### Technical Analysis The code claims to create a sanitized configuration template, but its `jq` expression examines string values rather than object key names. For example, a configuration entry such as: ```json { "apiKey": "sk-example-opaque-value", "gatewayToken": "9f3a7c..." } ``` will not be redacted unless the secret value itself happens to contain the lowercase literal text `key`, `token`, or `secret`. Real credentials are commonly opaque strings and therefore will generally remain unchanged. The checks are also case-sensitive and cover only three literal terms. Passwords, authorization headers, cookies, private keys, client secrets, and credentials under differently named fields can remain in the generated template. The resulting file is subsequently staged, committed, and pushed to the selected repository. ### Attack Path 1. `/home/node/.openclaw/openclaw.json` contains an API key, gateway token, password, or other opaque credential. 2. The user runs the GitHub synchronization workflow in push mode. 3. The `jq` expression checks whether the credential value contains one of three lowercase words. 4. The opaque credential does not contain those words and is copied unchanged into `agent-backup/openclaw.json.template`. 5. `git add -A` stages the generated template. 6. The script commits and pushes the file to the supplied remo ...[truncated 813 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Redact values based primarily on normalized key names, not on whether values contain sensitive words. - Use a case-insensitive denylist covering names such as `key`, `token`, `secret`, `password`, `credential`, `authorization`, `cookie`, `privateKey`, and `clientSecret`. - Prefer an allowlist that emits only configuration fields known to be safe and necessary for restoration. - Replace nested sensitive objects in their entirety where their schema is not explicitly understood. - Add a secret scanner before `git add` and abort synchronization if likely credentials are detected. - Show the exact staged files and require confirmation before committing or pushing. - Never assume that a private repository is a secure secret-storage mechanism. - If credentials have already been pushed, revoke and rotate them immediately, then purge them from repository history and all mirrors or clones. - Add automated tests containing representative opaque tokens to verify that generated templates never retain them. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/export-agent.sh:24
Finding
Plaintext Export of Sensitive Agent Configuration<![CDATA[ ## Vulnerability Details **File Location**: `scripts/export-agent.sh:24-26` **Vulnerability Type**: `T09: Insecure Skill Coding Practices` **Risk Level**: High ### Vulnerable Code ```bash echo " → 导出配置..." mkdir -p "$EXPORT_DIR/config" cp /home/node/.openclaw/openclaw.json "$EXPORT_DIR/config/" 2>/dev/null || true ``` ### Technical Analysis The export workflow copies the complete `openclaw.json` configuration into a plaintext directory under `/tmp`. No sanitization, encryption, restrictive file permissions, or explicit confirmation is applied. The project documentation warns users to sanitize the configuration, but the script does not enforce that requirement. Documentation alone does not prevent credentials from being included in the generated archive. The export directory is created without a restrictive `umask` or explicit permission mode. Depending on the user's environment and default permissions, other local users may be able to inspect files or directory contents. The sensitive configuration is also included in the final portable archive, increasing the number of locations and transfer channels through which it may be exposed. ### Attack Path 1. The OpenClaw configuration contains API keys, gateway tokens, passwords, or other credentials. 2. The user runs `scripts/export-agent.sh`. 3. The script copies the complete configuration into `/tmp/agent-export-<name>/config/openclaw.json`. 4. The export directory is packaged into `/tmp/agent-export-<name>.tar.gz`. 5. The plaintext configuration may be exposed to another local user, an unintended archive recipient, insecure transfer infrastructure, backup software, or artifact retention systems. 6. An attacker extracts the archive and obtains the embedded credentials. ### Impact Assessment Exposure is limited to the privileges represented by credentials and sensitive data stored in `openclaw.json`, but may include: - Unauthorized gateway access. - Abuse of model provider API keys and resultin ...[truncated 343 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Exclude credentials and other secrets from exports by default. - Generate a safe configuration template using a strict allowlist of non-sensitive fields. - Require a clearly named explicit option before including secrets, accompanied by a prominent warning and confirmation. - Set `umask 077` at the beginning of the script. - Create export directories with mode `0700` and sensitive files with mode `0600`. - Encrypt sensitive exports using a recipient-controlled public key or a modern authenticated encryption mechanism. - Avoid retaining sensitive plaintext files under `/tmp`; securely remove temporary material after packaging. - Verify destination ownership and permissions before writing the export. - Provide an export manifest that clearly indicates whether credentials are included. - Add a pre-export secret scan and fail closed when sanitization cannot be completed safely. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/sync-github.sh:146
Finding
Automatic Destructive Force Push to Remote Repository<![CDATA[ ## Vulnerability Details **File Location**: `scripts/sync-github.sh:146-150` **Vulnerability Type**: `T09: Insecure Skill Coding Practices` **Risk Level**: High ### Vulnerable Code ```bash git push origin HEAD:main 2>/dev/null || git push origin HEAD:master 2>/dev/null || { echo " 尝试强制推送..." git push --force origin HEAD:main 2>/dev/null || git push --force origin HEAD:master 2>/dev/null } ``` ### Technical Analysis If normal pushes to both `main` and `master` fail, the script automatically falls back to `git push --force`. A normal push can fail for many non-malicious and recoverable reasons, including divergent history, stale local state, concurrent updates, or selection of the wrong target branch. None of these conditions establish that overwriting remote history is safe. The script does not fetch and reconcile remote changes, inspect branch ownership, use `--force-with-lease`, create a backup reference, or request user confirmation. Because the repository URL is supplied by the caller, the script may also be pointed at a repository containing unrelated or important history. If the invoking credentials permit force pushes, the fallback can replace that history with the temporary backup repository state. ### Attack Path 1. A target repository contains commits that are not present in the temporary local repository. 2. The user runs the synchronization script in push mode. 3. The normal push fails because it would be non-fast-forward or because the local history diverges. 4. The script automatically invokes `git push --force`. 5. If branch permissions allow the operation, the remote branch is reset to the local temporary repository commit. 6. Existing commits become unreachable from the overwritten branch and may be lost from ordinary workflows, automated deployments, or retention processes. An attacker could increase the likelihood of this outcome by supplying a repository URL with divergent history or by racing the synchronization pr ...[truncated 716 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove all automatic `--force` push fallbacks. - Fetch remote branches and determine the actual default branch before pushing. - Reconcile divergent history through an explicit merge, rebase, or a separate backup branch. - Push backups to a dedicated namespaced branch rather than overwriting `main` or `master`. - Require explicit user confirmation before any history-rewriting operation. - If force pushing is an intentional, exceptional operation, use `--force-with-lease` with an expected commit identifier. - Create and verify a remote backup reference before modifying an existing branch. - Display the repository URL, target branch, remote head, and planned changes before the push. - Encourage branch protection rules that prohibit force pushes to primary branches. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (14)

Tool Parameter Abuse

High
Category
Tool Misuse
Content
echo "  → 推送到远程..."
    git push origin HEAD:main 2>/dev/null || git push origin HEAD:master 2>/dev/null || {
        echo "  尝试强制推送..."
        git push --force origin HEAD:main 2>/dev/null || git push --force origin HEAD:master 2>/dev/null
    }
    
    echo "[SYNC] ✅ 推送完成"
Confidence
98% confidence
Finding
Using git push --force as an automatic fallback can overwrite remote history and destroy existing repository contents, especially if the provided REPO_URL points to a non-empty or shared repository. In this script's context, the risk is amplified because the repository is user-supplied and the force-push happens after a normal push failure, with no interactive confirmation or safety validation.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The README explicitly advertises exporting the agent's full state and synchronizing it to a GitHub repository, but it provides no warning that the exported state may contain secrets, tokens, credentials, conversation history, or other sensitive operational data. In the context of a migration skill, users are likely to run these commands as documented, so the omission materially increases the risk of unintended data exfiltration or privacy leakage, especially if repository configuration or access controls are incorrect.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The skill documents `--replace` import and rollback behavior that can wipe an existing agent state, but it does not prominently warn about irreversible data loss, backup requirements, or verification steps before execution. In an operational migration skill, users may copy commands directly, so the omission increases the chance of accidental destructive use rather than requiring deliberate confirmation.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The GitHub sync workflow encourages pushing agent state to a remote repository without an explicit warning that the exported workspace may contain identity files, memory, configuration, session data, extensions, or secrets. Because this skill is specifically about migrating full agent state across environments, transmitting that state over GitHub without strong scoping and sanitization guidance creates a real risk of credential leakage, privacy exposure, and persistent compromise.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The guide instructs users to expose a gateway service on port 18789 and to provide authentication tokens and API keys, but it does not warn about restricting network exposure, protecting secrets, or the risks of mounting sensitive workspace data into the container. In deployment documentation, this omission can lead users to run an internet-reachable service with weak operational safeguards, increasing the chance of unauthorized access or secret leakage.

Rp1

Medium
Category
MCP Rug Pull
Confidence
75% confidence
Finding
Docker image references without a specific tag (:latest is implicit) or digest (@sha256:...) can be silently replaced by a malicious image.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
In full mode, the script archives the entire agents/session data tree into a transferable tarball without any warning, review step, or redaction. Session data commonly contains prompts, outputs, credentials, tokens, or other sensitive operational context, so users may exfiltrate secrets unintentionally when sharing the export.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The generated restore script extracts archives and copies configuration directly into the target directory, overwriting existing files without confirmation or backup. This can cause destructive loss of local state or replacement of trusted configuration/code with exported content, which is especially risky when the archive origin is not fully trusted.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script collects local agent identity files, memory data, installed skill inventory, custom skills, and configuration templates, then pushes them to a remote GitHub repository without a prominent, explicit consent screen describing exactly what leaves the machine. In a skill context, this is dangerous because these files may contain sensitive prompts, private memories, operational details, or embedded secrets, and users may not realize the scope of exfiltration.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The comment at L059 says the backup stores only installed skill names and not content, but the subsequent section at L063-L067 copies custom .skill files into the backup. This is an active contradiction in the file's own documentation about what data is being synchronized.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The pull path clones remote content and immediately executes restore.sh, which writes files into the user's .openclaw directory without a clear warning in the main script that local state will be modified. This is risky because a user invoking pull may not expect overwrites or trust-boundary crossing from remote repository content into their local agent configuration.

Natural-Language Policy Violations

Low
Confidence
94% confidence
Finding
SQP-3 applies to all file types and covers language or locale policy violations. This file presents all instructions in Chinese only, with no opt-in, alternative language, or justification that the skill is region- or locale-specific.

Natural-Language Policy Violations

Low
Confidence
98% confidence
Finding
User-facing messages and comments are written in Chinese throughout the script, with no opt-in or alternative locale handling. This can violate language/locale policy when a skill imposes a specific language on users without documented justification or a user choice.

Natural-Language Policy Violations

Low
Confidence
98% confidence
Finding
The script's comments, usage output, status messages, and restore guidance are consistently presented in Chinese only. This imposes a specific language on users without offering a choice or documenting a locale-specific constraint.

Static analysis

No suspicious patterns detected.