Back to skill

Security audit

OpenClaw GitHub Backup

Security checks for vulnerabilities and agentic risk

Overview

This backup skill has a coherent purpose, but it can upload broad private OpenClaw data and makes risky Git/SSH changes that could expose secrets or lose backup history.

Review carefully before installing. Use only a dedicated empty private repository, inspect exactly what ~/.openclaw would stage, and avoid running the installer unchanged unless you accept broad backup of private agent data. Safer changes would remove recursive .git deletion and all force-pushes, use a file allowlist, encrypt or secret-scan backups, avoid global Git config, and require explicit consent before any SSH key or known_hosts modification.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (5)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/backup.sh:24
Finding

Broad backup scope uploads sensitive OpenClaw data with incomplete sanitization

Content
View full analysis
"$output" log_info "配置文件已脱敏" else log_error "配置文件不存在: $input" return 1 fi } do_backup() { cd "$OPENCLAW_DIR" log_info "开始备份 OpenClaw..." if [[ -z $(git status --porcelain 2>/dev/null) ]]; then log_info "没有变更需要备份" return 0 fi if [[ -f "openclaw.json" ]]; then cp openclaw.json openclaw.json.original sanitize_config "openclaw.json.original" "openclaw.json.staged" mv openclaw.json.staged openclaw.json fi git add -A local timestamp=$(date '+%Y-%m-%d %H:%M:%S') git commit -m "Auto backup: $timestamp" log_info "已提交备份: $timestamp" git push origin "$BACKUP_BRANCH" 2>/dev/null || { log_warn "推送失败,尝试强制推送..." git push origin "$BACKUP_BRANCH" --force } log_info "已推送到 GitHub" if [[ -f "openclaw.json.original" ]]; then mv openclaw.json.original openclaw.json log_info "已恢复原始配置" fi } ``` The installer uses the same unsafe pattern: ```bash if [[ -f "openclaw.json" ]]; then cp openclaw.json openclaw.json.original sed -E 's/"apiKey": "[^"]+"/"apiKey": "***SET_YOUR_API_KEY***"/g' openclaw.json.original > openclaw.json.staged mv openclaw.json.staged openclaw.json fi git add -A ``` ### Technical Analysis The scripts initialize `~/.openclaw` as a Git repository and execute `git add -A`, thereby staging every file not covered by the minimal `.gitignore`. According to `SKILL.md`, the intended backu ...[truncated 2248 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/install.sh:159
Finding

Recursive deletion destroys Git metadata throughout the OpenClaw directory

Content
View full analysis
/dev/null || true ``` This operation is invoked after the installer initializes the root repository: ```bash init_git() { log_step "初始化 Git 仓库..." cd "$OPENCLAW_DIR" if [[ -d ".git" ]]; then log_warn "Git 仓库已存在,更新远程地址..." git remote set-url origin "$REPO_URL" 2>/dev/null || git remote add origin "$REPO_URL" else git init git branch -M main git remote add origin "$REPO_URL" log_info "Git 仓库已初始化" fi } ``` ### Technical Analysis The `find` command recursively locates every directory named `.git` beneath `~/.openclaw` and permanently deletes it with `rm -rf`. This includes nested workspace repositories and the root `~/.openclaw/.git` directory that `init_git` just created or reused. A `.git` directory contains commit history, branches, tags, remotes, configuration, staging state, reflogs, and references to unpushed work. Deleting it converts the working tree into ordinary files and can permanently destroy repository state. The `|| true` suffix suppresses errors, making partial deletion less visible. Because the root repository may also be removed, subsequent `git add`, `git commit`, and `git push` operations can fail after destructive changes have already occurred. ### Attack Path 1. The user has one or more Git repositories under `~/.openclaw`, potentially containing unpushed work. 2. The installer initializes or reconfigures `~/.openclaw/.git`. 3. `first_backup` executes the recursive `find` command. 4. Every discovered `.git` directory is passed to `rm -rf`. 5. Root and nested repository histories, branches, remotes, and refl ...[truncated 526 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/backup.sh:121
Finding

