Back to skill

Security audit

myclaw-backup

Security checks for vulnerabilities and agentic risk

Overview

This is a real backup-and-restore skill, but it handles highly sensitive OpenClaw data through unsafe restore, upload, web UI, and shell execution paths.

Install only if you are comfortable with a full-trust backup tool that can read, package, restore, and schedule access to essentially all OpenClaw state. Keep archives encrypted or otherwise strongly protected, do not expose the HTTP server on a network without TLS, avoid sharing tokenized URLs, run restores only from trusted archives, and treat the current restore/upload web server paths as needing security fixes before remote use.

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/restore.sh:257
Finding

Untrusted backup archives can install and execute attacker-controlled scripts

Content
View full analysis
{ if (err) return json(res, 400, { error: err.message }); if (!file.filename.endsWith('.tar.gz')) return json(res, 400, { error: 'Only .tar.gz files accepted' }); const dest = path.join(BACKUP_DIR, path.basename(file.filename)); fs.writeFileSync(dest, file.data); fs.chmodSync(dest, 0o600); return json(res, 200, { message: 'Upload successful', filename: file.filename, size: fmt(file.data.length) }); }); } ``` ```bash # scripts/restore.sh:43-51 WORK_DIR="/tmp/openclaw-restore-$$" mkdir -p "$WORK_DIR" trap "rm -rf $WORK_DIR" EXIT info "Extracting archive..." tar -xzf "$ARCHIVE" -C "$WORK_DIR" BACKUP_DIR=$(find "$WORK_DIR" -maxdepth 1 -name "openclaw-backup_*" -type d | head -1) [ -z "$BACKUP_DIR" ] && error "Invalid archive: no openclaw-backup_* directory found" ``` ```bash # scripts/restore.sh:257-269 if [ -d "${BACKUP_DIR}/scripts" ] && [ -n "$(ls -A ${BACKUP_DIR}/scripts 2>/dev/null)" ]; then info "Restoring scripts..." if $DRY_RUN; then dryrun "copy scripts → ${OPENCLAW_HOME}/" else for f in "${BACKUP_DIR}/scripts/"*; do fname=$(basename "$f") cp "$f" "${OPENCLAW_HOME}/${fname}" chmod +x "${OPENCLAW_HOME}/${fname}" done info " scripts restored ($(ls ${BACKUP_DIR}/scripts | tr '\n' ' '))" fi fi ``` ```bash # scripts/restore.sh:286-291 if ! $DRY_RUN; then echo "" info "Starting OpenClaw Gateway..." if [ -f "${OPENCLAW_HOME}/start-gateway.sh" ]; then bash "${OPENCLAW_HOME}/start-gateway.sh" & ``` ### Technical Analysis The authenticated upload endpoint accepts a ...[truncated 1806 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/server.js:106
Finding

Stored cross-site scripting through uploaded backup filenames exposes the management token

Content
View full analysis
f.startsWith('openclaw-backup_') && f.endsWith('.tar.gz')) .map(f => { const stat = fs.statSync(path.join(BACKUP_DIR, f)); return { filename: f, size: stat.size, sizeHuman: fmt(stat.size), createdAt: stat.mtime.toISOString(), downloadUrl: `/download/${f}?token=${TOKEN}` }; }) .sort((a, b) => b.createdAt.localeCompare(a.createdAt)); } ``` ```javascript // scripts/server.js:106-113 const rows = backups.map(b => `tar.gz ${b.filename}${b.sizeHuman}${new Date(b.createdAt).toLocaleString()}⬇ Download` + `👁 Dry Run` + `♻️ Restore` + `` + `` ).join(''); ``` ```html
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/server.js:202
Finding

Shell command injection through backup paths and archive filenames

