Back to skill

Security audit

ClawGuard

Security checks for vulnerabilities and agentic risk

Overview

ClawGuard is purpose-built and mostly transparent, but it installs an always-on watchdog that can automatically rewrite OpenClaw configuration and send service diagnostics, so users should review it before installing.

Install only if you want a persistent OpenClaw watchdog running in your user session. Review the service files it creates, understand how to disable the systemd/launchd service, and be comfortable with automatic OpenClaw config rollback and alert messages that may include local service diagnostics.

Vulnerability Patterns
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (29)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill describes installation and operation of a daemon, CLI, and shell-based system integration, but its frontmatter declares no explicit tool scope or permissions. That omission can mislead users and agents about the skill's capabilities, increasing the chance that file modification, shell execution, and persistent service installation occur without informed approval.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill advertises automatic config backup, revert, and retry behavior for gateway restarts, but does not give a prominent warning that it may restore older configuration state automatically. This can unexpectedly overwrite intended changes, roll back security settings, or cause integrity and availability issues if the wrong backup is reapplied.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The install section enables a systemd user service or launchd agent with auto-start and Restart=always, creating continuous background monitoring and persistence across reboots without a prominent warning. Persistent monitoring of PIDs, logs, and directories changes the user's system state and can continue running long after the immediate task, which is risky if the user did not knowingly consent.

Content

No source excerpt is available for this finding.

Session Persistence

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

Content

Scanner excerpt · scripts/claw-guard-cli.py (reported line 136)May include surrounding context.

python
parser = argparse.ArgumentParser(prog="claw-guard")
    sub = parser.add_subparsers(dest="cmd")

    p = sub.add_parser("register", help="Register a task for monitoring")
    p.add_argument("--id", required=True)
    p.add_argument("--pid", type=int, required=True)
    p.add_argument("--target", required=True, help="Notification target (room:!id:server, telegram:id, etc.)")

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/claw-guard.py (reported line 62)May include surrounding context.

python
else:
            # No target — let OpenClaw route to default channel
            cmd = ["openclaw", "message", "send", "--message", message]
        subprocess.run(cmd, capture_output=True, text=True, timeout=15)
    except Exception as e:
        log(f"  Notify error: {e}")

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/claw-guard.py (reported line 78)May include surrounding context.

python
def gateway_active():
    try:
        if IS_MACOS:
            r = subprocess.run(["launchctl", "list"], capture_output=True, text=True, timeout=5)
            return "openclaw" in r.stdout.lower()
        else:
            r = subprocess.run(

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/claw-guard.py (reported line 81)May include surrounding context.

python
r = subprocess.run(["launchctl", "list"], capture_output=True, text=True, timeout=5)
            return "openclaw" in r.stdout.lower()
        else:
            r = subprocess.run(
                ["systemctl", "--user", "is-active", "openclaw-gateway.service"],
                capture_output=True, text=True, timeout=5)
            return r.stdout.strip() == "active"

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/claw-guard.py (reported line 92)May include surrounding context.

python
def gateway_status_error():
    try:
        if IS_MACOS:
            r = subprocess.run(["launchctl", "list", "com.openclaw.gateway"],
                              capture_output=True, text=True, timeout=10)
            return (r.stdout or r.stderr)[-500:]
        else:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/claw-guard.py (reported line 96)May include surrounding context.

python
capture_output=True, text=True, timeout=10)
            return (r.stdout or r.stderr)[-500:]
        else:
            r = subprocess.run(
                ["systemctl", "--user", "status", "openclaw-gateway.service"],
                capture_output=True, text=True, timeout=10)
            return r.stdout[-500:] if r.stdout else "no output"

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/claw-guard.py (reported line 114)May include surrounding context.

python
return logs[0].read_text()[-500:]
            return ""
        else:
            r = subprocess.run(
                ["journalctl", "--user-unit", "openclaw-gateway.service", "-n", "20", "--no-pager"],
                capture_output=True, text=True, timeout=10)
            return r.stdout[-500:] if r.stdout else ""

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/claw-guard.py (reported line 126)May include surrounding context.

