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)

Lp3

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.

Missing User Warnings

Medium
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.

Missing User Warnings

Medium
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.

Session Persistence

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

subprocess module call

Medium
Category
Dangerous Code Execution
Content
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}")
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
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(
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
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"
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
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:
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
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"
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
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 ""
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
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"],
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
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}")
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Missing User Warnings

Medium
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.

Missing User Warnings

Medium
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.

Session Persistence

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

Session Persistence

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

Session Persistence

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

Session Persistence

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

Session Persistence

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

Session Persistence

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

Session Persistence

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

Session Persistence

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

Session Persistence

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

Session Persistence

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

Session Persistence

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

Static analysis

No suspicious patterns detected.