Content
View full analysis
/dev/null | grep -v "openclaw-backup" || true) NEW_CRON="${CRON_EXPR} ${BACKUP_SCRIPT} ${OUTPUT_DIR} >> /tmp/openclaw-backup.log 2>&1 # openclaw-backup" warn "This will add the following entry to your crontab:" echo " ${NEW_CRON}" echo "" { echo "$EXISTING" echo "$NEW_CRON" } | crontab - ``` ### Technical Analysis The Node.js service builds shell command strings containing configurable paths and archive filenames and executes them with `execSync`. Double-quoting a value does not neutralize shell command su ...[truncated 1962 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/server.js:86
Finding

Unbounded multipart uploads permit memory and disk exhaustion

Content
View full analysis
chunks.push(c)); req.on('end', () => { const body = Buffer.concat(chunks); const headerEnd = body.indexOf('\r\n\r\n'); const headerStr = body.slice(0, headerEnd).toString(); const fnm = headerStr.match(/filename="([^"]+)"/); if (!fnm) return cb(new Error('No filename')); const filename = path.basename(fnm[1]); const start = headerEnd + 4; const endBoundary = Buffer.from('\r\n--' + bm[1]); const end = body.indexOf(endBoundary, start); cb(null, { filename, data: end > 0 ? body.slice(start, end) : body.slice(start) }); }); req.on('error', cb); } ``` ```javascript // scripts/server.js:178-187 if (req.method === 'POST' && urlPath === '/upload') { return parseMultipart(req, (err, file) => { if (err) return json(res, 400, { error: err.message }); if (!file.filename.endsWith('.tar.gz')) return json(res, 400, { error: 'Only .tar.gz files accepted' }); const dest = path.join(BACKUP_DIR, path.basename(file.filename)); fs.writeFileSync(dest, file.data); fs.chmodSync(dest, 0o600); return json(res, 200, { message: 'Upload successful', filename: file.filename, size: fmt(file.data.length) }); }); } ``` ### Technical Analysis The custom multipart parser stores every request chunk in an array and then creates another full-size allocation with `Buffer.concat`. No request-size limit, `Content-Length` check, streaming quota, upload timeout, archive-count limit, or disk-space check is enforced. Authentication reduces exposure but ...[truncated 1212 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/server.js:218
Finding

Credential-bearing archives and bearer tokens are exposed through plaintext HTTP and tokenized URLs

Content
View full analysis
f.startsWith('openclaw-backup_') && f.endsWith('.tar.gz')) .map(f => { const stat = fs.statSync(path.join(BACKUP_DIR, f)); return { filename: f, size: stat.size, sizeHuman: fmt(stat.size), createdAt: stat.mtime.toISOString(), downloadUrl: `/download/${f}?token=${TOKEN}` }; }) .sort((a, b) => b.createdAt.localeCompare(a.createdAt)); } ``` ```javascript // scripts/server.js:218-223 server.listen(PORT, '0.0.0.0', () => { console.log(`\n🦞 MyClaw Backup Server`); console.log(` Token protected | Localhost-only for /backup and /restore`); console.log(` http://localhost:${PORT}/?token=${TOKEN}`); console.log(` ⚠️ Do not expose this port to the internet without TLS.\n`); }); ``` ```bash # scripts/serve.sh:64-71 echo " 🌐 Web UI: http://localhost:${PORT}/?token=${TOKEN}" echo " 📥 Upload: POST http://localhost:${PORT}/upload?token=${TOKEN}" echo " 📤 List: GET http://localhost:${PORT}/backups?token=${TOKEN}" echo " 📋 Log: ${LOG_FILE}" echo "" warn "Share the URL above to download/restore from another machine (requires network access)" ``` ### Technical Analysis The server listens on `0.0.0.0`, making it reachable through all available interfaces, but only supports plaintext HTTP. The documentation warns users to add TLS, yet the launch script explicitly encourages sharing an HTTP URL for remote migration. The bearer token is accepted in query parameters, returned in API-generated download URLs, displayed in terminal output, and embedded in the UI. Query credentials can be retained in shell history, terminal logs, browser history, c ...[truncated 1313 chars]
Remediation
View remediation
Vulnerability Patterns
  • 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
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
Findings (24)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared description promises a broader backup-and-restore toolkit, but this code chunk only performs backup creation and retention pruning. The implemented behavior does align with part of the description: it archives highly sensitive OpenClaw data such as configuration, credentials, skills, agent data, and workspace contents. However, several headline capabilities in the description are absent from the provided code: there is no restore path, no restore safety checks like --dry-run, no HTTP server, no token enforcement, and no upload/download web workflow. There is also no direct scheduling feature here; backing up cron state is not the same as scheduling periodic backups. This is therefore a description-behavior mismatch due to substantial declared functionality not present in the supplied code chunk.

