Back to skill

Security audit

Gateway Keepalive

Security checks for vulnerabilities and agentic risk

Overview

The skill’s keepalive purpose is coherent, but it installs persistent background services and has unsafe configuration handling that can repeatedly run user-level shell code or overwrite local OpenClaw configuration.

Review carefully before installing. This skill will create persistent macOS LaunchAgents, run a shell recovery script every minute, restart OpenClaw Gateway, and overwrite OpenClaw configuration from a backup after repeated failures. Treat the Telegram option as sensitive credential storage, secure or avoid keepalive.conf, and prefer a version that parses config without source and requires explicit user action before updating the golden backup.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/health-check-recovery.sh:21
Finding
Recurring Arbitrary Command Execution Through Sourced Configuration<![CDATA[ ## Vulnerability Details **File Location**: `scripts/health-check-recovery.sh:21-30` **Related Location**: `scripts/install.sh:69-87` **Vulnerability Type**: Shell command injection through unsafe configuration loading **Risk Level**: High ### Vulnerable Code ```bash CONFIG_FILE="$HOME/.openclaw/config/keepalive.conf" # Telegram notification configuration (read from configuration file) if [ -f "$CONFIG_FILE" ]; then source "$CONFIG_FILE" fi ``` The installer places unvalidated interactive input into the sourced file: ```bash read -r BOT_TOKEN echo "Please enter Telegram Chat ID (format: 123456789):" read -r CHAT_ID cat > ~/.openclaw/config/keepalive.conf <<EOF # OpenClaw Keepalive configuration file # Automatically generated by the installer # Telegram notification configuration TELEGRAM_BOT_TOKEN="$BOT_TOKEN" TELEGRAM_CHAT_ID="$CHAT_ID" EOF ``` ### Technical Analysis The `source` command evaluates the complete contents of `keepalive.conf` as shell code. The file is intended to contain two data values, but no parser, key allowlist, syntax validation, or character validation separates configuration data from executable shell syntax. The installer also writes user-provided values directly into shell assignment statements. A value containing a closing quotation mark followed by a shell command can generate a syntactically valid malicious configuration. For example, an input shaped like: ```text "; touch "$HOME/.openclaw/injected"; # ``` can result in executable content when the recovery script later sources the file. The health-check script is registered as a LaunchAgent and runs every 60 seconds. Consequently, modification of this configuration file provides a recurring execution path rather than a one-time injection. This does not cross into root privileges because the LaunchAgent is installed in the current user's GUI domain. Nevertheless, it permits arbitrary command execution with all permissions of the logged-in user. ### Att ...[truncated 1272 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `source "$CONFIG_FILE"` entirely. 2. Store configuration in a non-executable format such as JSON or plist. 3. Parse only an explicit allowlist of keys: - `TELEGRAM_BOT_TOKEN` - `TELEGRAM_CHAT_ID` 4. Reject duplicate keys, unknown fields, newlines, control characters, shell metacharacters, and malformed values. 5. Validate the Chat ID as an expected numeric identifier and validate the token against a conservative format before storage. 6. Pass parsed values directly to `curl`; never reconstruct shell syntax or use `eval`. 7. Verify that the configuration is a regular file owned by the current user and is not a symbolic link before reading it. 8. If shell-format configuration must be retained, use a strict inert parser that extracts values without evaluating the file. Merely filtering some shell characters before using `source` is not a robust fix. 9. Add regression tests using quotation marks, semicolons, command substitutions, backticks, newlines, and malformed assignments to confirm that none are executed. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/install.sh:61
Finding
Telegram Bot Credential Stored Without Restrictive File Permissions<![CDATA[ ## Vulnerability Details **File Location**: `scripts/install.sh:61-85` **Vulnerability Type**: Insecure plaintext secret storage **Risk Level**: Medium ### Vulnerable Code ```bash # Create configuration file if it does not exist mkdir -p ~/.openclaw/config if [ ! -f ~/.openclaw/config/keepalive.conf ]; then echo "Creating configuration file..." cp ~/.openclaw/skills/gateway-keepalive/config/keepalive.conf.example ~/.openclaw/config/keepalive.conf # Ask whether Telegram notifications should be configured echo "" echo "Telegram notification configuration (optional)" echo "Configure Telegram notifications? (y/N)" read -r RESPONSE if [[ $RESPONSE =~ ^[Yy]$ ]]; then echo "Enter Telegram Bot Token:" read -r BOT_TOKEN echo "Enter Telegram Chat ID:" read -r CHAT_ID cat > ~/.openclaw/config/keepalive.conf <<EOF # OpenClaw Keepalive configuration file # Telegram notification configuration TELEGRAM_BOT_TOKEN="$BOT_TOKEN" TELEGRAM_CHAT_ID="$CHAT_ID" EOF ``` No restrictive `umask`, `chmod`, or ownership verification is applied after the Telegram bot token is written. ### Technical Analysis The Telegram bot token is an authentication credential. It is stored in plaintext at `~/.openclaw/config/keepalive.conf`, and the resulting mode is inherited from the user's ambient umask or from the previously copied example file. Under an insufficiently restrictive umask, the file may be readable by other local accounts or processes operating under shared group permissions. The installer does not verify that the destination is a regular file owned by the current user, nor does it protect against an existing symbolic-link destination. The documentation discloses the configuration location, but it does not instruct users to protect the file or use a system credential store. ### Attack Path 1. A user enables optional Telegram notifications during installation. 2. The installer writes the bot to ...[truncated 997 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Prefer storing the bot token in macOS Keychain rather than a plaintext file. 2. If file storage is retained, set a restrictive umask before creation: ```bash umask 077 mkdir -p "$HOME/.openclaw/config" ``` 3. Create or replace the file with mode `0600`, for example using a secure temporary file followed by `install -m 600`. 4. Verify that the configuration directory and file are owned by the current user. 5. Refuse symbolic links and unexpected file types before writing. 6. Avoid placing the token in command-line arguments where it may be visible in process listings. 7. Redact credentials from console output and logs. 8. During uninstall, offer to remove the credential file explicitly and explain that it contains a secret. 9. Document token revocation and rotation procedures in case the file has previously had permissive permissions. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/health-check-recovery.sh:106
Finding
Unreliable Health Detection and Automatic Corruption of the Recovery Baseline<![CDATA[ ## Vulnerability Details **File Location**: `scripts/health-check-recovery.sh:106-110, 211-226` **Related Location**: `scripts/install.sh:115-123` **Vulnerability Type**: Unsafe automated recovery and integrity-check design **Risk Level**: Medium ### Vulnerable Code The health check searches for a process name that does not match the command installed by the LaunchAgent: ```bash check_health() { local failed=0 local reason="" # Check 1: Gateway process if ! ps aux | grep -v grep | grep -q "openclaw-gateway"; then reason="Gateway process does not exist" failed=1 fi ``` The installer launches Node using `index.js gateway`, rather than an executable named `openclaw-gateway`: ```xml <key>ProgramArguments</key> <array> <string>/opt/homebrew/opt/node/bin/node</string> <string>/opt/homebrew/lib/node_modules/openclaw/dist/index.js</string> <string>gateway</string> <string>--port</string> <string>18789</string> </array> ``` The script also overwrites the recovery baseline after every successful health check: ```bash update_golden_backup() { if check_health > /dev/null 2>&1; then cp "$CURRENT_CONFIG" "$GOLDEN_CONFIG" log "Golden backup updated because health check passed" fi } main() { rotate_log log "Starting health check" if check_health; then log "Health check passed" reset_failure update_golden_backup else reason=$(check_health) increment_failure count=$(cat "$STATE_FILE") if [ $count -ge $MAX_FAILURES ]; then log_recovery "Consecutive failures reached $count; triggering automatic recovery" trigger_recovery "$reason" else log "Failure count: $count/$MAX_FAILURES" fi fi } ``` ### Technical Analysis The recovery mechanism has two related integrity problems. First, its process test relies on an imprecise textual search for `openclaw-gateway`. The in ...[truncated 2537 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace process-name matching with authoritative service-state inspection, such as `launchctl print gui/$(id -u)/ai.openclaw.gateway`. 2. If process verification is necessary, use a trusted PID file or validate the exact executable path and arguments without broad `ps | grep` matching. 3. Preserve port and RPC checks as additional availability signals, not as configuration-integrity checks. 4. Remove automatic calls to `update_golden_backup` from routine successful health checks. 5. Update the golden baseline only through an explicit user action after configuration validation and confirmation. 6. Validate JSON syntax and required OpenClaw schema fields before accepting a new baseline. 7. Store versioned, timestamped backups and retain at least one previous validated generation. 8. Apply restrictive permissions to both current and backup configurations. 9. Use atomic copies through a securely created temporary file followed by a rename. 10. Add recovery-loop protection, such as a maximum number of recoveries within a time window and a cooldown after failed recovery. 11. Test health detection against the exact LaunchAgent command generated by the installer before enabling automatic restoration. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (77)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The skill reads process state, localhost port status, logs, backups, and state files as part of health monitoring, but this monitoring footprint is broader than the simple keepalive description implies. Even if operationally justified, undocumented enumeration and inspection of local state reduces user awareness and can expose sensitive operational data.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill reads process state, localhost port status, logs, backups, and state files as part of health monitoring, but this monitoring footprint is broader than the simple keepalive description implies. Even if operationally justified, undocumented enumeration and inspection of local state reduces user awareness and can expose sensitive operational data.

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding
The skill reads process state, localhost port status, logs, backups, and state files as part of health monitoring, but this monitoring footprint is broader than the simple keepalive description implies. Even if operationally justified, undocumented enumeration and inspection of local state reduces user awareness and can expose sensitive operational data.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The skill reads process state, localhost port status, logs, backups, and state files as part of health monitoring, but this monitoring footprint is broader than the simple keepalive description implies. Even if operationally justified, undocumented enumeration and inspection of local state reduces user awareness and can expose sensitive operational data.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
# 删除 LaunchAgent 配置文件
echo "🗑️ 删除 LaunchAgent 配置..."
rm -f ~/Library/LaunchAgents/ai.openclaw.gateway.plist
rm -f ~/Library/LaunchAgents/com.openclaw.health-check.plist

# 询问是否删除备份
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
# 删除 LaunchAgent 配置文件
echo "🗑️ 删除 LaunchAgent 配置..."
rm -f ~/Library/LaunchAgents/ai.openclaw.gateway.plist
rm -f ~/Library/LaunchAgents/com.openclaw.health-check.plist

# 询问是否删除备份
read -p "是否删除黄金备份?(y/N) " -n 1 -r
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
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
    echo "🗑️ 删除黄金备份..."
    rm -rf ~/.openclaw/backups/golden-config
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
if [[ $REPLY =~ ^[Yy]$ ]]; then
    echo "🗑️ 删除黄金备份..."
    rm -rf ~/.openclaw/backups/golden-config
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
if [[ $REPLY =~ ^[Yy]$ ]]; then
    echo "🗑️ 删除日志..."
    rm -f ~/.openclaw/logs/health-recovery.log*
    rm -f ~/.openclaw/logs/health-check.log*
    rm -f ~/.openclaw/state/recovery-count
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
if [[ $REPLY =~ ^[Yy]$ ]]; then
    echo "🗑️ 删除日志..."
    rm -f ~/.openclaw/logs/health-recovery.log*
    rm -f ~/.openclaw/logs/health-check.log*
    rm -f ~/.openclaw/state/recovery-count
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
echo "🗑️ 删除日志..."
    rm -f ~/.openclaw/logs/health-recovery.log*
    rm -f ~/.openclaw/logs/health-check.log*
    rm -f ~/.openclaw/state/recovery-count
fi

echo ""
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).

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill clearly instructs users to execute shell scripts and install persistent LaunchAgents, yet it declares no permissions or allowed tool scope. This creates a transparency and consent failure: users and any hosting platform cannot accurately understand that the skill can modify files, start background services, and run recurring shell commands.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The skill describes automatic recovery actions that can overwrite local configuration from a golden backup, restart processes, and maintain persistent agents, but it does not prominently warn about the operational impact. Automatic rollback and restart behavior can cause data loss, revert intentional configuration changes, or create service instability if triggered incorrectly.

File System Enumeration

Medium
Category
Data Exfiltration
Content
### 自动恢复失败

```bash
ls -la ~/.openclaw/backups/golden-config/
cp ~/.openclaw/backups/golden-config/openclaw.json ~/.openclaw/openclaw.json
launchctl kickstart -k gui/$(id -u)/ai.openclaw.gateway
```
Confidence
60% confidence
Finding
Code scans file system directories looking for sensitive files. This could be reconnaissance for credential theft.

File System Enumeration

Medium
Category
Data Exfiltration
Content
### 自动恢复失败

```bash
ls -la ~/.openclaw/backups/golden-config/
cp ~/.openclaw/backups/golden-config/openclaw.json ~/.openclaw/openclaw.json
launchctl kickstart -k gui/$(id -u)/ai.openclaw.gateway
```
Confidence
60% confidence
Finding
Code scans file system directories looking for sensitive files. This could be reconnaissance for credential theft.

File System Enumeration

Medium
Category
Data Exfiltration
Content
### 自动恢复失败

```bash
ls -la ~/.openclaw/backups/golden-config/
cp ~/.openclaw/backups/golden-config/openclaw.json ~/.openclaw/openclaw.json
launchctl kickstart -k gui/$(id -u)/ai.openclaw.gateway
```
Confidence
60% confidence
Finding
Code scans file system directories looking for sensitive files. This could be reconnaissance for credential theft.

Session Persistence

Medium
Category
Rogue Agent
Content
└── health-check-recovery.sh          # 健康检测脚本

~/Library/LaunchAgents/
├── ai.openclaw.gateway.plist         # Gateway LaunchAgent
└── com.openclaw.health-check.plist   # 健康检测 LaunchAgent

~/.openclaw/backups/golden-config/
Confidence
96% confidence
Finding
The skill establishes persistence via macOS LaunchAgents so it can auto-start and run health checks continuously. Persistence is a sensitive capability because it survives user sessions, continuously executes code, and can be abused or forgotten if not transparently disclosed and explicitly authorized.

Session Persistence

Medium
Category
Rogue Agent
Content
~/Library/LaunchAgents/
├── ai.openclaw.gateway.plist         # Gateway LaunchAgent
└── com.openclaw.health-check.plist   # 健康检测 LaunchAgent

~/.openclaw/backups/golden-config/
└── openclaw.json                     # 黄金备份配置
Confidence
96% confidence
Finding
The second LaunchAgent reference confirms an additional persistent background component for periodic health checks. Multiple persistent agents increase attack surface and reduce visibility if users are not clearly informed, especially when combined with auto-restart logic and config restoration.

Session Persistence

Medium
Category
Rogue Agent
Content
### Step 1: 创建黄金备份目录

```bash
mkdir -p ~/.openclaw/backups/golden-config
mkdir -p ~/.openclaw/logs
mkdir -p ~/.openclaw/state
```
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.

Session Persistence

Medium
Category
Rogue Agent
Content
### Step 1: 创建黄金备份目录

```bash
mkdir -p ~/.openclaw/backups/golden-config
mkdir -p ~/.openclaw/logs
mkdir -p ~/.openclaw/state
```
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.

Session Persistence

Medium
Category
Rogue Agent
Content
### Step 3: 创建 Gateway LaunchAgent

```bash
cat > ~/Library/LaunchAgents/ai.openclaw.gateway.plist <<'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
Confidence
90% confidence
Finding
The guide instructs users to create a LaunchAgent that automatically starts and persistently restarts a network-exposed gateway process at login. Although this appears intended for reliability, persistence mechanisms materially increase risk because they ensure the service continues running after failures and user sessions, making misconfiguration or compromise more durable.

Session Persistence

Medium
Category
Rogue Agent
Content
```bash
cat > ~/Library/LaunchAgents/ai.openclaw.gateway.plist <<'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>Label</key>
Confidence
90% confidence
Finding
This duplicate match still points to the same LaunchAgent persistence mechanism. The risk is contextual: persistent user-level service startup is not inherently malicious, but it does make any underlying gateway weakness continuously available.

Session Persistence

Medium
Category
Rogue Agent
Content
```bash
cat > ~/Library/LaunchAgents/ai.openclaw.gateway.plist <<'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>Label</key>
Confidence
90% confidence
Finding
This duplicate match still points to the same LaunchAgent persistence mechanism. The risk is contextual: persistent user-level service startup is not inherently malicious, but it does make any underlying gateway weakness continuously available.

Session Persistence

Medium
Category
Rogue Agent
Content
cat > ~/Library/LaunchAgents/ai.openclaw.gateway.plist <<'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>Label</key>
    <string>ai.openclaw.gateway</string>
Confidence
90% confidence
Finding
This finding corresponds to the declared LaunchAgent service label for the persistent gateway. In this skill context, the persistence is intentional for availability, but such mechanisms are still security-relevant because they create durable execution and automatic recovery after termination.

Session Persistence

Medium
Category
Rogue Agent
Content
<string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin</string>
    </dict>
  </dict>
</plist>
EOF
```
Confidence
88% confidence
Finding
This line closes the same persistent LaunchAgent definition. The issue is not the XML itself but the operational effect: installing a persistent auto-restarting service that may keep an exposed gateway available indefinitely.

Static analysis

No suspicious patterns detected.