Back to skill

Security audit

OpenClaw Guardian by MyClaw.ai

Security checks for vulnerabilities and agentic risk

Overview

This watchdog skill is purpose-aligned, but it can persistently and automatically change, commit, reset, and restart an OpenClaw workspace without a clear consent boundary.

Install only if you explicitly want a persistent watchdog that can modify your OpenClaw workspace. Before use, disable or gate hard reset rollback, avoid `git add -A` over sensitive workspace content, validate `OPENCLAW_CMD`, move logs/state out of shared `/tmp`, use exact service or PID-based process control, and configure Discord only if operational details may be sent to that webhook.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/guardian.sh:10
Finding

Arbitrary Command Execution Through Unvalidated OPENCLAW_CMD

Content
View full analysis
> "$LOG_FILE" 2>&1 sleep 10 if is_gateway_running; then log "doctor --fix 修复成功,Gateway 已恢复" return 0 fi return 1 } ``` ```bash nohup $OPENCLAW_CMD gateway >> "$LOG_FILE" 2>&1 & ``` ### Technical Analysis `OPENCLAW_CMD` is obtained from an environment variable and expanded as an unquoted shell command. Bash performs word splitting on its contents, allowing the value to specify an executable and attacker-selected arguments rather than only the intended OpenClaw executable. For example, an environment value such as `OPENCLAW_CMD='sh -c id'` causes the repair operation to evaluate an invocation equivalent to: ```bash sh -c id doctor --fix ``` The shell consequently runs `id` instead of the expected OpenClaw repair operation. More consequential shell commands could be supplied in the same way. The issue is reachable both during `doctor --fix` repair and during the post-rollback gateway restart. This is not an independent privilege-escalation primitive: exploitation requires the ability to influence the watchdog's startup environment. However, the injected command inherits all privileges, filesystem access, credentials, and network access of the watchdog process. ### Attack Path 1. An attacker gains the ability to set or alter the environment used to launch `guardian.sh`, such as through an insecure service definition, wrapper script, container environment, or shell startup configuration. 2. The attacker sets `OPENCLAW_CMD` to an executable and malicious argument sequence, for example `sh -c `. 3. The attacker waits for or causes `is_gateway_running` to report that t ...[truncated 883 chars]
Remediation
View remediation
&2 exit 1 } if [ ! -f "$OPENCLAW_BIN" ] || [ ! -x "$OPENCLAW_BIN" ]; then echo "Invalid OpenClaw executable" >&2 exit 1 fi "$OPENCLAW_BIN" doctor --fix >> "$LOG_FILE" 2>&1 nohup "$OPENCLAW_BIN" gateway >> "$LOG_FILE" 2>&1 & ``` ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/guardian.sh:101
Finding

Predictable Temporary Files Permit Symlink-Based File Clobbering

