Back to skill

Security audit

Backup & Restore

Security checks for vulnerabilities and agentic risk

Overview

This is a real backup and restore skill, but its scripts can expose OpenClaw credentials through unsafe plaintext backup and restore handling, so it needs review before use.

Install only if you are comfortable with a backup tool that can read all OpenClaw data, store reusable secrets, schedule recurring jobs, and upload archives to configured cloud services. Before using it, keep encryption enabled, avoid portable/unencrypted full backups, protect all credential files with strict permissions, use least-privilege cloud identities, and restore only archives you trust.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (6)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/backup.sh:35
Finding
Portable mode is ignored, allowing credentials to be included in plaintext backups<![CDATA[ ## Vulnerability Details **File Location**: `scripts/backup.sh:35-39, 92-110`; related documentation at `references/setup-guide.md:31-45` **Vulnerability Type**: Configuration enforcement failure and plaintext sensitive-data exposure **Risk Level**: High ### Vulnerable Code ```bash ENCRYPT="${BACKUP_ENCRYPT:-$(read_config encrypt)}" ENCRYPT="${ENCRYPT:-true}" RETAIN_DAYS="${BACKUP_RETAIN_DAYS:-$(read_config retainDays)}" RETAIN_DAYS="${RETAIN_DAYS:-30}" ``` ```bash # --------------------------------------------------------------------------- # 1. Full backup (encrypted) # --------------------------------------------------------------------------- FULL_NAME="openclaw-${HOSTNAME_SHORT}-${TIMESTAMP}-full.tar.gz" FULL_PATH="$BACKUP_DIR/$FULL_NAME" log "Creating full backup..." tar czf "$FULL_PATH" -C "$HOME" .openclaw/ log "Full archive: $FULL_PATH ($(du -h "$FULL_PATH" | cut -f1))" if [[ "$ENCRYPT" == "true" ]]; then log "Encrypting full backup with AES-256..." gpg --batch --yes --symmetric --cipher-algo AES256 \ --passphrase "$PASSPHRASE" \ --output "${FULL_PATH}.gpg" \ "$FULL_PATH" rm -f "$FULL_PATH" FULL_PATH="${FULL_PATH}.gpg" log "Encrypted: $FULL_PATH ($(du -h "$FULL_PATH" | cut -f1))" else log "WARNING: Full backup is NOT encrypted — contains credentials in plaintext" fi ``` The documented setup directs portable-mode users to configure: ```text If they choose portable/unencrypted, set `encrypt: false` and `mode: "portable"` in config. ``` ### Technical Analysis The backup implementation reads the `encrypt` and `retainDays` settings, but never reads or enforces the documented `mode` setting. It unconditionally archives the complete `~/.openclaw/` directory, including `~/.openclaw/credentials/`. Consequently, selecting the documented portable mode does not exclude credentials. If portable mode is combined with `encrypt: false`, the script creates an unencrypted full archive containing API keys, cloud credentials, to ...[truncated 1034 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Read and validate the `mode` setting before constructing an archive. - In portable mode, archive an explicit allowlist of portable paths rather than using broad exclusions. - Explicitly exclude `~/.openclaw/credentials/`, session secrets, tokens, and other machine-specific state. - Reject unsupported or missing mode values instead of silently falling back. - Enforce the invariant that a full backup cannot run when encryption is disabled. - Add automated tests that inspect archive contents and verify that portable backups never contain credentials. - Update documentation to match the implementation and remove claims that are not programmatically enforced. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/backup.sh:60
Finding
Complete plaintext archives are written to persistent storage before encryption<![CDATA[ ## Vulnerability Details **File Location**: `scripts/backup.sh:60-63, 92-105, 112-124` **Vulnerability Type**: Insecure handling of sensitive temporary data **Risk Level**: High ### Vulnerable Code ```bash # --------------------------------------------------------------------------- # Prepare # --------------------------------------------------------------------------- mkdir -p "$BACKUP_DIR" TIMESTAMP="$(date '+%Y%m%d-%H%M')" HOSTNAME_SHORT="$(hostname -s 2>/dev/null || echo unknown)" ``` ```bash FULL_NAME="openclaw-${HOSTNAME_SHORT}-${TIMESTAMP}-full.tar.gz" FULL_PATH="$BACKUP_DIR/$FULL_NAME" log "Creating full backup..." tar czf "$FULL_PATH" -C "$HOME" .openclaw/ log "Full archive: $FULL_PATH ($(du -h "$FULL_PATH" | cut -f1))" if [[ "$ENCRYPT" == "true" ]]; then log "Encrypting full backup with AES-256..." gpg --batch --yes --symmetric --cipher-algo AES256 \ --passphrase "$PASSPHRASE" \ --output "${FULL_PATH}.gpg" \ "$FULL_PATH" rm -f "$FULL_PATH" ``` ```bash WS_NAME="openclaw-${HOSTNAME_SHORT}-${TIMESTAMP}-workspace.tar.gz" WS_PATH="$BACKUP_DIR/$WS_NAME" log "Creating workspace-only backup..." tar czf "$WS_PATH" -C "$HOME" .openclaw/workspace/ log "Workspace archive: $WS_PATH ($(du -h "$WS_PATH" | cut -f1))" if [[ "$ENCRYPT" == "true" ]]; then log "Encrypting workspace backup..." gpg --batch --yes --symmetric --cipher-algo AES256 \ --passphrase "$PASSPHRASE" \ --output "${WS_PATH}.gpg" \ "$WS_PATH" rm -f "$WS_PATH" ``` ### Technical Analysis The script first creates complete unencrypted archives in the persistent backup directory and only then encrypts and removes them. It does not set a restrictive `umask`, explicitly set file permissions, or register cleanup for partially created plaintext archives. If GPG fails, the process is interrupted, storage becomes full, or the machine crashes between archive creation and deletion, the plaintext archive remains on disk. Even after deletion, data may remain re ...[truncated 951 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Set `umask 077` at the beginning of every script handling backups or credentials. - Stream archive output directly into GPG so no plaintext archive is created: ```bash tar czf - -C "$HOME" .openclaw/ | gpg --batch --yes --symmetric --cipher-algo AES256 \ --pinentry-mode loopback --passphrase-fd 3 \ --output "${FULL_PATH}.gpg" 3<"$PASSPHRASE_FILE" ``` - Write encrypted output to a temporary file in a mode-700 directory, then atomically rename it after successful completion. - Register an `EXIT`, `INT`, and `TERM` cleanup handler for all temporary artifacts. - Explicitly create backup files with owner-only permissions. - Avoid relying on `rm` as protection against recovery of sensitive plaintext. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/backup.sh:99
Finding
Backup encryption passphrase is exposed through process command-line arguments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/backup.sh:99-103`; repeated at `scripts/restore.sh:124-128` and `scripts/test-backup.sh:78-90` **Vulnerability Type**: Secret disclosure through process arguments **Risk Level**: Medium ### Vulnerable Code ```bash gpg --batch --yes --symmetric --cipher-algo AES256 \ --passphrase "$PASSPHRASE" \ --output "${FULL_PATH}.gpg" \ "$FULL_PATH" ``` The restore script uses the same pattern: ```bash gpg --batch --yes --decrypt \ --passphrase "$PASSPHRASE" \ --output "$DECRYPTED" \ "$ARCHIVE" ``` The test script also exposes the passphrase twice: ```bash gpg --batch --yes --symmetric --cipher-algo AES256 \ --passphrase "$PASSPHRASE" \ --output "$TEST_FILE.gpg" \ "$TEST_FILE" 2>/dev/null gpg --batch --yes --decrypt \ --passphrase "$PASSPHRASE" \ --output "$TEST_FILE.dec" \ "$TEST_FILE.gpg" 2>/dev/null ``` ### Technical Analysis Passing a secret with `--passphrase "$PASSPHRASE"` places the passphrase in GPG's argument vector. Depending on operating-system process visibility and `/proc` restrictions, another local process may be able to inspect the command line while GPG is running. The same passphrase protects both full and workspace backups, so disclosure compromises all archives encrypted with that passphrase. ### Attack Path 1. A local attacker continuously monitors process command lines. 2. The user runs backup, restore, or the setup test. 3. GPG starts with the passphrase in its argument vector. 4. The attacker records the passphrase. 5. The attacker uses it to decrypt any accessible current or historical backup protected by the same secret. ### Impact Assessment The immediate privilege gained is the ability to decrypt accessible OpenClaw backups. Full backups may disclose credentials that grant broader access to APIs, cloud accounts, storage buckets, and other configured services. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions - Do not place passphrases in command-line arguments. - Supply the secret through a protected file descriptor using GPG's `--passphrase-fd` and `--pinentry-mode loopback`. - Alternatively, use an appropriately configured GPG agent or another secret-input facility that does not expose the value in the argument vector. - Ensure the source credential file is owned by the current user and has mode 600 before reading it. - Clear the shell variable as soon as practical after use, while recognizing that variable clearing does not remedy command-line exposure already caused. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/restore.sh:174
Finding
Full restore extracts unvalidated archives directly into the user's home directory<![CDATA[ ## Vulnerability Details **File Location**: `scripts/restore.sh:82-105, 174-184` **Vulnerability Type**: Unsafe archive extraction **Risk Level**: High ### Vulnerable Code ```bash if [[ "$SOURCE" == s3://* ]]; then log "Downloading from S3..." LOCAL_FILE="$WORK_DIR/$(basename "$SOURCE")" if [[ -f "$CRED_DIR/aws-credentials" ]]; then safe_load_creds "$CRED_DIR/aws-credentials" fi aws s3 cp "$SOURCE" "$LOCAL_FILE" elif [[ "$SOURCE" == gs://* ]]; then log "Downloading from GCS..." LOCAL_FILE="$WORK_DIR/$(basename "$SOURCE")" if [[ -f "$CRED_DIR/gcs-key.json" ]]; then gcloud auth activate-service-account --key-file="$CRED_DIR/gcs-key.json" 2>/dev/null || true fi gsutil cp "$SOURCE" "$LOCAL_FILE" elif [[ -f "$SOURCE" ]]; then LOCAL_FILE="$SOURCE" else die "Source not found or unsupported: $SOURCE" fi ``` ```bash else # Full restore: replace entire ~/.openclaw/ if [[ -d "$OPENCLAW_DIR" ]]; then SAFETY="$HOME/.openclaw.pre-restore" [[ -d "$SAFETY" ]] && rm -rf "$SAFETY" log "Moving existing ~/.openclaw/ → ~/.openclaw.pre-restore/" mv "$OPENCLAW_DIR" "$SAFETY" fi log "Extracting full backup..." tar xzf "$ARCHIVE" -C "$HOME" log "Full restore complete" fi ``` ### Technical Analysis The restore process accepts local archives and objects downloaded from cloud storage, then extracts full backups directly into `$HOME`. Before extraction, it does not validate: - That every member is under `.openclaw/` - Absolute or parent-directory traversal paths - Symbolic or hard links - Device files or unexpected file types - Ownership and permission metadata - Archive authenticity or cryptographic integrity beyond successful symmetric decryption A crafted archive can therefore attempt to write unexpected files under the user's home directory. Even if the installed `tar` implementation blocks common traversal forms, unrestricted members that legitimately name files such as `.bashrc`, `.profile`, or applicatio ...[truncated 971 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - List and validate every archive member before extraction. - Require all members to begin with the exact `.openclaw/` prefix. - Reject absolute paths, `..` components, unsafe symbolic links, hard links, devices, FIFOs, and other unexpected types. - Extract into a newly created mode-700 staging directory rather than directly into `$HOME`. - Verify the staged directory structure, ownership, permissions, and expected contents. - Atomically move the validated `.openclaw` directory into place. - Use authenticated encryption or separately sign backups so a compromised storage destination cannot silently substitute an archive. - Verify backup checksums or signatures before moving the existing installation. - Restore conservative ownership and permissions rather than blindly trusting archive metadata. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
references/setup-guide.md:97
Finding
Cloud credential files lack consistent permission and ownership enforcement<![CDATA[ ## Vulnerability Details **File Location**: `references/setup-guide.md:97-101`; provider-specific examples at `references/destinations.md:14-18, 37-41, 60-64, 81, 99-100` **Vulnerability Type**: Insecure credential storage permissions **Risk Level**: Medium ### Vulnerable Documentation ```text General flow per destination: 1. Check if the required CLI tool is installed (offer to install if not) 2. Ask for the required credentials/config 3. Save credentials to `~/.openclaw/credentials/backup/<provider>-credentials` 4. Add the destination entry to `config.json` 5. Run `test-backup.sh` to verify connectivity ``` Provider credentials are stored as follows: ```bash export AWS_ACCESS_KEY_ID="AKIA..." export AWS_SECRET_ACCESS_KEY="..." ``` ```bash export AWS_ACCESS_KEY_ID="your-r2-access-key" export AWS_SECRET_ACCESS_KEY="your-r2-secret-key" ``` ```bash export B2_APPLICATION_KEY_ID="your-key-id" export B2_APPLICATION_KEY="your-key" ``` The documentation also directs users to store a GCS service-account key and an OAuth-bearing rclone configuration in the same directory: ```text Save it to `~/.openclaw/credentials/backup/gcs-key.json` ``` ```text Copy the generated config to `~/.openclaw/credentials/backup/rclone.conf` ``` ### Technical Analysis The setup guide explicitly requires mode 600 for the backup passphrase, but no equivalent requirement is stated or enforced for AWS, R2, B2, GCS, or rclone credentials. The scripts merely check whether these files exist and then read them or pass them to external clients. If files are created under a permissive umask, other local users may be able to read long-lived access keys, service-account material, or OAuth refresh tokens. There is also no script-side validation of file ownership, symbolic links, or group/world permissions. ### Attack Path 1. A user follows the setup instructions and creates a provider credential file. 2. The file inherits permissive ambient permissions. 3. Another local user reads ...[truncated 503 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Create `~/.openclaw/credentials/backup/` with mode 700. - Create every credential file with mode 600 and ensure it is owned by the OpenClaw user. - Add preflight checks that reject group-readable, world-readable, incorrectly owned, or symbolic-link credential files. - Set `umask 077` before creating configuration or credential files. - Document least-privilege provider policies, including bucket-scoped identities and only the operations needed for backup and restore. - Prefer separate read and write identities where practical. - Avoid granting administrative cloud roles such as unrestricted Storage Object Admin when narrower bucket-level permissions suffice. - Establish credential rotation and revocation guidance. ]]>

T08 · Insecure Dependencies

Note
Location
references/destinations.md:3
Finding
Setup instructions install mutable third-party packages without version or integrity pinning<![CDATA[ ## Vulnerability Details **File Location**: `references/destinations.md:3-8, 52-55, 68-74` **Vulnerability Type**: Unpinned third-party dependency installation **Risk Level**: Low ### Vulnerable Documentation ```bash **CLI needed:** `aws` (AWS CLI) ```bash pip install awscli # or: sudo apt install awscli ``` ``` ```bash **CLI needed:** `b2` ```bash pip install b2 ``` ``` ```bash **CLI needed:** `gsutil` (part of Google Cloud SDK) ```bash # Debian/Ubuntu: sudo snap install google-cloud-cli --classic # or: pip install gsutil ``` ``` ### Technical Analysis The setup instructions recommend installing mutable package names from package repositories without pinning reviewed versions or verifying hashes or signatures. These names are consistent with the intended tools, so there is no evidence of typosquatting in the project. Nevertheless, later upstream compromise, dependency compromise, or an incompatible release would be installed automatically when a user follows these commands. The risk is greater if users execute package installation with elevated privileges or into a global Python environment. ### Attack Path 1. A user follows the cloud-destination setup guide. 2. The package manager resolves the latest available package and transitive dependencies. 3. A compromised or unexpectedly changed release is downloaded. 4. Installation hooks or later CLI execution runs unreviewed code with the installing user's privileges. 5. The compromised tool can access backup files and provider credentials supplied to it. ### Impact Assessment A compromised dependency could execute code as the installing user, read OpenClaw data and backup credentials, alter archives, or transmit data externally. System-wide installation with elevated privileges could increase the affected scope. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions - Prefer vendor-supported or trusted operating-system repositories. - Pin reviewed package versions rather than installing an unconstrained latest release. - For Python packages, use an isolated virtual environment and hash-locked requirements. - Verify repository signatures, package hashes, and vendor installation instructions. - Avoid recommending global or privileged `pip` installation. - Document known-compatible CLI versions and periodically review and update them. ]]>
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 (39)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The code is clearly a local backup script, not a full implementation of the broader declared description. It does support encrypted backups of ~/.openclaw and creates a workspace-only archive, which aligns with part of the description. However, the declared purpose explicitly includes restore, disaster recovery, migration, and storing backups to multiple cloud destinations, none of which are implemented in this supplied chunk. The gateway stop/start behavior is a reasonable supporting detail, not a mismatch. The main discrepancy is that the actual code only performs local backup creation and retention management, so the description overstates the capabilities of this code chunk.

Ae1

High
Category
analysis-evasion
Content
./scripts/restore.sh openclaw-myhost-20260215-full.tar.gz.gpg
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
./scripts/restore.sh openclaw-myhost-20260215-full.tar.gz.gpg
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
./scripts/restore.sh openclaw-myhost-20260215-full.tar.gz.gpg
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
./scripts/restore.sh openclaw-myhost-20260215-full.tar.gz.gpg
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Chaining Abuse

High
Category
Tool Misuse
Content
if [[ -d "$WORKSPACE_DIR" ]]; then
    SAFETY="${WORKSPACE_DIR}.pre-restore"
    [[ -d "$SAFETY" ]] && rm -rf "$SAFETY"
    log "Moving existing workspace → ${SAFETY}/"
    mv "$WORKSPACE_DIR" "$SAFETY"
  fi
Confidence
75% confidence
Finding
Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Chaining Abuse

High
Category
Tool Misuse
Content
if [[ -d "$WORKSPACE_DIR" ]]; then
    SAFETY="${WORKSPACE_DIR}.pre-restore"
    [[ -d "$SAFETY" ]] && rm -rf "$SAFETY"
    log "Moving existing workspace → ${SAFETY}/"
    mv "$WORKSPACE_DIR" "$SAFETY"
  fi
Confidence
75% confidence
Finding
Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
echo "  1. Review the restored files at ~/.openclaw/"
  echo "  2. Start the gateway:  openclaw gateway start"
  echo "  3. If everything works, remove the safety copy:"
  echo "     rm -rf ~/.openclaw.pre-restore/"
fi
Confidence
100% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
echo "  1. Review the restored files at ~/.openclaw/"
  echo "  2. Start the gateway:  openclaw gateway start"
  echo "  3. If everything works, remove the safety copy:"
  echo "     rm -rf ~/.openclaw.pre-restore/"
fi
Confidence
95% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
safe_load_creds "$CRED_DIR/aws-credentials" || true

        if aws s3 cp "$TEST_UPLOAD" "${BUCKET%/}/$TEST_NAME" --region "$REGION" 2>&1 && \
           aws s3 rm "${BUCKET%/}/$TEST_NAME" --region "$REGION" 2>&1; then
          pass "S3 upload + cleanup OK"
        else
          fail "S3 upload failed"; ((FAILURES++))
Confidence
95% confidence
Finding
The delete target is built from configuration-controlled bucket/path data and passed directly to `aws s3 rm`. If the configured bucket value includes an unexpected prefix/path, the cleanup step could delete an unintended remote object rather than only the just-uploaded test artifact.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
safe_load_creds "$CRED_DIR/r2-credentials" || true

        if aws s3 cp "$TEST_UPLOAD" "s3://${BUCKET}/$TEST_NAME" --endpoint-url "$ENDPOINT" 2>&1 && \
           aws s3 rm "s3://${BUCKET}/$TEST_NAME" --endpoint-url "$ENDPOINT" 2>&1; then
          pass "R2 upload + cleanup OK"
        else
          fail "R2 upload failed"; ((FAILURES++))
Confidence
95% confidence
Finding
The R2 cleanup command constructs the deletion URI from configuration-controlled bucket data without enforcing that the field is bucket-only. A malformed or overbroad configured value could cause deletion of an unintended object in remote storage during cleanup.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
gcloud auth activate-service-account --key-file="$CRED_DIR/gcs-key.json" 2>/dev/null || true

        if gsutil cp "$TEST_UPLOAD" "${BUCKET%/}/$TEST_NAME" 2>&1 && \
           gsutil rm "${BUCKET%/}/$TEST_NAME" 2>&1; then
          pass "GCS upload + cleanup OK"
        else
          fail "GCS upload failed"; ((FAILURES++))
Confidence
95% confidence
Finding
The GCS removal path is derived from the configured bucket string with only minimal trimming, so a bucket value containing additional path elements could broaden what object is targeted for deletion. In a backup tool that talks to real cloud storage, this increases the chance of accidental destructive operations against remote data.

Session Persistence

Medium
Category
Rogue Agent
Content
## Manual Usage

### backup.sh — Create local backups

Every run produces **two files**:
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.

Intent-Code Divergence

Medium
Confidence
83% confidence
Finding
The documentation is internally inconsistent about whether workspace backups are always encrypted: several sections say workspace backups are encrypted, while examples and filename conventions show plain .tar.gz restores. That ambiguity can lead operators to create, transfer, or restore unencrypted archives containing memory, notes, conversations, and other sensitive data, causing accidental disclosure.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
**CLI needed:** `aws` (AWS CLI)
```bash
pip install awscli
# or: sudo apt install awscli
```

**Setup:**
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
**CLI needed:** `aws` (AWS CLI)
```bash
pip install awscli
# or: sudo apt install awscli
```

**Setup:**
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
**CLI needed:** `aws` (AWS CLI)
```bash
pip install awscli
# or: sudo apt install awscli
```

**Setup:**
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Session Persistence

Medium
Category
Rogue Agent
Content
```

**Setup:**
1. Create an S3 bucket in your AWS account
2. Create an IAM user with S3 write access (or use an existing one)
3. Save credentials to `~/.openclaw/credentials/backup/aws-credentials`:
```bash
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.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The instructions tell users to place long-lived AWS credentials in a file under ~/.openclaw without any warning about file permissions, rotation, or the sensitivity of the secret material. In a backup skill, these credentials are especially valuable because they can grant persistent access to backup storage and may expose or enable tampering with protected data if the local machine or config directory is later compromised.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
A downloaded GCS service account JSON key is a reusable bearer secret, and the instructions omit any warning that storing it locally creates a high-value target. In backup/restore context this is more dangerous because the key may allow broad object access to backup archives, enabling data theft or unauthorized modification depending on the account scope.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
rclone.conf can contain reusable OAuth refresh tokens and remote definitions, but the instructions present copying it into ~/.openclaw as routine without warning about token sensitivity. In a backup destination skill, compromise of that config could grant ongoing access to cloud-stored backups and facilitate exfiltration of potentially sensitive archives.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
## Remote Retention & Lifecycle

Local backups are auto-pruned after 30 days (configurable). **Remote backups are never automatically deleted** — this is intentional. Storage is cheap, and offsite backups should be your safety net.

To manage remote retention, set lifecycle rules directly on your storage provider:
Confidence
80% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The guide explicitly instructs storing a backup encryption passphrase and provider credentials on disk under ~/.openclaw/credentials/backup, but it does not clearly warn the user that this creates a local secret-at-rest risk. In the context of a backup skill handling API keys and recovery secrets, compromised local access, malware, or overly broad filesystem permissions could expose both backup contents and cloud destinations.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The guide recommends cron-based unattended backups and optional chained cloud uploads, but does not clearly disclose that this will repeatedly collect local data and may automatically transmit it to third-party services. In a backup skill covering workspace contents and possibly credentials, lack of prominent consent and scope warning increases the risk of unintended ongoing data exfiltration or privacy exposure.

Session Persistence

Medium
Category
Rogue Agent
Content
#!/usr/bin/env bash
# backup.sh — Create local backups of ~/.openclaw/
# Always produces two files:
#   1. Full backup (encrypted) — everything, for disaster recovery on same/similar environment
#   2. Workspace-only backup — just the workspace (memory, skills, files), safe for any environment
Confidence
88% confidence
Finding
This script intentionally archives the entire ~/.openclaw directory, which likely includes credentials, tokens, and session material, then stores the backup on disk. While backup is the skill's stated purpose, persisting full application state materially increases exposure if the backup directory is accessed by another local user, synced insecurely, or encryption is disabled or mismanaged.