Back to skill

Security audit

OpenClaw Updater (LinZ)

Security checks for vulnerabilities and agentic risk

Overview

This OpenClaw updater is mostly coherent, but it enables unattended global software updates with mutable npm packages and possible elevated privileges, so users should review it carefully before installing.

Install only if you intentionally want this skill to modify your OpenClaw installation. Prefer dry-run checks and manual approval before installation, avoid sudo or root cron, review the fallback to the unscoped openclaw package, and do not enable unattended cron updates unless you accept the supply-chain and local filesystem risks.

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

T08 · Insecure Dependencies

Error
Location
scripts/update-openclaw.sh:110
Finding

Unpinned npm Packages Are Installed Globally During Unattended Updates

Content
View full analysis

Vulnerability Details

File Location: scripts/update-openclaw.sh:57-60, 110-115; scheduled execution is documented in SKILL.md:48-65, and elevated execution is suggested in SKILL.md:101
Vulnerability Type: Unpinned dependency installation and unsafe automatic updates
Risk Level: High

Vulnerable Code

bash
# Get latest version from npm
get_latest_version() {
    npm view @openclaw/core version 2>/dev/null || npm view openclaw version 2>/dev/null || echo ""
}
bash
if ! npm install -g @openclaw/core@latest 2>&1 | tee -a "$LOG_FILE"; then
    # Try alternative package name
    if ! npm install -g openclaw@latest 2>&1 | tee -a "$LOG_FILE"; then
        log "${RED}Update failed! Check $LOG_FILE for details.${NC}"
        return 1
    fi
fi

The accompanying instructions enable unattended execution:

bash
0 3 * * * /bin/bash ~/.openclaw/workspace/skills/openclaw-updater/scripts/update-openclaw.sh >> ~/.openclaw/logs/cron-update.log 2>&1

The troubleshooting instructions also suggest elevated installation:

bash
sudo npm install -g @openclaw/core@latest

Technical Analysis

The updater installs the mutable latest npm tag without pinning an approved version, validating package integrity, or verifying a trusted signature. npm installation can execute package lifecycle scripts, so package installation is also a code-execution boundary.

The fallback from the scoped @openclaw/core package to the separate unscoped openclaw package broadens the supply-chain trust boundary. A failure involving the intended package can cause a different package to be installed automatically.

The documented cron configuration is optional and consistent with the declared auto-update feature; it is not silently registered by the script and therefore is not, by itself, malicious persistence. Nevertheless, scheduling the updater changes a sup ...[truncated 1499 chars]

Remediation
View remediation

Remediation Suggestions

  1. Replace @latest with an explicitly approved, immutable version:
    bash
    npm install -g "@openclaw/core@${APPROVED_VERSION}"
    
  2. Validate the downloaded package against an independently trusted integrity hash or signature before installation.
  3. Remove the unscoped openclaw fallback unless its provenance and equivalence are explicitly verified. A failed installation should stop safely rather than silently switch package identities.
  4. Separate update checking from installation. Scheduled jobs should only check and notify; installation should require explicit user approval.
  5. If unattended installation is essential, use a restricted service account, a controlled package mirror, an allowlisted version, and a staged rollout process.
  6. Avoid sudo and root cron. Configure npm with a user-owned prefix or use a version manager so global installation does not require administrative privileges.
  7. Consider disabling package lifecycle scripts with --ignore-scripts if OpenClaw's package does not require them, followed by explicit trusted setup steps.
  8. Verify that the installed version exactly equals the approved target rather than merely checking that it differs from the previous version.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/update-openclaw.sh:17
Finding

Predictable Shared Temporary Lock File Allows Symlink Clobbering

Content
View full analysis

Vulnerability Details

File Location: scripts/update-openclaw.sh:17-43
Vulnerability Type: Unsafe predictable file in a shared temporary directory
Risk Level: Medium

Vulnerable Code

bash
LOCK_FILE="/tmp/openclaw-updater.lock"
BACKUP_DIR="$HOME/.openclaw/backups"

# Ensure log directory exists
mkdir -p "$(dirname "$LOG_FILE")"
mkdir -p "$BACKUP_DIR"

# Logging function
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

