Back to skill

Security audit

Failover Gateway Pub

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a legitimate failover setup guide, but it needs Review because it installs a persistent root-level monitor and uses unverified remote installer commands.

Review before installing on a real server. Prefer verified package repositories or pinned checksums instead of curl-pipe installers, run the monitor under a dedicated least-privilege account with systemd hardening, avoid broad sudo access, use authenticated health checks, and treat optional secret rsync as sensitive production credential handling.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (5)

T03 · Remote Payload Retrieval and Execution

Error
Location
SKILL.md:71
Finding
Remote Tailscale Installer Is Executed Without Integrity Verification<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:71` **Vulnerability Type**: Remote payload retrieval and immediate shell execution **Risk Level**: High ### Vulnerable Code ```bash curl -fsSL https://tailscale.com/install.sh | sh ``` ### Technical Analysis The installation instructions pipe content retrieved from an external URL directly into a shell. The downloaded bytes are not reviewed locally and are not validated using a pinned cryptographic digest or an independently verified signature. Although `tailscale.com` is the expected vendor domain, the effective code executed during installation can change after this Skill has been reviewed. The surrounding provisioning instructions include administrative operations, so users may execute this command in a root or otherwise privileged shell. ### Attack Path 1. An attacker compromises the remote installer, its hosting infrastructure, or an authorized publishing account. 2. Alternatively, the delivery path supplies unexpected content despite the URL appearing legitimate. 3. A user follows the Skill instructions and executes the `curl | sh` pipeline with provisioning privileges. 4. The shell immediately executes the modified content without an integrity check or review step. 5. The payload can alter the operating system, install additional persistence, access local credentials, or compromise the standby gateway. ### Impact Assessment If run as root, the retrieved payload receives arbitrary root-level command execution on the standby VPS. It could modify any local file, create users or services, access gateway configuration and credentials, intercept failover operations, or use the server as a pivot point. No evidence shows that the current vendor installer is malicious. The vulnerability is the mutable and unverified remote execution mechanism. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not pipe downloaded content directly into a shell. 2. Prefer a vendor-supported package repository whose metadata and packages are cryptographically signed. 3. If a script is required, download it to a local file before execution. 4. Pin a reviewed release and verify an expected SHA-256 digest or vendor signature through an independent trust channel. 5. Inspect the verified script and execute it with only the privileges required by the installation step. 6. Record the verified release and digest in the deployment documentation to make installation reproducible. ]]>

T03 · Remote Payload Retrieval and Execution