Content

No source excerpt is available for this finding.

Chaining Abuse

High
Category
Tool Misuse
Confidence
86% confidence
Finding

Using ls -t ... | tail -n +8 | xargs rm -f is unsafe because it relies on whitespace-delimited parsing and passes filenames through a shell pipeline without null delimiting. If backup filenames or paths contain spaces, newlines, or crafted characters, the prune step can delete unintended files; the danger is increased because OUTPUT_DIR is user-controlled input and this code performs destructive deletion there.

Content

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

sh
BACKUP_COUNT=$(ls "${OUTPUT_DIR}"/openclaw-backup_*.tar.gz 2>/dev/null | wc -l)
if [ "$BACKUP_COUNT" -gt 7 ]; then
  info "Pruning old backups (keeping last 7)..."
  ls -t "${OUTPUT_DIR}"/openclaw-backup_*.tar.gz | tail -n +8 | xargs rm -f
  info "  Removed $((BACKUP_COUNT - 7)) old backup(s)"
fi

Self-Modification

High
Category
Rogue Agent
Confidence
85% confidence
Finding

Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.

Content

Scanner excerpt · scripts/restore.sh (reported line 5)May include surrounding context.

sh
# openclaw-restore: Restore OpenClaw from a backup archive
# Usage: restore.sh <backup.tar.gz> [--dry-run] [--overwrite-gateway-token]
#
# ⚠️  WARNING: This will overwrite existing files. Run with --dry-run first.
#
# By default, the gateway auth token from the NEW server is preserved after restore.
# This prevents "gateway token mismatch" errors in Control UI / Dashboard.

YARA rule 'backdoor_persistence': Backdoor persistence with malicious payloads (shell commands, SSH key injection, hidden root users) [malware]

High
Category
YARA Match
Confidence
75% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

Scanner excerpt · scripts/schedule.sh (reported line 33)May include surrounding context.

sh
; shift 2 ;;
    --output-dir) OUTPUT_DIR="$2"; shift 2 ;;
    --disable) DISABLE=true; shift ;;
    *) echo "Unknown option: $1"; exit 1 ;;
  esac
done

GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m'
info() { echo -e "${GREEN}[✓]${NC} $*"; }
warn() { echo -e "${YELLOW}[!]${NC} $*"; }

BACKUP_SCRIPT="${SKILL_DIR}/scripts/backup.sh"

if $DISABLE; then
  # Remove existing cron
  EXISTING=$(crontab -l 2>/dev/null | grep -v "openclaw-backup" || true)
  echo "$EXISTING" | crontab -
  info "Backup cron job disabled"
  exit 0
fi

case $INTERVAL in
  hourly) CRON_EXPR="0 * * * *" ;;
  daily)  CRON_EXPR="0 3 * * *" ;;  # 3 AM daily
  weekly) CRON_EXPR="0 3 * * 0" ;;  # 3 AM Sunday
  *)      echo "Unknown interval: $INTERVAL (use hourly/daily/weekly)"; exit 1 ;;
esac

# Ensure backup script is executable
chmod +x "$BACKUP_SCRIPT"

# Add to crontab — notify user explicitly
EXISTING=$(crontab -l 2>/dev/null | grep -v "openclaw-backup" || true)
NEW_CRON="${CRON_EXPR} ${BACKUP_SCRIPT} ${O

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
90% confidence
Finding

The skill is explicitly designed to persist and restore agent memory, credentials, session history, and other durable state. In this context, persistence is intentional rather than covert, but it is still security-relevant because the archived data includes highly sensitive secrets and long-lived session material; compromise of the archive or misuse of restore/upload features could expose or reintroduce powerful credentials across systems.