# Check if already running
check_lock() {
    if [ -f "$LOCK_FILE" ]; then
        pid=$(cat "$LOCK_FILE" 2>/dev/null)
        if ps -p "$pid" > /dev/null 2>&1; then
            log "${YELLOW}Updater already running (PID: $pid)${NC}"
            exit 0
        else
            rm -f "$LOCK_FILE"
        fi
    fi
    echo $$ > "$LOCK_FILE"
}

# Cleanup on exit
cleanup() {
    rm -f "$LOCK_FILE"
}
trap cleanup EXIT

Technical Analysis

/tmp is normally writable by every local user. The script uses a fixed, predictable pathname and writes to it using shell redirection without atomically creating the file, checking ownership, rejecting symbolic links, or opening it with no-follow semantics.

If the updater account can write to a target file, a local attacker can create /tmp/openclaw-updater.lock as a symbolic link to that target. The echo $$ > "$LOCK_FILE" operation follows the link and truncates or overwrites the target with the updater PID.

The lock is also subject to time-of-check/time-of-use races. Another process can replace the path between the existence check, removal, and subsequent write. Moreover, this PID-file design does not provide mutual exclusion atomically, so concurrent updater instances can both proceed.

Attack Path

  1. A local attacker predicts the known path /tmp/openclaw-updater.lock.
  2. Before the updater runs, the attacker creates that path as a symbolic link ...[truncated 1203 chars]
Remediation
View remediation

Remediation Suggestions

  1. Replace the PID file with an advisory lock obtained atomically through flock:
    bash
    RUNTIME_DIR="${XDG_RUNTIME_DIR:-$HOME/.cache/openclaw}"
    mkdir -p -m 700 "$RUNTIME_DIR"
    exec 9>"$RUNTIME_DIR/updater.lock"
    flock -n 9 || {
        log "Updater already running"
        exit 0
    }
    
  2. Prefer ${XDG_RUNTIME_DIR}, where the directory is owned by the current user, rather than a shared top-level /tmp pathname.
  3. If /tmp must be used, create a private directory with mktemp -d, validate its ownership and permissions, and reject symbolic links.
  4. Do not implement locking as separate existence-check and write operations; use an atomic kernel-supported lock.
  5. Run the updater as an unprivileged account so any filesystem impact remains limited.
  6. Set a restrictive umask, such as umask 077, before creating lock, log, or backup files.
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (5)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `update-openclaw.sh` - Main update script with backup/restore capabilities

Chaining Abuse

High
Category
Tool Misuse
Confidence
96% confidence
Finding

The backup cleanup pipeline uses ls ... | tail ... | xargs rm -f, which is unsafe because xargs splits on whitespace and does not preserve filenames reliably. If an attacker can place specially crafted filenames in the backup directory, the script may delete unintended files or pass attacker-controlled arguments to rm. In an auto-updater context that runs unattended, this is more dangerous because it performs destructive filesystem operations without human review.

Content

Scanner excerpt · scripts/update-openclaw.sh (reported line 92)May include surrounding context.

sh
2>/dev/null || true

    # Keep only last 5 backups
    ls -t "$BACKUP_DIR"/openclaw-backup-*.tar.gz 2>/dev/null | tail -n +6 | xargs rm -f 2>/dev/null || true

    echo "$backup_path"
}

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The trigger phrase "check for updates" is generic and can match many unrelated user requests, causing this skill to activate outside its intended OpenClaw-specific context. Because the skill performs software update actions and can lead to package installation or scheduled execution, accidental invocation increases the risk of unintended system modification.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill promotes automated updates, cron scheduling, and installation behavior without a prominent warning that it modifies the local system, installs packages, and may run recurring privileged operations. In this context, missing consent and risk disclosure is dangerous because users may authorize persistent or destructive changes without understanding the consequences.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
91% confidence
Finding

The documentation explicitly advises using sudo for a global npm install, which normalizes privileged package installation. If followed, this can execute package lifecycle scripts and modify system-wide files as root, magnifying the impact of a compromised package, registry tampering, or user error.

Content

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

md
1. Check logs: `cat ~/.openclaw/logs/auto-update.log`
2. Verify npm permissions: `npm config get prefix`
3. Try with sudo if needed: `sudo npm install -g @openclaw/core@latest`

### Rollback

Static analysis

No suspicious patterns detected.