Back to skill

Security audit

VPS Bootstrap

Security checks for vulnerabilities and agentic risk

Overview

This skill is a coherent VPS bootstrap and recovery tool, but it performs high-impact system and credential changes with weak verification and limited user safeguards.

Install only on a fresh, disposable VPS or after reviewing the scripts line by line. Do not run restore.sh on a backup you do not fully trust, because it can overwrite agent instructions, memory, executable scripts, scheduled jobs, and credential stores. Consider pinning and verifying external installers, disabling the default firewall reset, and using passphrase-protected key material before use.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
Findings (5)

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/bootstrap.sh:46
Finding

Remote NodeSource installer is executed directly with root privileges

Content
View full analysis
/dev/null sudo apt-get install -y -qq nodejs 2>/dev/null log "Node.js $(node --version) installed" fi ``` ### Technical Analysis The script downloads mutable shell code from an external URL and immediately pipes it into `sudo bash`. The downloaded content is not pinned to a cryptographic digest, verified using a trusted signature, or saved for inspection before execution. HTTPS protects the connection in ordinary circumstances, but it does not protect against compromise of NodeSource infrastructure, unauthorized modification of the hosted installer, certificate or trust-store compromise, or an upstream account takeover. Because `sudo -E bash` runs the response as root while preserving environment variables, any command introduced into the response receives complete control of the VPS. This behavior exceeds the privileges needed merely to retrieve repository metadata: the effective root-level payload can change after the Skill has been audited. ### Attack Path 1. An attacker compromises the remote installer, its hosting infrastructure, or the delivery path. 2. The administrator invokes `scripts/bootstrap.sh`. 3. `curl` retrieves the attacker-modified response. 4. The response is passed directly to `sudo -E bash`. 5. Attacker-controlled commands execute as root and may modify system files, create accounts, install services, access local data, or deploy additional payloads. ### Impact Assessment Successful exploitation provides arbitrary root-level code execution over the entire VPS. The attacker can access all users' files, credentials, OpenClaw state, and network-accessible resources; disable security control ...[truncated 48 chars]
Remediation
View remediation

T01 · Skill Instruction Hijacking

Error
Location
scripts/restore.sh:20
Finding

Unauthenticated backups can replace Agent instructions, memory, executable scripts, credentials, and cron state

Content
View full analysis
/dev/null || true echo " ✓ memory/ ($(ls "$WORKSPACE/memory/" | wc -l) files)" fi # Scripts if [ -d "$BACKUP_ROOT/scripts" ]; then cp -r "$BACKUP_ROOT/scripts/"* "$WORKSPACE/scripts/" 2>/dev/null || true chmod +x "$WORKSPACE/scripts/"*.sh 2>/dev/null || true echo " ✓ scripts/ ($(ls "$WORKSPACE/scripts/"*.sh 2>/dev/null | wc -l) scripts)" fi # --- OpenClaw config --------------------------------------------------------- echo "Restoring config..." if [ -f "$BACKUP_ROOT/openclaw.json" ]; then cp "$BACKUP_ROOT/openclaw.json" "$OPENCLAW_DIR/openclaw.json" echo " ✓ openclaw.json" fi if [ -f "$BACKUP_ROOT/dot-env" ]; then cp "$BACKUP_ROOT/dot-env" "$OPENCLAW_DIR/.env" echo " ✓ .env" fi # --- Cron database ----------------------------------------------------------- if [ -d "$BACKUP_ROOT/cron-db" ]; then echo "Restoring cron database..." for crondir in "$OPENCLAW_DIR/cron" "$OPENCLAW_DIR/data/cron"; do mkdir -p "$crondir" cp -r "$BACKUP_ROOT/cro ...[truncated 3706 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Error
Location
scripts/bootstrap.sh:58
Finding

Mutable Chrome and OpenClaw releases are installed without version or integrity pinning

Content
View full analysis
/dev/null; then log "Chrome already installed: $(google-chrome --version 2>/dev/null | head -1)" else log "Installing Google Chrome..." wget -q -O /tmp/chrome.deb https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb sudo dpkg -i /tmp/chrome.deb 2>/dev/null || sudo apt-get install -f -y -qq 2>/dev/null rm -f /tmp/chrome.deb # Create headless shim for OpenClaw browser tools sudo tee /usr/local/bin/chrome-shim > /dev/null << 'SHIM' #!/bin/bash exec google-chrome --headless --no-sandbox --disable-gpu --disable-dev-shm-usage "$@" SHIM sudo chmod +x /usr/local/bin/chrome-shim log "Chrome installed with headless shim" fi fi # --- Step 4: OpenClaw ------------------------------------------------------- if command -v openclaw &>/dev/null; then log "OpenClaw already installed: $(openclaw --version 2>/dev/null | head -1)" log "Updating OpenClaw..." npm update -g openclaw 2>/dev/null || npm install -g openclaw else log "Installing OpenClaw..." npm install -g openclaw fi ``` ### Technical Analysis The Chrome URL always resolves to the current stable package, while the npm commands install or update `openclaw` without specifying an approved version. No expected digest, detached artifact signature, lockfile, or controlled package mirror is used. The effective dependency set can consequently change between executions after the Skill itself has been reviewed. Debian packages can run maintainer scripts under root during installation. npm packages can also execute lifecycle scripts with the privileges available to the npm process. The script does not state that it disables lifecycle ...[truncated 1225 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/bootstrap.sh:80
Finding