Content

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

md
---
name: myclaw-backup
description: "Backup and restore all OpenClaw configuration, agent memory, skills, and workspace data. Part of the MyClaw.ai (https://myclaw.ai/skills) open skills ecosystem — the AI personal assistant platform that gives every user a full server with complete code control. Use when the user wants to create a snapshot of their OpenClaw instance, schedule periodic backups, restore from a backup, migrate to a new server, download a backup file locally, upload a backup file from another machine, or protect against data loss. Includes a built-in HTTP server for browser-based download/upload/restore without needing cloud storage. TRUST BOUNDARY: This skill archives and restores highly sensitive data including bot tokens, API keys, and channel credentials. Only install if you trust the operator. Always use --dry-run before restore. Never start the HTTP server without a --token."
metadata:
  openclaw:
    requires:

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

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

Content

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

md
This skill handles **highly sensitive data**: bot tokens, API keys, channel credentials, session history. Understand the security model before use:

### What each script does
- **backup.sh** — reads `~/.openclaw/` and writes a `chmod 600` archive to disk. No network access.
- **restore.sh** — overwrites `~/.openclaw/` from an archive. Requires typing `yes` to confirm. Always run `--dry-run` first.
- **serve.sh / server.js** — starts a local HTTP server. Token is **mandatory** (refuses to start without one). Shell-execution endpoints (`/backup`, `/restore`) are **localhost-only** — remote access can only download and upload files, not trigger execution.
- **schedule.sh** — modifies your system crontab to run backup.sh on a schedule. Prints the cron entry before adding. Use `--disable` to remove.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

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

Content

Scanner excerpt · references/what-gets-saved.md (reported line 35)May include surrounding context.

md
This skill handles **highly sensitive data**: bot tokens, API keys, channel credentials, session history. Understand the security model before use:

### What each script does
- **backup.sh** — reads `~/.openclaw/` and writes a `chmod 600` archive to disk. No network access.
- **restore.sh** — overwrites `~/.openclaw/` from an archive. Requires typing `yes` to confirm. Always run `--dry-run` first.
- **serve.sh / server.js** — starts a local HTTP server. Token is **mandatory** (refuses to start without one). Shell-execution endpoints (`/backup`, `/restore`) are **localhost-only** — remote access can only download and upload files, not trigger execution.
- **schedule.sh** — modifies your system crontab to run backup.sh on a schedule. Prints the cron entry before adding. Use `--disable` to remove.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

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

Content

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

sh
This skill handles **highly sensitive data**: bot tokens, API keys, channel credentials, session history. Understand the security model before use:

### What each script does
- **backup.sh** — reads `~/.openclaw/` and writes a `chmod 600` archive to disk. No network access.
- **restore.sh** — overwrites `~/.openclaw/` from an archive. Requires typing `yes` to confirm. Always run `--dry-run` first.
- **serve.sh / server.js** — starts a local HTTP server. Token is **mandatory** (refuses to start without one). Shell-execution endpoints (`/backup`, `/restore`) are **localhost-only** — remote access can only download and upload files, not trigger execution.
- **schedule.sh** — modifies your system crontab to run backup.sh on a schedule. Prints the cron entry before adding. Use `--disable` to remove.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

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

Content

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

sh
This skill handles **highly sensitive data**: bot tokens, API keys, channel credentials, session history. Understand the security model before use:

### What each script does
- **backup.sh** — reads `~/.openclaw/` and writes a `chmod 600` archive to disk. No network access.
- **restore.sh** — overwrites `~/.openclaw/` from an archive. Requires typing `yes` to confirm. Always run `--dry-run` first.
- **serve.sh / server.js** — starts a local HTTP server. Token is **mandatory** (refuses to start without one). Shell-execution endpoints (`/backup`, `/restore`) are **localhost-only** — remote access can only download and upload files, not trigger execution.
- **schedule.sh** — modifies your system crontab to run backup.sh on a schedule. Prints the cron entry before adding. Use `--disable` to remove.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

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

