Back to skill

Security audit

Gateway Health Monitor

Security checks for vulnerabilities and agentic risk

Overview

This skill is aimed at fixing OpenClaw gateway stability, but it installs a persistent macOS watcher and recommends system-level changes without enough rollback or scoping safeguards.

Review before installing. The diagnostic scripts are mostly local checks, but running the patcher installs a persistent macOS LaunchAgent that keeps changing the OpenClaw gateway plist, and the Power Nap fix changes a system-wide setting. Install only if you are comfortable managing launchd services, first back up the affected plist, record current pmset values, and plan how to disable and remove the patcher later.

Vulnerability Patterns
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • 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 (1)

T06 · System Persistence

Error
Location
scripts/install-patcher.sh:14
Finding

Persistent macOS LaunchAgent Installation

Content
View full analysis

Vulnerability Details

File Location: scripts/install-patcher.sh, lines 14–42
Vulnerability Type: Persistent startup service installation
Risk Level: High

Vulnerable Code

bash
cat > "$PATCHER_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.plist-patcher</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/bash</string>
        <string>$PATCHER_SCRIPT</string>
    </array>
    <key>WatchPaths</key>
    <array>
        <string>$PLIST_TO_WATCH</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>StandardOutPath</key>
    <string>$LOG_DIR/plist-patcher.log</string>
    <key>StandardErrorPath</key>
    <string>$LOG_DIR/plist-patcher.err.log</string>
</dict>
</plist>
EOF

# Load the patcher
launchctl bootout "gui/$(id -u)/ai.openclaw.plist-patcher" 2>/dev/null || true
launchctl bootstrap "gui/$(id -u)" "$PATCHER_PLIST"

The persistent agent invokes the following modification logic from scripts/patch-plist.sh, lines 10–25:

bash
[ ! -f "$PLIST" ] && exit 0

# ExitTimeOut: force-kill after 10s if shutdown hangs
if ! plutil -p "$PLIST" 2>/dev/null | grep -q '"ExitTimeOut"'; then
    plutil -insert ExitTimeOut -integer 10 "$PLIST" 2>/dev/null && CHANGED=1
fi

# ProcessType: Interactive prevents launchd from delaying restarts
if ! plutil -p "$PLIST" 2>/dev/null | grep -q '"ProcessType"'; then
    plutil -insert ProcessType -string "Interactive" "$PLIST" 2>/dev/null && CHANGED=1
fi

# LowPriorityBackgroundIO: prevent IO throttling
if ! plutil -p "$PLIST" 2>/dev/null | grep -q '"LowPriorityBackgroundIO"'; then
    plutil -insert LowPriorityBackgroundIO -bool false "$PLIST" 2>/dev/null && CHANGED=1
fi

Technical Analysis

The installer creates ~/Library/LaunchAgents/ai.openclaw.plist-patcher.plist and registers it in ...[truncated 2244 chars]

Remediation
View remediation

Remediation Suggestions

  1. Do not install or activate a persistent LaunchAgent by default. Prefer an explicit, one-time plist patch where operationally possible.
  2. Require informed opt-in immediately before installation and clearly state that the agent survives the current Skill run and may run during future sessions.
  3. Copy the patcher into a dedicated, user-owned application-support directory instead of executing it from the mutable Skill source directory.
  4. Validate ownership and permissions for the installed script and LaunchAgent. Reject symlinks and files writable by other users.
  5. Use restrictive permissions, such as user-only write access, on the installed script, plist, and log directory.
  6. Validate the generated plist with plutil -lint before bootstrapping it.
  7. Provide and document an uninstall procedure that runs launchctl bootout and removes both the LaunchAgent plist and installed script.
  8. Consider integrity validation of the installed script before execution or updates.
  9. Avoid continually overriding administrator or user configuration. Patch only expected files and values, and log or request approval before replacing conflicting settings.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (62)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The skill presents itself as troubleshooting gateway stability, but it also establishes a persistent launchd WatchPaths-based auto-patching mechanism. That is a material behavior expansion because it installs ongoing system automation beyond a one-time diagnosis, which can surprise users and create long-lived configuration drift.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The skill presents itself as troubleshooting gateway stability, but it also establishes a persistent launchd WatchPaths-based auto-patching mechanism. That is a material behavior expansion because it installs ongoing system automation beyond a one-time diagnosis, which can surprise users and create long-lived configuration drift.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
96% confidence
Finding

The skill instructs users to run multiple shell commands and scripts, but it does not declare any tool scope or allowed-tools boundary. That weakens reviewability and consent because a caller cannot easily tell in advance that shell execution and system modification are part of the skill's behavior.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger phrases are broad enough to match ordinary support conversations such as 'disconnected' or 'gateway down.' Over-broad activation can cause the wrong skill to engage and suggest system-altering commands in contexts where a narrower diagnostic flow would be safer.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
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.