Automatic force-push can overwrite remote backup history

Content
View full analysis
/dev/null || { log_warn "推送失败,尝试强制推送..." git push origin "$BACKUP_BRANCH" --force } ``` The initial installation also force-pushes unconditionally: ```bash if git push -u origin main --force; then log_info "已推送到 GitHub" else log_error "推送失败,请检查仓库地址和权限" exit 1 fi ``` ### Technical Analysis The routine backup treats every normal push failure as justification for a force-push. Pushes can fail because of divergence, concurrent updates, stale local state, branch protection, authentication problems, network errors, or an incorrect remote. Automatically retrying with `--force` is not a safe recovery procedure. The installation path uses `--force` for its first push regardless of whether the remote branch already contains commits. This can replace legitimate remote history without first fetching or confirming the intended action. Unlike `--force-with-lease`, plain `--force` does not verify that the remote branch still points to the expected commit. ### Attack Path 1. The remote `main` branch contains commits absent from the local repository. 2. A normal push is rejected as non-fast-forward. 3. The script automatically retries using `--force`. 4. The remote branch reference is moved to the local commit. 5. Remote-only commits disappear from the visible branch history and may eventually become unrecoverable. 6. In a shared or automated repository, concurrent backup data can consequently be lost. ### Impact Assessment The affected scope is the configured remote branch. The script can overwrite backup history and discard commits created by other systems or users. This causes integrity and availability loss and may eliminate historical recovery points. ]]>
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/install.sh:37
Finding

Installer creates an unencrypted SSH private key and trusts unverified host-key data

Content
View full analysis
&1 | grep -q "successfully authenticated"; then log_info "GitHub SSH 连接正常" return 0 else log_warn "SSH Key 可能未添加到 GitHub" echo "请将以下公钥添加到 GitHub → Settings → SSH Keys:" cat ~/.ssh/id_ed25519.pub 2>/dev/null || cat ~/.ssh/id_rsa.pub 2>/dev/null echo "" read -p "已添加到 GitHub?继续安装?(y/n) " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then exit 1 fi fi else log_warn "未找到 SSH Key,正在生成..." ssh-keygen -t ed25519 -C "openclaw-backup" -f ~/.ssh/id_ed25519 -N "" log_info "SSH Key 已生成" echo "" echo "请将以下公钥添加到 GitHub → Settings → SSH Keys:" cat ~/.ssh/id_ed25519.pub echo "" read -p "已添加到 GitHub?继续安装?(y/n) " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then exit 1 fi fi # 添加 GitHub 到 known_hosts ssh-keyscan github.com >> ~/.ssh/known_hosts 2>/dev/null } ``` ### Technical Analysis Reading and displaying `id_ed25519.pub` or `id_rsa.pub` accesses only public-key material and is reasonably related to configuring GitHub SSH authentication. The script does not read or print an existing private key. However, when no expected public key is found, it creates `~/.ssh/id_ed25519` with `-N ""`, producing a private key without a passphrase. It uses a fixed default identity path rather than a dedicated Skill-specific path or a user-selected SSH agent identity. This modifies credential-related state beyo ...[truncated 1600 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/install.sh:102
Finding

Installer unnecessarily changes global Git identity

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
Findings (25)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.md (reported line 28)May include surrounding context.

md
### 1. Prerequisites

- Git installed
- GitHub SSH Key configured (recommended) or Personal Access Token
- GitHub private repository created (e.g., `openclaw-backup`)

### 2. Install Skill

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
93% confidence
Finding

The troubleshooting guidance suggests using git push origin main --force, which can overwrite repository history and destroy prior backups. In a backup skill, this is especially dangerous because users may erase good restore points or unintentionally replace remote state with incomplete or sanitized-but-broken local state.

Content

Scanner excerpt · SKILL.md (reported line 143)May include surrounding context.

ssh -T git@github.com