Content
View full analysis
> "$LOG_FILE" 2>&1 || true echo "$today" > "$last_backup_file" ``` ### Technical Analysis The script uses fixed names in the shared `/tmp` directory for its log and daily-backup state. It does not securely create these files, verify their ownership, reject symbolic links, or place them in a private directory. An attacker with local access may create one of these paths as a symbolic link before Guardian opens it. Subsequent append or truncating redirection follows the link: - `tee -a "$LOG_FILE"` and `>> "$LOG_FILE"` append Guardian-controlled output to the link target. - `echo "$today" > "$last_backup_file"` truncates and overwrites the link target with the date. The target must be writable by the Guardian process. Operating-system protections such as `fs.protected_symlinks` may block some attacks, but the implementation should not rely on optional platform behavior. ### Attack Path 1. A local attacker predicts the fixed path `/tmp/guardian-last-backup` or `/tmp/openclaw-guardian.log`. 2. Before Guardian creates or writes the file, the attacker creates a symbolic link from that path to another file writable by the Guardian account. 3. Guardian starts logging or performs its daily backup. 4. Shell redir ...[truncated 695 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/guardian.sh:31
Finding

Broad Process-Name Matching Can Terminate Unrelated Processes

Content
View full analysis
/dev/null 2>&1; then return 0 fi return 1 } ``` ```bash # 重启 Gateway pkill -f "openclaw-gateway" 2>/dev/null || true sleep 3 nohup $OPENCLAW_CMD gateway >> "$LOG_FILE" 2>&1 & ``` The documented auto-start procedure also uses broad matching in `SKILL.md`, line 69: ```bash pkill -f "guardian.sh" 2>/dev/null || true ``` ### Technical Analysis The `-f` option causes `pgrep` and `pkill` to search each process's complete command line. It does not establish that the matched process is the intended OpenClaw Gateway or Guardian instance. Consequently: - An unrelated process whose arguments contain `openclaw-gateway` can make the health check report a false positive. - Every same-user process whose command line contains `openclaw-gateway` may be terminated during rollback. - The documented startup command may terminate unrelated processes containing `guardian.sh` in their command line. The operating system normally restricts signaling processes belonging to other users, but all matching processes owned by the Guardian account are exposed. ### Attack Path 1. A legitimate or attacker-controlled process is launched under the Guardian account with `openclaw-gateway` somewhere in its command line. 2. During health checks, `pgrep -f` treats that process as proof that the real gateway is healthy, potentially suppressing repair. 3. Alternatively, a rollback is triggered. 4. `pkill -f "openclaw-gateway"` sends a termination signal to all matching processes. 5. The unrelated process is terminated, causing service disruption or loss of in-memory work. ### Impact Assessment The primary impact is local denial of service against processes owned by the Guardian user. False-positive h ...[truncated 262 chars]
Remediation
View remediation
/exe` resolves to the expected executable. - The process start time matches the recorded instance, preventing PID-reuse errors. 4. Signal only the verified PID instead of using `pkill -f`. 5. Apply the same approach to the Guardian auto-start procedure. For systemd-managed deployments, use operations equivalent to: ```bash systemctl --user is-active --quiet openclaw-gateway.service systemctl --user restart openclaw-gateway.service ``` ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/guardian.sh:39
Finding

Unbounded Workspace Snapshotting and Unattended Destructive Git Rollback

Content
View full analysis
/dev/null | \ grep -v -E "rollback|daily-backup|auto-backup|guardian-auto" | \ sed -n '2p' | awk '{print $1}' } ``` ```bash do_rollback() { log "开始执行 git 回滚..." local CURRENT_COMMIT CURRENT_COMMIT=$(git -C "$WORKSPACE" rev-parse HEAD 2>/dev/null) local STABLE_COMMIT STABLE_COMMIT=$(get_stable_commit) if [ -z "$STABLE_COMMIT" ]; then log "❌ 无法找到稳定版本,跳过回滚" return 1 fi log "回滚目标: $STABLE_COMMIT (当前: $CURRENT_COMMIT)" git -C "$WORKSPACE" reset --hard "$STABLE_COMMIT" >> "$LOG_FILE" 2>&1 git -C "$WORKSPACE" commit --allow-empty \ -m "rollback: guardian auto rollback from $CURRENT_COMMIT to $STABLE_COMMIT at $(date '+%Y-%m-%d %H:%M:%S')" \ >> "$LOG_FILE" 2>&1 ``` ```bash daily_backup() { local today today=$(date '+%Y-%m-%d') local last_backup_file="/tmp/guardian-last-backup" local last_backup="" [ -f "$last_backup_file" ] && last_backup=$(cat "$last_backup_file") if [ "$last_backup" != "$today" ]; then cd "$WORKSPACE" && git add -A && \ git commit -m "daily-backup: auto snapshot $today" >> "$LOG_FILE" 2>&1 || true echo "$today" > "$last_backup_file" log "📦 每日备份完成: $today" fi } ``` ### Technical Analysis The daily backup executes `git add -A` over the entire configured workspace. Any file not explicitly excluded by Git ignore rules is committed, including credentials, tokens, private configuration, conversation artifacts, or other sensitive workspace data. Removing such a file later does not remove it from Git history. The recovery mechanism derives a supposedly stable commit by parsing human-readable `git ...[truncated 2042 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • 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 (13)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
98% confidence
Finding

git reset --hard is a destructive command that discards uncommitted workspace changes, and here it is part of an automated failure-handling path. In the context of a watchdog running every 30 seconds, this is especially dangerous because transient health-check issues could trigger repeated irreversible data loss without human review.

Content

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

md
- Checks Gateway health every 30 seconds (`GUARDIAN_CHECK_INTERVAL`, default: 30)
- On failure: runs `openclaw doctor --fix` up to 3 times (`GUARDIAN_MAX_REPAIR`, default: 3)
- If still down: `git reset --hard` to last stable commit, restart Gateway
- Daily automatic `git commit` snapshot of workspace
- Optional Discord webhook alerts (`DISCORD_WEBHOOK_URL`)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script performs a destructive git reset --hard and restarts the gateway automatically, which can discard uncommitted local changes and interrupt running service state without operator approval. In an agent skill context, this is especially risky because it gives unattended automation authority to overwrite workspace state based on simple health checks, increasing the chance of accidental or cascading damage.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill clearly instructs shell-based installation, process management, git rollback, and background execution, but it declares no explicit tool scope or permissions boundary. That mismatch is dangerous because an agent may invoke powerful shell actions without an upfront, machine-readable restriction or user warning.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The description advertises auto-repair and rollback behavior but does not prominently warn that recovery includes openclaw doctor --fix, process restarts, and git reset --hard, which can overwrite workspace state. Missing disclosure is risky because users may invoke the skill expecting monitoring only, while the actual behavior can modify or destroy files automatically.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The trigger phrase 'Help me install openclaw-guardian to harden my gateway' is broad and overlaps with normal help-seeking language, making accidental invocation more likely. In this skill, accidental activation is meaningful because the workflow includes persistence, self-repair, rollback, and process control actions.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
92% confidence
Finding