Content

Scanner excerpt · scripts/restore.sh (reported line 131)May include surrounding context.

sh
This skill handles **highly sensitive data**: bot tokens, API keys, channel credentials, session history. Understand the security model before use:

### What each script does
- **backup.sh** — reads `~/.openclaw/` and writes a `chmod 600` archive to disk. No network access.
- **restore.sh** — overwrites `~/.openclaw/` from an archive. Requires typing `yes` to confirm. Always run `--dry-run` first.
- **serve.sh / server.js** — starts a local HTTP server. Token is **mandatory** (refuses to start without one). Shell-execution endpoints (`/backup`, `/restore`) are **localhost-only** — remote access can only download and upload files, not trigger execution.
- **schedule.sh** — modifies your system crontab to run backup.sh on a schedule. Prints the cron entry before adding. Use `--disable` to remove.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

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

Content

Scanner excerpt · scripts/restore.sh (reported line 216)May include surrounding context.

sh
This skill handles **highly sensitive data**: bot tokens, API keys, channel credentials, session history. Understand the security model before use:

### What each script does
- **backup.sh** — reads `~/.openclaw/` and writes a `chmod 600` archive to disk. No network access.
- **restore.sh** — overwrites `~/.openclaw/` from an archive. Requires typing `yes` to confirm. Always run `--dry-run` first.
- **serve.sh / server.js** — starts a local HTTP server. Token is **mandatory** (refuses to start without one). Shell-execution endpoints (`/backup`, `/restore`) are **localhost-only** — remote access can only download and upload files, not trigger execution.
- **schedule.sh** — modifies your system crontab to run backup.sh on a schedule. Prints the cron entry before adding. Use `--disable` to remove.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill states that schedule.sh modifies the system crontab, but the declared permissions only cover ~/.openclaw read/write and network listening. This under-declares the actual trust boundary and can mislead users or policy engines into approving a skill that alters persistence/scheduling on the host.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

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

Content

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

bash
bash scripts/backup.sh /tmp/openclaw-backups
# → /tmp/openclaw-backups/openclaw-backup_TIMESTAMP.tar.gz (chmod 600)

Restore — always dry-run first

Session Persistence

Medium
Category
Rogue Agent
Confidence
90% confidence
Finding

The script intentionally copies openclaw.json and related state into a backup archive, and the metadata explicitly states that this file contains bot tokens, API keys, and channel credentials. While expected for backup/restore functionality, this is still a real sensitive-data persistence risk: the script stages secrets under /tmp, packages them into a portable archive, and thereby creates a high-value artifact that can be stolen if filesystem permissions, temp directory exposure, or archive handling are weak.

Content

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

sh
info "Backing up Gateway config..."
CONFIG_FILE="${OPENCLAW_HOME}/openclaw.json"
if [ -f "$CONFIG_FILE" ]; then
  mkdir -p "${WORK_DIR}/config"
  cp "$CONFIG_FILE" "${WORK_DIR}/config/openclaw.json"
  [ -f "${CONFIG_FILE}.bak" ] && cp "${CONFIG_FILE}.bak" "${WORK_DIR}/config/openclaw.json.bak"
  info "  openclaw.json → $(wc -c < ${WORK_DIR}/config/openclaw.json) bytes"

Session Persistence

Medium
Category
Rogue Agent
Confidence
85% confidence
Finding

This restore flow writes extensively into ~/.openclaw, including config, credentials, scripts, cron data, and agent state, effectively persisting whatever content is present in the supplied backup archive. In this skill's trust boundary, an attacker who can supply or tamper with a backup can implant persistent malicious scripts or poisoned configuration that survive restart, making the behavior significantly more dangerous than ordinary file restore.

Content

Scanner excerpt · scripts/restore.sh (reported line 106)May include surrounding context.