Bootstrap destructively resets the host firewall policy

Content
View full analysis
/dev/null 2>&1 sudo ufw default deny incoming >/dev/null sudo ufw default allow outgoing >/dev/null sudo ufw allow ssh >/dev/null sudo ufw --force enable >/dev/null log "Firewall enabled (SSH only)" fi ``` ### Technical Analysis The script performs `ufw --force reset`, deleting all existing UFW rules before installing its own minimal policy. The reset is noninteractive and enabled by default through `ENABLE_FIREWALL=true`. Configuring a firewall is consistent with the declared security-baseline functionality, but deleting unrelated policy is broader than necessary. Existing deny rules, rate limits, interface restrictions, VPN rules, application access rules, and custom SSH-port allowances can be lost. The generic `ufw allow ssh` rule also relies on the local service profile and may not match a customized SSH configuration. ### Attack Path 1. The VPS already has a deliberate UFW policy, including custom restrictions or a nonstandard SSH rule. 2. The administrator runs the bootstrap script. 3. The unconditional reset removes all existing rules. 4. The script installs only default deny-incoming, default allow-outgoing, and a generic SSH allowance. 5. Previously protected services or network boundaries lose their intended rules, or legitimate management connectivity is disrupted. ### Impact Assessment This issue requires an administrator to run the script and does not directly grant an attacker root privileges. However, it can remove defense-in-depth controls, cause service exposure when applications later add allowances, disrupt production connectivity, or lock administrators out of hosts using nonstandard SSH configurations. All chan ...[truncated 74 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/bootstrap.sh:143
Finding

Password-store GPG key is generated without passphrase protection

Content
View full analysis
/dev/null | grep -q "pub"; then log "Setting up GPG key for secret store..." read -p "Enter email for GPG key (or press Enter for default): " GPG_EMAIL GPG_EMAIL="${GPG_EMAIL:-openclaw@localhost}" cat > /tmp/gpg-params << GPGEOF %no-protection Key-Type: RSA Key-Length: 4096 Name-Real: OpenClaw Agent Name-Email: ${GPG_EMAIL} Expire-Date: 0 %commit GPGEOF gpg --batch --gen-key /tmp/gpg-params 2>/dev/null rm -f /tmp/gpg-params pass init "${GPG_EMAIL}" 2>/dev/null || true log "GPG key + password store initialized" else ``` ### Technical Analysis The `%no-protection` directive creates the GPG private key without a passphrase. The generated key is then used to initialize `pass`, making possession of the private key sufficient to decrypt password-store entries. Filesystem permissions still provide a security boundary, but there is no second cryptographic barrier if malware, another process running as the user, an exposed backup, or an account compromise obtains the keyring. The key also has no expiration date, increasing the duration of exposure. The temporary parameter file is created at a predictable path. It does not contain the resulting private key or a password, but using a securely created temporary file would still avoid collisions and symlink-related reliability concerns. ### Attack Path 1. An attacker compromises the OpenClaw user account, reads a backup containing `.gnupg`, or otherwise obtains the private keyring. 2. The attacker imports or uses the unprotected private key. 3. No passphrase is required to perform decryption. 4. The attacker decrypts entries from the associated password store. ### Impact Assessment The attacker can decrypt every `pass` secret encrypted solely to this key. T ...[truncated 252 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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (49)

Chaining Abuse

High
Category
Tool Misuse
Confidence
99% confidence
Finding

This command chains a remote download directly into a privileged shell, eliminating any opportunity for inspection or integrity verification before execution. In a bootstrap script, that means a single upstream compromise can become immediate root-level code execution on every target VPS.

Content

Scanner excerpt · scripts/bootstrap.sh (reported line 52)May include surrounding context.