Error
Location
SKILL.md:79
Finding
Remote NVM Installer Is Executed Without Cryptographic Verification<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:79` **Vulnerability Type**: Remote payload retrieval and immediate shell execution **Risk Level**: High ### Vulnerable Code ```bash curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash ``` ### Technical Analysis The command retrieves an installer from GitHub-hosted content and immediately executes it with Bash. The URL references an apparent NVM version, but the downloaded bytes are not checked against a pinned digest or signature. Using a recognizable GitHub organization and version does not eliminate supply-chain risk. A compromised repository, maintainer account, tag, or hosting path could change the payload that is effectively executed by users following these instructions. ### Attack Path 1. An attacker compromises the repository, publishing account, referenced tag, or content-delivery infrastructure. 2. The hosted `install.sh` is replaced or causes additional attacker-controlled code to be retrieved. 3. The standby operator executes the documented pipeline as the `openclaw` user. 4. Bash executes the modified installer without local verification. 5. The payload modifies the user's shell initialization, NVM installation, OpenClaw workspace, or credentials accessible to that account. 6. Because the account is added to the `sudo` group earlier in the instructions, stolen credentials or unsafe sudo configuration could facilitate further privilege escalation. ### Impact Assessment The direct impact is arbitrary code execution with the privileges of the `openclaw` account. That account can access the OpenClaw workspace, user configuration, messaging credentials, Git credentials, and any cached failover secrets available to it. Depending on sudo policy and credential availability, broader system compromise may also become possible. No evidence shows that the referenced NVM installer is currently malicious. The issue is execution of mutable remote content without ...[truncated 40 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Download the installer as a local file rather than piping it to Bash. 2. Pin the source to a reviewed immutable commit instead of relying only on a tag. 3. Publish and verify an expected SHA-256 digest or a trusted release signature. 4. Review the verified installer before execution. 5. Run it as the unprivileged `openclaw` user and avoid granting that account broad sudo access unless operationally necessary. 6. Consider installing a pinned Node.js package from a signed operating-system or vendor repository instead of using a remotely executed bootstrap script. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
SKILL.md:142
Finding
Boot-Persistent Health Monitor Runs With Unrestricted Root Privileges<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:142-186` **Vulnerability Type**: Persistent privileged system service exceeding least privilege **Risk Level**: High ### Vulnerable Code ```ini [Unit] Description=OpenClaw Failover Health Monitor After=network-online.target tailscaled.service Wants=network-online.target [Service] Type=simple ExecStart=/usr/local/bin/openclaw-health-monitor.sh Restart=always RestartSec=10 [Install] WantedBy=multi-user.target ``` ```bash sudo systemctl daemon-reload sudo systemctl enable openclaw-health-monitor sudo systemctl start openclaw-health-monitor # Do NOT enable openclaw.service — the monitor controls it ``` ### Technical Analysis The monitor unit does not specify a `User=` or `Group=`. A system service therefore runs as root by default. It is enabled under `multi-user.target`, survives reboots, and is automatically restarted. Persistence is explicitly documented and is relevant to automatic failover. However, unrestricted root execution exceeds the minimum privilege needed for health polling, Git synchronization, secret synchronization, and control of one designated gateway service. The unit also lacks common systemd sandboxing controls. The monitor executable is copied into `/usr/local/bin` and then continuously trusted by systemd. Modification of that script or unit by an attacker with a suitable write primitive would provide persistent root execution on every restart or reboot. ### Attack Path 1. An attacker obtains a method to replace or modify `/usr/local/bin/openclaw-health-monitor.sh`, alter the unit, or compromise the package or deployment process that supplies the script. 2. The attacker inserts commands into the trusted monitor. 3. The service is restarted automatically, manually, or during the next system boot. 4. Systemd executes the altered monitor as root. 5. The malicious commands persist across sessions and can take complete control of the standby server. ### Impact Assessment Su ...[truncated 567 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Run the monitor under a dedicated unprivileged service account using explicit `User=` and `Group=` directives. 2. Grant only narrowly scoped permission to start, stop, and query `openclaw.service`, using a constrained root helper, D-Bus policy, or tightly limited sudoers rules. 3. Ensure the unit and executable are owned by root and are not writable by the monitor account or the `openclaw` account. 4. Add systemd hardening directives appropriate to the required file access, such as: ```ini NoNewPrivileges=true PrivateTmp=true ProtectSystem=strict ProtectHome=true ProtectKernelTunables=true ProtectKernelModules=true ProtectControlGroups=true RestrictSUIDSGID=true CapabilityBoundingSet= LockPersonality=true ``` 5. Explicitly grant only the workspace and secret-directory access needed by the synchronization operations. 6. Verify the installed monitor against a pinned digest during deployment and before service startup. 7. Audit service changes and restrict who can invoke `systemctl daemon-reload` or modify `/etc/systemd/system`. ]]>

T08 · Insecure Dependencies