Force push (use with caution)

cd ~/.openclaw && git push origin main --force

text

### Configuration Lost After Restore

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
97% confidence
Finding

The hardcoded use of 'git push origin "$BACKUP_BRANCH" --force' enables a destructive remote operation without validating branch state, remote expectations, or obtaining explicit consent. In the context of a backup skill, this can erase trusted history and turn a recovery mechanism into a data-loss event if local state is stale, corrupted, or manipulated.

Content

Scanner excerpt · scripts/backup.sh (reported line 112)May include surrounding context.

sh
git push origin "$BACKUP_BRANCH" 2>/dev/null || {
        log_warn "推送失败,尝试强制推送..."
        git push origin "$BACKUP_BRANCH" --force
    }
    log_info "已推送到 GitHub"

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/install.sh (reported line 40)May include surrounding context.

sh
check_ssh_key() {
    log_step "检查 SSH Key..."
    
    if [[ -f ~/.ssh/id_ed25519.pub ]] || [[ -f ~/.ssh/id_rsa.pub ]]; then
        log_info "已找到 SSH Key"
        
        # 测试 GitHub 连接

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/install.sh (reported line 50)May include surrounding context.

sh
check_ssh_key() {
    log_step "检查 SSH Key..."
    
    if [[ -f ~/.ssh/id_ed25519.pub ]] || [[ -f ~/.ssh/id_rsa.pub ]]; then
        log_info "已找到 SSH Key"
        
        # 测试 GitHub 连接

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/install.sh (reported line 64)May include surrounding context.

sh
check_ssh_key() {
    log_step "检查 SSH Key..."
    
    if [[ -f ~/.ssh/id_ed25519.pub ]] || [[ -f ~/.ssh/id_rsa.pub ]]; then
        log_info "已找到 SSH Key"
        
        # 测试 GitHub 连接

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/install.sh (reported line 40)May include surrounding context.

sh
check_ssh_key() {
    log_step "检查 SSH Key..."
    
    if [[ -f ~/.ssh/id_ed25519.pub ]] || [[ -f ~/.ssh/id_rsa.pub ]]; then
        log_info "已找到 SSH Key"
        
        # 测试 GitHub 连接

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/install.sh (reported line 50)May include surrounding context.

sh
check_ssh_key() {
    log_step "检查 SSH Key..."
    
    if [[ -f ~/.ssh/id_ed25519.pub ]] || [[ -f ~/.ssh/id_rsa.pub ]]; then
        log_info "已找到 SSH Key"
        
        # 测试 GitHub 连接

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

Automatically generating an SSH keypair alters the user's authentication environment and creates long-lived credentials without strong scoping or explicit explanation of lifecycle and storage implications. In the context of a backup installer, this is more intrusive than necessary and can lead to unmanaged credentials being added to the user's GitHub account.

Content

Scanner excerpt · scripts/install.sh (reported line 60)May include surrounding context.

sh
fi
    else
        log_warn "未找到 SSH Key,正在生成..."
        ssh-keygen -t ed25519 -C "openclaw-backup" -f ~/.ssh/id_ed25519 -N ""
        log_info "SSH Key 已生成"
        echo ""
        echo "请将以下公钥添加到 GitHub → Settings → SSH Keys:"

Credential Access

High
Category
Privilege Escalation
Confidence
92% confidence
Finding

Appending ssh-keyscan github.com output directly to ~/.ssh/known_hosts blindly trusts a network-retrieved host key without verification. This weakens SSH trust-on-first-use protections and could permit a man-in-the-middle to seed a malicious host key if the network path is compromised.

Content

Scanner excerpt · scripts/install.sh (reported line 74)May include surrounding context.

sh
fi
    
    # 添加 GitHub 到 known_hosts
    ssh-keyscan github.com >> ~/.ssh/known_hosts 2>/dev/null
}

# 获取配置

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The command find . -name ".git" -type d -exec rm -rf {} + recursively deletes every nested Git metadata directory under ~/.openclaw. This is destructive and not necessary for normal backup setup; it can irreversibly remove version history from embedded repos or any nested project content living under that directory.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The installer performs git push --force on the target repository during first backup, which can overwrite remote history and destroy existing data if the user points to a non-empty or wrong repository. This is especially risky because the script does not provide a destructive-operation warning or verify that the remote is empty and intended for replacement.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

Force-pushing without an explicit destructive warning or confirmation creates a significant risk of accidental remote data loss. In a backup skill, users may reasonably expect additive behavior, not history replacement, so the context makes this more dangerous rather than less.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
99% confidence
Finding

Using git push -u origin main --force is a dangerous parameter choice because it turns a normal backup operation into a potentially destructive overwrite of the remote branch. In a backup context this is especially hazardous, since a mistaken repo URL or non-empty destination can lead to immediate loss of prior backup history.

Content

Scanner excerpt · scripts/install.sh (reported line 192)May include surrounding context.

sh
fi
    
    # 推送
    if git push -u origin main --force; then
        log_info "已推送到 GitHub"
    else
        log_error "推送失败,请检查仓库地址和权限"

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill instructs users to run shell commands and install scripts that read and write files, but it does not declare any explicit tool scope or permissions. This weakens reviewability and consent, making it easier for a skill with filesystem and shell capabilities to perform broader actions than a user may expect.

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 · SKILL.md (reported line 37)May include surrounding context.

bash
# Ensure skills directory exists
mkdir -p ~/.openclaw/workspace/skills

# Copy skill (assuming downloaded to current directory)
cp -r openclaw-backup ~/.openclaw/workspace/skills/

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill claims API key sanitization, but the backup scope includes agent histories, workspaces, memory databases, credentials, and collaboration configuration directories that may still contain tokens, personal data, or other secrets in unsanitized form. Backing these into GitHub, even privately, creates a concentrated secret store and raises the risk of accidental disclosure, account compromise, or privacy exposure.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The description mentions backup to a private GitHub repository but does not clearly warn that configuration data will be transmitted off-system to a third-party service. Because configuration backups may include sensitive operational details, tokens, endpoints, or other secrets despite sanitization claims, insufficient disclosure increases the risk of users enabling data exfiltration they did not fully understand.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

If the normal push fails, the script automatically retries with 'git push --force' and only emits a generic warning. Force-pushing can overwrite remote history and destroy backups or collaborators' changes, which is especially risky in a backup tool where integrity and retention are the primary goals.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest claims 'One-click recovery support', suggesting the skill can directly restore configuration. In code, the restore command merely echoes a sequence of manual steps for the user to perform, which contradicts that stated capability rather than implementing it.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

User-facing comments, prompts, and status messages throughout the installer are in Chinese, and the script provides no alternative language selection. This can violate language/locale policy when a skill forces a specific language without user opt-in or documented justification.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · scripts/install.sh (reported line 28)May include surrounding context.

sh
if ! command -v git &>/dev/null; then
        log_error "未安装 Git,请先安装:"
        echo "  Ubuntu/Debian: sudo apt install git"
        echo "  macOS: brew install git"
        exit 1
    fi

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The installer inspects existing SSH keys, tests GitHub SSH authentication, may generate a new SSH keypair, and appends host keys to known_hosts. These actions are broader than a simple backup install and touch sensitive authentication material and trust configuration, increasing the blast radius if the script behaves unexpectedly or is modified.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The installer changes the user's global Git identity with git config --global, affecting all repositories on the system rather than only this backup repo. That exceeds the stated backup scope and can cause unintended commits elsewhere to be attributed to the wrong identity, which is a cross-context side effect users may not expect.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The manifest description says the skill will 'Automatically backup OpenClaw configuration' but does not describe any user-visible trigger, scope restriction, or consent boundary. For a skill that handles configuration data and uploads it externally, broad auto-activation language can lead to unexpected execution and unintended data transmission, even if the implementation is not overtly malicious.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.