The documented use of nohup ... & launches a long-lived background watchdog outside the current session, establishing persistence without an explicit lifecycle manager or consent checkpoint. Persistence increases risk because a misconfigured or compromised guardian can continue modifying the system, restarting processes, or rolling back the workspace after the initiating session ends.

Content

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

chmod +x ~/.openclaw/guardian.sh

3. Start

nohup ~/.openclaw/guardian.sh >> /tmp/openclaw-guardian.log 2>&1 &

text

Note: Use repository-level git config, not --global:

Session Persistence

Medium
Category
Rogue Agent
Confidence
95% confidence
Finding

Modifying start-gateway.sh to restart the guardian automatically on container restart creates recurring persistence across restarts. This is more dangerous than a one-time nohup because it survives service recovery events and can keep reasserting control over process management and rollback behavior.

Content

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

Add to ~/.openclaw/start-gateway.sh before the final exec line:

bash
pkill -f "guardian.sh" 2>/dev/null || true
nohup /home/ubuntu/.openclaw/guardian.sh >> /tmp/openclaw-guardian.log 2>&1 &

Full docs: https://github.com/LeoYeAI/openclaw-guardian

Session Persistence

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

sh
#!/bin/bash
# guardian.sh - OpenClaw Guardian 守护进程
# 功能:监控 Gateway → doctor --fix → git 回滚 → Discord 通知
# 用法:chmod +x guardian.sh && nohup ./guardian.sh >> /tmp/openclaw-guardian.log 2>&1 &

WORKSPACE="${GUARDIAN_WORKSPACE:-$HOME/.openclaw/workspace}"
LOG_FILE="${GUARDIAN_LOG:-/tmp/openclaw-guardian.log}"

External Transmission

Medium
Category
Data Exfiltration
Confidence
86% confidence
Finding

The script sends operational status and commit identifiers to an external Discord webhook, creating an outbound data channel to a third-party service. In this skill context, that can leak repository state, incident timing, and potentially attacker-controlled message content if variables are manipulated, which is more concerning because the transmission is built into an always-running monitor.

Content

Scanner excerpt · scripts/guardian.sh (reported line 22)May include surrounding context.

sh
notify() {
    local msg="$1"
    if [ -n "$DISCORD_WEBHOOK" ]; then
        curl -s -X POST "$DISCORD_WEBHOOK" \
            -H "Content-Type: application/json" \
            -d "{\"content\": \"🚨 **OpenClaw Guardian**: $msg\"}" \
            >/dev/null 2>&1 || true

Session Persistence

Medium
Category
Rogue Agent
Confidence
78% confidence
Finding

The script restarts the gateway with nohup ... &, ensuring it continues running detached from the initiating session. In a recovery automation skill, this persistence is intentional, but it can still be dangerous because it re-establishes a service automatically after failure or rollback without validating whether the binary or configuration is safe to relaunch.

Content

Scanner excerpt · scripts/guardian.sh (reported line 79)May include surrounding context.

sh
# 重启 Gateway
    pkill -f "openclaw-gateway" 2>/dev/null || true
    sleep 3
    nohup $OPENCLAW_CMD gateway >> "$LOG_FILE" 2>&1 &
    sleep 15

    if is_gateway_running; then

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The daily backup routine automatically stages and commits all workspace changes, which can persist unintended edits, sensitive files, or attacker-introduced modifications into repository history. In this watchdog skill, the danger is elevated because the action is unattended and recurring, so users may not notice that their working tree and audit trail are being modified every day.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The skill mentions optional Discord webhook alerts but does not warn that operational details, error messages, host metadata, or other sensitive information may be transmitted to a third-party service. Even if optional, this can create unintended data exposure when users configure the webhook without understanding what may be sent.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

User-visible comments and runtime log/notification strings are written in Chinese throughout the script, with no indication that another language can be selected. This can violate language/locale policy when a skill imposes a specific language without user opt-in.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.