Warning
Location
SKILL.md:79
Finding
Unpinned Node.js and Global OpenClaw Installation Expose the Deployment to Supply-Chain Changes<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:79-82` **Vulnerability Type**: Unpinned third-party dependency installation **Risk Level**: Medium ### Vulnerable Code ```bash curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash source ~/.bashrc nvm install --lts npm install -g openclaw ``` ### Technical Analysis `nvm install --lts` resolves a moving Node.js release, while `npm install -g openclaw` installs the registry version selected by npm at deployment time. The OpenClaw dependency is not pinned to a reviewed version or integrity value, and a global npm installation can execute package lifecycle scripts. As a result, two deployments performed from the same instructions can install different code. A compromised package release, maintainer account, or registry artifact could introduce arbitrary installation-time behavior. This finding does not establish that the current Node.js or OpenClaw packages are malicious. It identifies a non-reproducible and insufficiently verified dependency chain. ### Attack Path 1. An attacker compromises a relevant package publishing account or causes a malicious release to become the version selected by the unpinned command. 2. A user provisions or rebuilds the standby server using these instructions. 3. NVM or npm resolves the attacker-controlled or unexpectedly changed release. 4. npm installs the package globally and may execute its lifecycle scripts. 5. Attacker code executes with the privileges of the installing user and becomes part of the failover gateway runtime. ### Impact Assessment The likely initial privilege is the `openclaw` user used for installation. The installed package can access that user's OpenClaw configuration, workspace, bot tokens, Git credentials, and synchronized secrets. It also becomes the gateway process started by the system service, allowing ongoing access to gateway data and network connections. If the global npm command is instead run with ad ...[truncated 77 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin an exact reviewed Node.js version rather than the moving `--lts` alias. 2. Pin OpenClaw to an exact reviewed version, for example through an explicitly versioned package specification. 3. Verify release signatures or published integrity hashes through a trusted channel. 4. Use a lockfile or a reproducible deployment artifact that captures the full dependency graph and integrity values. 5. Review package lifecycle scripts and use `--ignore-scripts` where operationally compatible. 6. Install dependencies as an unprivileged account and avoid system-wide global installation where possible. 7. Use automated dependency monitoring, but require review and testing before version updates are deployed. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/health-monitor.sh:24
Finding
Failover State Is Controlled by an Unauthenticated Plaintext HTTP Health Check<![CDATA[ ## Vulnerability Details **File Location**: `scripts/health-monitor.sh:24-27,68-83` **Vulnerability Type**: Unauthenticated health-check response used for failover control **Risk Level**: Medium ### Vulnerable Code ```bash check_primary() { curl -sf -o /dev/null --connect-timeout 5 \ "http://${PRIMARY_IP}:${PRIMARY_PORT}/health" 2>/dev/null } ``` ```bash while true; do if check_primary; then if [ "$PROMOTED" = true ]; then demote fi FAIL_COUNT=0 else if [ "$PROMOTED" = false ]; then FAIL_COUNT=$((FAIL_COUNT + 1)) log "Primary check FAILED (${FAIL_COUNT}/${FAIL_THRESHOLD})" if [ "$FAIL_COUNT" -ge "$FAIL_THRESHOLD" ]; then promote fi fi fi sleep "$CHECK_INTERVAL" done ``` ### Technical Analysis The monitor uses plaintext HTTP and treats any response accepted by `curl -f` as proof that the primary gateway is healthy. It discards the response body and performs no application-level authentication, expected-content validation, or cryptographic endpoint verification. Tailscale normally encrypts tailnet traffic, which reduces exposure when the configured address is exclusively reached through a correctly secured tailnet. However, the script also documents the address as a Tailscale or LAN address. On an untrusted LAN, with unsafe routing, or after compromise of another reachable host, endpoint spoofing or traffic manipulation may affect the failover decision. A forged successful response can suppress promotion or force a promoted standby to demote. Blocking health traffic can cause promotion while the primary remains operational. ### Attack Path 1. An attacker gains a position from which traffic to the configured primary address can be intercepted, redirected, blocked, or impersonated. 2. To suppress failover, the attacker returns any successful HTTP status at `/health`, even when the real primary is unavailab ...[truncated 815 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Use authenticated HTTPS with strict certificate and hostname verification when the health endpoint supports it. 2. If Tailscale is required, enforce access through the tailnet and validate the expected peer identity rather than permitting fallback to an untrusted LAN path. 3. Require a narrowly scoped health-check credential or signed challenge-response mechanism. 4. Validate an exact expected response body and content type rather than accepting any successful HTTP status. 5. Set explicit total request timeouts in addition to the connection timeout. 6. Consider multiple independent health signals before promotion or demotion. 7. Add hysteresis and a recovery threshold so a single successful response cannot immediately demote an active standby. 8. Log endpoint identity and validation failures without logging authentication secrets. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
Findings (18)

External Script Fetching

High
Category
Supply Chain
Content
# Copy your SSH key to openclaw user

# Install Tailscale
curl -fsSL https://tailscale.com/install.sh | sh
tailscale up --hostname=your-failover-name
```
Confidence
97% confidence
Finding
The guide instructs users to fetch and execute a remote installer script directly from the network using a shell pipe. If the source, transport, DNS, or upstream account is compromised, arbitrary code runs immediately on the standby host, likely with elevated privileges during setup.

Chaining Abuse

High
Category
Tool Misuse
Content
# Copy your SSH key to openclaw user

# Install Tailscale
curl -fsSL https://tailscale.com/install.sh | sh
tailscale up --hostname=your-failover-name
```
Confidence
98% confidence
Finding
Piping curl output directly into sh removes opportunities for inspection and compounds the supply-chain risk by turning a network response into immediate code execution. In a deployment guide for infrastructure nodes, this is especially dangerous because compromise of the failover host can undermine resilience and expose secrets or tokens.

Chaining Abuse

High
Category
Tool Misuse
Content
```bash
# As openclaw user
curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
source ~/.bashrc
nvm install --lts
npm install -g openclaw
Confidence
96% confidence
Finding
Using curl piped to bash for the nvm install similarly enables instant execution of unverified remote content. The risk is somewhat lower than a root-level installer if run as an unprivileged user, but it can still compromise the openclaw account, workspace, tokens, and subsequent operational workflows.

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill contains multiple shell commands, privileged operations, and service-management steps but does not declare any tool scope or permissions boundary. In an agent ecosystem, this increases the chance that automation executes impactful system changes without explicit user awareness or policy enforcement.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
Copy the included `scripts/health-monitor.sh` to the standby:

```bash
sudo cp health-monitor.sh /usr/local/bin/openclaw-health-monitor.sh
sudo chmod +x /usr/local/bin/openclaw-health-monitor.sh
```
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
Copy the included `scripts/health-monitor.sh` to the standby:

```bash
sudo cp health-monitor.sh /usr/local/bin/openclaw-health-monitor.sh
sudo chmod +x /usr/local/bin/openclaw-health-monitor.sh
```
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
Copy the included `scripts/health-monitor.sh` to the standby:

```bash
sudo cp health-monitor.sh /usr/local/bin/openclaw-health-monitor.sh
sudo chmod +x /usr/local/bin/openclaw-health-monitor.sh
```
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
Copy the included `scripts/health-monitor.sh` to the standby:

```bash
sudo cp health-monitor.sh /usr/local/bin/openclaw-health-monitor.sh
sudo chmod +x /usr/local/bin/openclaw-health-monitor.sh
```
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
Copy the included `scripts/health-monitor.sh` to the standby:

```bash
sudo cp health-monitor.sh /usr/local/bin/openclaw-health-monitor.sh
sudo chmod +x /usr/local/bin/openclaw-health-monitor.sh
```
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
Copy the included `scripts/health-monitor.sh` to the standby:

```bash
sudo cp health-monitor.sh /usr/local/bin/openclaw-health-monitor.sh
sudo chmod +x /usr/local/bin/openclaw-health-monitor.sh
```
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
Copy the included `scripts/health-monitor.sh` to the standby:

```bash
sudo cp health-monitor.sh /usr/local/bin/openclaw-health-monitor.sh
sudo chmod +x /usr/local/bin/openclaw-health-monitor.sh
```
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
```bash
sudo systemctl daemon-reload
sudo systemctl enable openclaw-health-monitor
sudo systemctl start openclaw-health-monitor
# Do NOT enable openclaw.service — the monitor controls it
```
Confidence
80% 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
90% confidence
Finding
The test procedure tells the operator to stop the primary gateway to simulate failure but does not clearly warn that this intentionally disrupts production service and may trigger user-visible downtime or message loss. In a high-availability guide, destructive validation is legitimate, but omitting an explicit disruption warning makes accidental unsafe execution more likely.

External Transmission

Medium
Category
Data Exfiltration
Content
log() { logger -t "$LOG_TAG" "$1"; echo "$(date -Is) $1"; }

check_primary() {
    curl -sf -o /dev/null --connect-timeout 5 \
        "http://${PRIMARY_IP}:${PRIMARY_PORT}/health" 2>/dev/null
}
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
# Pull latest workspace from git (best effort)
    if [ -d "$WORKSPACE/.git" ]; then
        cd "$WORKSPACE"
        sudo -u "$OPENCLAW_USER" git pull --ff-only 2>&1 | logger -t "$LOG_TAG" \
            || log "WARNING: git pull failed, using last sync"
    fi
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
# Pull latest workspace from git (best effort)
    if [ -d "$WORKSPACE/.git" ]; then
        cd "$WORKSPACE"
        sudo -u "$OPENCLAW_USER" git pull --ff-only 2>&1 | logger -t "$LOG_TAG" \
            || log "WARNING: git pull failed, using last sync"
    fi
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
# Sync secrets from remote host (optional, best effort)
    if [ -n "$SECRETS_HOST" ]; then
        sudo -u "$OPENCLAW_USER" rsync -a "${SECRETS_HOST}:~/.secrets/" \
            "/home/${OPENCLAW_USER}/.secrets/" 2>&1 | logger -t "$LOG_TAG" \
            || log "WARNING: secrets sync failed, using cached"
    fi
Confidence
90% confidence
Finding
The script automatically rsyncs secrets from a remote host during promotion without any visible integrity verification, host key pinning, or restriction on what is synchronized. In a failover context this is more dangerous because compromise, misconfiguration, or spoofing of SECRETS_HOST could poison the standby with attacker-controlled credentials or overwrite local secret material right before service startup.

External Script Fetching

Low
Category
Supply Chain
Content
```bash
# As openclaw user
curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
source ~/.bashrc
nvm install --lts
npm install -g openclaw
Confidence
94% confidence
Finding
The skill also fetches and executes the nvm installer directly from a remote URL. Although common in practice, it still creates a supply-chain execution path where a compromised upstream or network path can run arbitrary code on the target machine.

Static analysis

No suspicious patterns detected.