sh
log "Node.js already installed: $NODE_VER"
else
    log "Installing Node.js ${NODE_MAJOR}..."
    curl -fsSL https://deb.nodesource.com/setup_${NODE_MAJOR}.x | sudo -E bash - 2>/dev/null
    sudo apt-get install -y -qq nodejs 2>/dev/null
    log "Node.js $(node --version) installed"
fi

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

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

sh
else
        log "Installing Google Chrome..."
        wget -q -O /tmp/chrome.deb https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
        sudo dpkg -i /tmp/chrome.deb 2>/dev/null || sudo apt-get install -f -y -qq 2>/dev/null
        rm -f /tmp/chrome.deb

        # Create headless shim for OpenClaw browser tools

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · scripts/bootstrap.sh (reported line 123)May include surrounding context.

sh
else
        log "Installing Google Chrome..."
        wget -q -O /tmp/chrome.deb https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
        sudo dpkg -i /tmp/chrome.deb 2>/dev/null || sudo apt-get install -f -y -qq 2>/dev/null
        rm -f /tmp/chrome.deb

        # Create headless shim for OpenClaw browser tools

Tool Parameter Abuse

High
Category
Tool Misuse
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).

Content

Scanner excerpt · scripts/bootstrap.sh (reported line 65)May include surrounding context.

sh
log "Installing Google Chrome..."
        wget -q -O /tmp/chrome.deb https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
        sudo dpkg -i /tmp/chrome.deb 2>/dev/null || sudo apt-get install -f -y -qq 2>/dev/null
        rm -f /tmp/chrome.deb

        # Create headless shim for OpenClaw browser tools
        sudo tee /usr/local/bin/chrome-shim > /dev/null << 'SHIM'

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
97% confidence
Finding

ufw --force reset is a destructive parameter combination that wipes current firewall policy without operator review. In a remote administration scenario this can break access controls and service exposure assumptions immediately.

Content

Scanner excerpt · scripts/bootstrap.sh (reported line 91)May include surrounding context.

sh
# --- Step 5: Security baseline ----------------------------------------------
if [ "$ENABLE_FIREWALL" = "true" ]; then
    log "Configuring UFW firewall..."
    sudo ufw --force reset >/dev/null 2>&1
    sudo ufw default deny incoming >/dev/null
    sudo ufw default allow outgoing >/dev/null
    sudo ufw allow ssh >/dev/null

Tool Parameter Abuse

High
Category
Tool Misuse
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).

Content

Scanner excerpt · scripts/bootstrap.sh (reported line 154)May include surrounding context.

sh
%commit
GPGEOF
    gpg --batch --gen-key /tmp/gpg-params 2>/dev/null
    rm -f /tmp/gpg-params
    pass init "${GPG_EMAIL}" 2>/dev/null || true
    log "GPG key + password store initialized"
else

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

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

sh
fi

if [ -f "$BACKUP_ROOT/dot-env" ]; then
    cp "$BACKUP_ROOT/dot-env" "$OPENCLAW_DIR/.env"
    echo "  ✓ .env"
fi

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

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

sh
fi

if [ -f "$BACKUP_ROOT/dot-env" ]; then
    cp "$BACKUP_ROOT/dot-env" "$OPENCLAW_DIR/.env"
    echo "  ✓ .env"
fi

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 · scripts/restore.sh (reported line 103)May include surrounding context.

sh
echo "  ✓ GOG config"
fi

if [ -d "$BACKUP_ROOT/keyrings" ]; then
    mkdir -p "$HOME/.local/share/keyrings"
    cp -r "$BACKUP_ROOT/keyrings/"* "$HOME/.local/share/keyrings/" 2>/dev/null || true
    echo "  ✓ keyrings"

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 · scripts/restore.sh (reported line 105)May include surrounding context.

sh
echo "  ✓ GOG config"
fi

if [ -d "$BACKUP_ROOT/keyrings" ]; then
    mkdir -p "$HOME/.local/share/keyrings"
    cp -r "$BACKUP_ROOT/keyrings/"* "$HOME/.local/share/keyrings/" 2>/dev/null || true
    echo "  ✓ keyrings"

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 · scripts/restore.sh (reported line 106)May include surrounding context.

sh
echo "  ✓ GOG config"
fi

if [ -d "$BACKUP_ROOT/keyrings" ]; then
    mkdir -p "$HOME/.local/share/keyrings"
    cp -r "$BACKUP_ROOT/keyrings/"* "$HOME/.local/share/keyrings/" 2>/dev/null || true
    echo "  ✓ keyrings"

Credential Access

High
Category
Privilege Escalation
Confidence
84% confidence
Finding