Content

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

md
**Symptoms**: Gateway restarts every 5-7 minutes. Log shows `restartReason=config.patch` with `plugins.installs.*.resolvedAt`.

**Cause**: Plugins re-resolve on every boot → write new timestamps to `openclaw.json` → config watcher detects "change" → triggers deferred restart → SIGTERM → repeat.

**Fix**: Set `gateway.reload.mode` to `"hot"`:

Session Persistence

Medium
Category
Rogue Agent
Confidence
90% confidence
Finding

The skill instructs users to modify LaunchAgent plist keys that affect process classification and restart behavior. Because launchd plist changes are persistent across sessions and alter how the service is treated by the OS, they create enduring system behavior changes that deserve explicit disclosure and safeguards.

Content

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

Cause: After many restarts (10+/day), macOS marks the job as low-priority and delays restarts via App Nap / Power Nap logic.

Fix: Add these keys to the launchd plist (~/Library/LaunchAgents/ai.openclaw.gateway.plist):

xml
<key>ProcessType</key>

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill recommends editing launchd plist keys and reloading the service without warning about side effects on login-session services, process priority, or service availability. Unwarned system changes can cause unintended persistence, unstable restarts, or masking of deeper faults while giving users little opportunity to assess risk.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
93% confidence
Finding

The bootout/bootstrap commands reload a LaunchAgent from a user-controlled plist path, causing persistent service behavior changes and immediate service lifecycle effects. In the context of a support skill, that is risky because it encourages service re-registration without emphasizing verification of the plist contents or the long-term persistence implications.

Content

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

bash
launchctl bootout gui/$(id -u)/ai.openclaw.gateway
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/ai.openclaw.gateway.plist

Note: openclaw gateway start overwrites the plist. Use the patcher script (below) to auto-reapply.

Session Persistence

Medium
Category
Rogue Agent
Confidence
95% confidence
Finding

This note explicitly states that the gateway start process overwrites the plist and recommends an auto-reapply mechanism. That introduces deliberate persistence of modified service settings, increasing the chance of hidden long-term changes or conflict with upstream service management.

Content

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

launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/ai.openclaw.gateway.plist

text

**Note**: `openclaw gateway start` overwrites the plist. Use the patcher script (below) to auto-reapply.

### 3. Hung Shutdown

Session Persistence

Medium
Category
Rogue Agent
Confidence
88% confidence
Finding

Setting ExitTimeOut in a LaunchAgent plist is a persistent service-management change. While not inherently malicious, it changes future termination behavior and can force-kill the gateway, which may affect data integrity or obscure shutdown bugs if applied without caution.

Content

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

Symptoms: Gateway receives SIGTERM but doesn't exit. launchd can't restart because old PID still alive.

Fix: Set ExitTimeOut in the plist:

xml
<key>ExitTimeOut</key>

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The recommendation to disable Power Nap uses sudo and changes a system-wide power management setting, but the skill does not explain the broader impact on battery usage, sleep behavior, or managed-device policy compliance. Users may apply a privileged workaround that persists beyond the gateway issue and affects the whole machine.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
97% confidence
Finding

The skill includes a sudo command that modifies global macOS power settings. Privileged commands are inherently risky in support content because they increase blast radius and can normalize elevated execution without sufficient justification, review, or rollback guidance.

Content

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

md
**Check**: `pmset -g | grep powernap`

**Fix**: `sudo pmset -a powernap 0`

## Plist Auto-Patcher

Session Persistence

Medium
Category
Rogue Agent
Confidence
98% confidence
Finding

The skill proposes using a script as a launchd WatchPaths agent to automatically reapply modifications whenever the gateway plist changes. This is a clear persistent automation mechanism that continuously monitors and alters system service configuration, expanding the blast radius well beyond a one-time troubleshooting step.

Content

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

Plist Auto-Patcher

Since openclaw gateway start overwrites the plist, use scripts/patch-plist.sh as a launchd WatchPaths agent:

bash
# Install the patcher

Session Persistence

Medium
Category
Rogue Agent
Confidence
98% confidence
Finding

This line confirms that installing the patcher creates a launchd agent that watches the gateway plist and re-adds keys after any overwrite. That is durable self-reinstating behavior, which can conceal configuration drift, resist normal service management, and persist beyond the user's immediate troubleshooting intent.

Content

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

bash scripts/install-patcher.sh

text

This creates a launchd agent that watches the gateway plist and re-adds `ExitTimeOut`, `ProcessType`, and `LowPriorityBackgroundIO` within seconds of any overwrite.

## Monitoring

Session Persistence

Medium
Category
Rogue Agent
Confidence
86% confidence
Finding