sh
# ── Explicit confirmation before destructive restore ─────────────────────────
if ! $DRY_RUN; then
  echo ""
  echo -e "${RED}⚠️  WARNING: This will OVERWRITE ~/.openclaw/ with backup data.${NC}"
  echo "   Backup: $(basename $ARCHIVE)"
  echo "   Target: ${OPENCLAW_HOME}"
  if [ -n "$CURRENT_GATEWAY_TOKEN" ] && ! $OVERWRITE_GATEWAY_TOKEN; then

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

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

Content

Scanner excerpt · scripts/restore.sh (reported line 215)May include surrounding context.

sh
else
    mkdir -p "${OPENCLAW_HOME}/credentials"
    rsync -a "${BACKUP_DIR}/credentials/" "${OPENCLAW_HOME}/credentials/"
    chmod 700 "${OPENCLAW_HOME}/credentials"
    chmod 600 "${OPENCLAW_HOME}/credentials/"* 2>/dev/null || true
    info "  credentials restored (permissions hardened)"
  fi

Session Persistence

Medium
Category
Rogue Agent
Confidence
85% 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 · scripts/schedule.sh (reported line 4)May include surrounding context.

sh
#!/usr/bin/env bash
# openclaw-backup-schedule: Set up a cron job for periodic automatic backups
#
# ⚠️  PERSISTENCE NOTICE: This script modifies your system crontab (crontab -e).
# It adds one entry to run backup.sh on a schedule. Use --disable to remove it.
#
# Usage: schedule.sh [--interval <daily|weekly|hourly>] [--output-dir <dir>] [--disable]

Session Persistence

Medium
Category
Rogue Agent
Confidence
88% confidence
Finding

This script programmatically removes and rewrites the user's crontab, establishing persistent execution of a backup task. While aligned with the skill's purpose, persistence is security-relevant because it creates long-lived execution of a sensitive backup process that may archive secrets, and misuse or compromise of the backup script later would be automatically re-triggered.

Content

Scanner excerpt · scripts/schedule.sh (reported line 33)May include surrounding context.

sh
if $DISABLE; then
  # Remove existing cron
  EXISTING=$(crontab -l 2>/dev/null | grep -v "openclaw-backup" || true)
  echo "$EXISTING" | crontab -
  info "Backup cron job disabled"
  exit 0

Session Persistence

Medium
Category
Rogue Agent
Confidence
90% confidence
Finding

The script adds a persistent cron entry that runs backup.sh with a user-controlled output directory, creating unattended repeated access to highly sensitive data. In this skill's context, that increases risk because backups may contain bot tokens, API keys, and workspace contents, so any weakness in backup.sh, file permissions, or destination handling becomes a recurring exposure.

Content

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

sh
chmod +x "$BACKUP_SCRIPT"

# Add to crontab — notify user explicitly
EXISTING=$(crontab -l 2>/dev/null | grep -v "openclaw-backup" || true)
NEW_CRON="${CRON_EXPR} ${BACKUP_SCRIPT} ${OUTPUT_DIR} >> /tmp/openclaw-backup.log 2>&1 # openclaw-backup"

warn "This will add the following entry to your crontab:"

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

The header comment states that remote clients are limited to list, download, and upload. In practice, any authenticated client can request GET / at L141-L142, and serveUI injects the bearer token into the HTML at L119-L122 while rendering restore actions in the interface at L115-L117. Although restore execution is still localhost-gated, the documentation's stated remote-access model is broader-restrictive than the actual exposed UI behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

This code performs a network upload of a backup archive via POST to /upload, but the only status message is shown after the operation starts. There is no prior disclosure, confirmation, or explanatory comment warning the user that selecting a file will immediately send backup contents to the server.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
76% confidence
Finding

The module comment claims /health is unauthenticated and returns no sensitive info. The implementation returns both status and service name at L132-L133, which is minor but still discloses product/service identification. This is not a major security issue, but it does contradict the absolute wording in the comment.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The document declares lang="en", which signals an English-only interface, and the visible UI text is also fixed in English. The file does not provide any indication of user-selectable language or a documented reason for restricting the interface to English.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/server.js:155