This line copies arbitrary files from the backup's keyrings directory into the user's active keyring store without validating the archive contents, ownership, or integrity. If the backup is tampered with, an attacker can replace stored credentials or inject maliciously crafted keyring data, leading to account takeover, persistence, or application authentication against attacker-controlled secrets.

Content

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

sh
fi

if [ -d "$BACKUP_ROOT/keyrings" ]; then
    mkdir -p "$HOME/.local/share/keyrings"
    cp -r "$BACKUP_ROOT/keyrings/"* "$HOME/.local/share/keyrings/" 2>/dev/null || true
    echo "  ✓ keyrings"
fi

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill advertises shell-driven deployment and recovery actions but does not declare any explicit tool scope or permissions boundaries. In practice, this obscures that the skill can drive high-risk system modifications, making accidental or unauthorized execution of privileged commands more likely.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The restore workflow is described as restoring secrets, configs, cron state, and workspace files, but it does not prominently warn that local state may be overwritten. During recovery, an operator or agent could unintentionally replace existing credentials, jobs, or configuration, causing loss of data integrity or reintroduction of stale secrets.

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

md
# --- Step 1: System packages ------------------------------------------------
log "Installing system packages..."
sudo apt-get update -qq
sudo apt-get install -y -qq \
    build-essential curl git jq unzip wget gnupg2 \
    ca-certificates lsb-release software-properties-common \

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/bootstrap.sh (reported line 37)May include surrounding context.

sh
# --- Step 1: System packages ------------------------------------------------
log "Installing system packages..."
sudo apt-get update -qq
sudo apt-get install -y -qq \
    build-essential curl git jq unzip wget gnupg2 \
    ca-certificates lsb-release software-properties-common \

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/bootstrap.sh (reported line 38)May include surrounding context.

sh
# --- Step 1: System packages ------------------------------------------------
log "Installing system packages..."
sudo apt-get update -qq
sudo apt-get install -y -qq \
    build-essential curl git jq unzip wget gnupg2 \
    ca-certificates lsb-release software-properties-common \

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/bootstrap.sh (reported line 53)May include surrounding context.

sh
# --- Step 1: System packages ------------------------------------------------
log "Installing system packages..."
sudo apt-get update -qq
sudo apt-get install -y -qq \
    build-essential curl git jq unzip wget gnupg2 \
    ca-certificates lsb-release software-properties-common \

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/bootstrap.sh (reported line 64)May include surrounding context.

sh
# --- Step 1: System packages ------------------------------------------------
log "Installing system packages..."
sudo apt-get update -qq
sudo apt-get install -y -qq \
    build-essential curl git jq unzip wget gnupg2 \
    ca-certificates lsb-release software-properties-common \

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/bootstrap.sh (reported line 72)May include surrounding context.

sh
# --- Step 1: System packages ------------------------------------------------
log "Installing system packages..."
sudo apt-get update -qq
sudo apt-get install -y -qq \
    build-essential curl git jq unzip wget gnupg2 \
    ca-certificates lsb-release software-properties-common \

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/bootstrap.sh (reported line 92)May include surrounding context.

sh
# --- Step 1: System packages ------------------------------------------------
log "Installing system packages..."
sudo apt-get update -qq
sudo apt-get install -y -qq \
    build-essential curl git jq unzip wget gnupg2 \
    ca-certificates lsb-release software-properties-common \

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/bootstrap.sh (reported line 93)May include surrounding context.

sh
# --- Step 1: System packages ------------------------------------------------
log "Installing system packages..."
sudo apt-get update -qq
sudo apt-get install -y -qq \
    build-essential curl git jq unzip wget gnupg2 \
    ca-certificates lsb-release software-properties-common \

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/bootstrap.sh (reported line 94)May include surrounding context.

sh
# --- Step 1: System packages ------------------------------------------------
log "Installing system packages..."
sudo apt-get update -qq
sudo apt-get install -y -qq \
    build-essential curl git jq unzip wget gnupg2 \
    ca-certificates lsb-release software-properties-common \

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/bootstrap.sh (reported line 95)May include surrounding context.

sh
# --- Step 1: System packages ------------------------------------------------
log "Installing system packages..."
sudo apt-get update -qq
sudo apt-get install -y -qq \
    build-essential curl git jq unzip wget gnupg2 \
    ca-certificates lsb-release software-properties-common \

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/bootstrap.sh (reported line 101)May include surrounding context.

sh
# --- Step 1: System packages ------------------------------------------------
log "Installing system packages..."
sudo apt-get update -qq
sudo apt-get install -y -qq \
    build-essential curl git jq unzip wget gnupg2 \
    ca-certificates lsb-release software-properties-common \

Static analysis

No suspicious patterns detected.