Recommending persistent plist keys such as ThrottleInterval and KeepAlive normalizes long-lived service-policy changes without discussing their persistence or failure modes. In context, this is less dangerous than the WatchPaths agent, but it still changes future launch behavior and may create unexpected restart patterns or resource use.

Content

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

}

text

Plus plist keys: `ExitTimeOut=10`, `ProcessType=Interactive`, `LowPriorityBackgroundIO=false`, `ThrottleInterval=1`, `KeepAlive=true`.

## Troubleshooting Reference

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

sh
echo "   Power Nap: $POWERNAP (0=disabled, 1=enabled)"
echo "   Sleep: $SLEEP (0=never)"
if [ "$POWERNAP" = "1" ]; then
    echo "⚠️  Power Nap enabled — may delay restarts. Fix: sudo pmset -a powernap 0"
    ISSUES=$((ISSUES + 1))
fi
echo ""

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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/diagnose.sh (reported line 7)May include surrounding context.

sh
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PATCHER_SCRIPT="$SCRIPT_DIR/patch-plist.sh"
PLIST_TO_WATCH="$HOME/Library/LaunchAgents/ai.openclaw.gateway.plist"
PATCHER_PLIST="$HOME/Library/LaunchAgents/ai.openclaw.plist-patcher.plist"
LOG_DIR="$HOME/.openclaw/logs"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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/diagnose.sh (reported line 59)May include surrounding context.

sh
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PATCHER_SCRIPT="$SCRIPT_DIR/patch-plist.sh"
PLIST_TO_WATCH="$HOME/Library/LaunchAgents/ai.openclaw.gateway.plist"
PATCHER_PLIST="$HOME/Library/LaunchAgents/ai.openclaw.plist-patcher.plist"
LOG_DIR="$HOME/.openclaw/logs"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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/diagnose.sh (reported line 61)May include surrounding context.

sh
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PATCHER_SCRIPT="$SCRIPT_DIR/patch-plist.sh"
PLIST_TO_WATCH="$HOME/Library/LaunchAgents/ai.openclaw.gateway.plist"
PATCHER_PLIST="$HOME/Library/LaunchAgents/ai.openclaw.plist-patcher.plist"
LOG_DIR="$HOME/.openclaw/logs"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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/diagnose.sh (reported line 62)May include surrounding context.

sh
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PATCHER_SCRIPT="$SCRIPT_DIR/patch-plist.sh"
PLIST_TO_WATCH="$HOME/Library/LaunchAgents/ai.openclaw.gateway.plist"
PATCHER_PLIST="$HOME/Library/LaunchAgents/ai.openclaw.plist-patcher.plist"
LOG_DIR="$HOME/.openclaw/logs"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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/diagnose.sh (reported line 70)May include surrounding context.

sh
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PATCHER_SCRIPT="$SCRIPT_DIR/patch-plist.sh"
PLIST_TO_WATCH="$HOME/Library/LaunchAgents/ai.openclaw.gateway.plist"
PATCHER_PLIST="$HOME/Library/LaunchAgents/ai.openclaw.plist-patcher.plist"
LOG_DIR="$HOME/.openclaw/logs"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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/install-patcher.sh (reported line 7)May include surrounding context.

sh
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PATCHER_SCRIPT="$SCRIPT_DIR/patch-plist.sh"
PLIST_TO_WATCH="$HOME/Library/LaunchAgents/ai.openclaw.gateway.plist"
PATCHER_PLIST="$HOME/Library/LaunchAgents/ai.openclaw.plist-patcher.plist"
LOG_DIR="$HOME/.openclaw/logs"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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/install-patcher.sh (reported line 8)May include surrounding context.

sh
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PATCHER_SCRIPT="$SCRIPT_DIR/patch-plist.sh"
PLIST_TO_WATCH="$HOME/Library/LaunchAgents/ai.openclaw.gateway.plist"
PATCHER_PLIST="$HOME/Library/LaunchAgents/ai.openclaw.plist-patcher.plist"
LOG_DIR="$HOME/.openclaw/logs"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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/install-patcher.sh (reported line 16)May include surrounding context.

sh
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PATCHER_SCRIPT="$SCRIPT_DIR/patch-plist.sh"
PLIST_TO_WATCH="$HOME/Library/LaunchAgents/ai.openclaw.gateway.plist"
PATCHER_PLIST="$HOME/Library/LaunchAgents/ai.openclaw.plist-patcher.plist"
LOG_DIR="$HOME/.openclaw/logs"

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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/install-patcher.sh (reported line 45)May include surrounding context.

sh
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PATCHER_SCRIPT="$SCRIPT_DIR/patch-plist.sh"
PLIST_TO_WATCH="$HOME/Library/LaunchAgents/ai.openclaw.gateway.plist"
PATCHER_PLIST="$HOME/Library/LaunchAgents/ai.openclaw.plist-patcher.plist"
LOG_DIR="$HOME/.openclaw/logs"