python
try:
        if IS_MACOS:
            uid = os.getuid()
            subprocess.run(["launchctl", "kickstart", "-k", f"gui/{uid}/com.openclaw.gateway"],
                          capture_output=True, text=True, timeout=30)
        else:
            subprocess.run(["systemctl", "--user", "restart", "openclaw-gateway.service"],

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/claw-guard.py (reported line 129)May include surrounding context.

python
subprocess.run(["launchctl", "kickstart", "-k", f"gui/{uid}/com.openclaw.gateway"],
                          capture_output=True, text=True, timeout=30)
        else:
            subprocess.run(["systemctl", "--user", "restart", "openclaw-gateway.service"],
                          capture_output=True, text=True, timeout=30)
    except Exception as e:
        log(f"  Restart command failed: {e}")

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

On restart failure, the code sends slices of service status and recent journal content through the messaging channel to the registered target. Those diagnostics can contain sensitive local paths, configuration values, usernames, host details, error traces, or tokens accidentally written to logs, creating an information-disclosure channel to any party that can influence or receive the target notification.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The installer immediately copies executables into a persistent user directory and later installs a long-running user service without any explicit upfront warning or confirmation. Even if this is intended functionality for a watchdog, silently creating persistence and startup behavior reduces informed consent and makes abuse or accidental installation harder for users to notice.

Content

No source excerpt is available for this finding.

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

sh
CURRENT_PATH="$PATH"

if [ "$OS" = "Darwin" ]; then
    # macOS — launchd plist
    PLIST_DIR="$HOME/Library/LaunchAgents"
    PLIST="$PLIST_DIR/com.openclaw.claw-guard.plist"
    mkdir -p "$PLIST_DIR"

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

sh
CURRENT_PATH="$PATH"

if [ "$OS" = "Darwin" ]; then
    # macOS — launchd plist
    PLIST_DIR="$HOME/Library/LaunchAgents"
    PLIST="$PLIST_DIR/com.openclaw.claw-guard.plist"
    mkdir -p "$PLIST_DIR"

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

sh
CURRENT_PATH="$PATH"

if [ "$OS" = "Darwin" ]; then
    # macOS — launchd plist
    PLIST_DIR="$HOME/Library/LaunchAgents"
    PLIST="$PLIST_DIR/com.openclaw.claw-guard.plist"
    mkdir -p "$PLIST_DIR"

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

sh
CURRENT_PATH="$PATH"

if [ "$OS" = "Darwin" ]; then
    # macOS — launchd plist
    PLIST_DIR="$HOME/Library/LaunchAgents"
    PLIST="$PLIST_DIR/com.openclaw.claw-guard.plist"
    mkdir -p "$PLIST_DIR"

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

sh
if [ "$OS" = "Darwin" ]; then
    # macOS — launchd plist
    PLIST_DIR="$HOME/Library/LaunchAgents"
    PLIST="$PLIST_DIR/com.openclaw.claw-guard.plist"
    mkdir -p "$PLIST_DIR"
    cat > "$PLIST" << PLIST

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

sh
if [ "$OS" = "Darwin" ]; then
    # macOS — launchd plist
    PLIST_DIR="$HOME/Library/LaunchAgents"
    PLIST="$PLIST_DIR/com.openclaw.claw-guard.plist"
    mkdir -p "$PLIST_DIR"
    cat > "$PLIST" << PLIST

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

sh
if [ "$OS" = "Darwin" ]; then
    # macOS — launchd plist
    PLIST_DIR="$HOME/Library/LaunchAgents"
    PLIST="$PLIST_DIR/com.openclaw.claw-guard.plist"
    mkdir -p "$PLIST_DIR"
    cat > "$PLIST" << PLIST

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

sh
if [ "$OS" = "Darwin" ]; then
    # macOS — launchd plist
    PLIST_DIR="$HOME/Library/LaunchAgents"
    PLIST="$PLIST_DIR/com.openclaw.claw-guard.plist"
    mkdir -p "$PLIST_DIR"
    cat > "$PLIST" << PLIST

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

sh
if [ "$OS" = "Darwin" ]; then
    # macOS — launchd plist
    PLIST_DIR="$HOME/Library/LaunchAgents"
    PLIST="$PLIST_DIR/com.openclaw.claw-guard.plist"
    mkdir -p "$PLIST_DIR"
    cat > "$PLIST" << PLIST

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

sh
if [ "$OS" = "Darwin" ]; then
    # macOS — launchd plist
    PLIST_DIR="$HOME/Library/LaunchAgents"
    PLIST="$PLIST_DIR/com.openclaw.claw-guard.plist"
    mkdir -p "$PLIST_DIR"
    cat > "$PLIST" << PLIST

Session Persistence

Medium
Category
Rogue Agent
Confidence
88% confidence
Finding

Although this duplicate finding is triggered on the plist content boundary, the underlying issue is the same: the script begins creating a LaunchAgent configuration that will persist across sessions. Persistent autostart increases risk if the installed Python scripts are later altered or replaced.

Content

Scanner excerpt · scripts/install.sh (reported line 31)May include surrounding context.

sh
if [ "$OS" = "Darwin" ]; then
    # macOS — launchd plist
    PLIST_DIR="$HOME/Library/LaunchAgents"
    PLIST="$PLIST_DIR/com.openclaw.claw-guard.plist"
    mkdir -p "$PLIST_DIR"
    cat > "$PLIST" << PLIST
<?xml version="1.0" encoding="UTF-8"?>