Back to skill

Security audit

LLM Loop Breaker

Security checks for vulnerabilities and agentic risk

Overview

This skill is a defensive gateway guard, but it persistently patches the gateway, starts a detached watchdog, can kill process trees, and has unsafe shell/path handling that users should review before installing.

Install only after reviewing the deploy script and accepting that it will modify openclaw.mjs, patch global fetch, start a background watchdog, collect local host diagnostics, and automatically kill selected gateway child processes. Prefer running it in a test environment first, under a dedicated unprivileged account, with pinned dependencies, explicit service management, restricted log paths, and a clear rollback plan.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • Tool Hijacking and SpoofingModifies or replaces tools so legitimate-looking calls execute attacker logic
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
Findings (5)

T07 · Tool Hijacking and Spoofing

Error
Location
src/stream-entropy-breaker.cjs:132
Finding

Process-Wide Hijacking of the Global Fetch API

Content
View full analysis
Remediation
View remediation

T06 · System Persistence

Error
Location
deploy.sh:66
Finding

Persistent Gateway Modification and Detached Watchdog Execution

Content
View full analysis
> "${TARGET_FILE}" << 'INJECT' // [LLM_STREAM_GUARD_START] -- Injected by deploy.sh. Do not edit manually. // Layer 2: Pull up Host Resource Watchdog daemon try { const { execSync } = module.createRequire(import.meta.url)("child_process"); try { execSync('pgrep -f "[h]ost-resource-watchdog.py"'); } catch (err) { const distDir = new URL("dist/llm_stream_guard/", import.meta.url).pathname; const logDir = (process.env.HOME || "/root") + "/.openclaw/workspace/memory/core"; execSync(`mkdir -p "${logDir}"`); execSync(`nohup python3 "${distDir}host-resource-watchdog.py" > "${logDir}/host_watchdog.log" 2>&1 &`); console.log("[Host Resource Watchdog] Started."); } } catch (e) { console.error("[Host Resource Watchdog] Failed to start:", e.message); } // Layer 1: Activate Stream Entropy Breaker (patches global.fetch) try { const { createRequire } = await import("node:module"); const require = createRequire(import.meta.url); const breaker = require("./dist/llm_stream_guard/stream-entropy-breaker.cjs"); if (breaker && breaker.install) { breaker.install(); } } catch (e) { console.error("[Stream Entropy Breaker] Failed to activate:", e); } // [LLM_STREAM_GUARD_END] INJECT ``` ### Technical Analysis The deployment process permanently appends executable code to the gateway's primary entry point, `openclaw.mjs`. The injected code runs on every subsequent gateway start. The startup hook searches globally for a process whose command line matches `host-resource-w ...[truncated 1611 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
deploy.sh:82
Finding

Shell Command Injection Through the HOME Environment Variable

Content
View full analysis
"${logDir}/host_watchdog.log" 2>&1 &`); ``` ### Technical Analysis `process.env.HOME` is environment-controlled input. It is concatenated into command strings and passed to `execSync`, which invokes a shell. Placing the value inside double quotes does not make it safe. POSIX shells still evaluate command substitution such as `$(command)` and backticks inside double quotes. A malicious value can also contain a double quote to terminate the quoted path and inject additional shell syntax. For example, a launch environment containing a `HOME` value with command substitution would cause that substitution to execute when the gateway evaluates the injected startup block. The exact ability to set the gateway environment depends on the deployment environment, but no validation or shell-safe argument handling is present. ### Attack Path 1. An attacker gains the ability to influence the gateway's launch environment, deployment configuration, container environment, or service environment file. 2. The attacker assigns a crafted value to `HOME`, containing shell substitution or quote-breaking syntax. 3. The gateway starts and executes the block injected by `deploy.sh`. 4. The crafted value is interpolated into the `mkdir` and `nohup` command strings. 5. `execSync` invokes a shell. 6. The shell evaluates the injected syntax with the gateway process's operating-system privileges. ### Impact Assessment Successful exploitation permits arbitrary command execution as the gateway account. The attacker can read or modify files accessible to that account ...[truncated 341 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
host-resource-watchdog.py:153
Finding

Overbroad Process Identification Enables Destructive Termination of Legitimate Workloads

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
deploy.sh:35
Finding

Unpinned Runtime Installation of a Third-Party Python Package

Content
View full analysis
/dev/null; then echo "[LLM Stream Guard] Installing psutil..." if command -v apt-get &>/dev/null; then apt-get update -qq && apt-get install -y -qq python3-psutil else python3 -m pip install psutil fi if ! python3 -c "import psutil" &>/dev/null; then echo "ERROR: Failed to install psutil. Aborting." exit 1 fi echo "[LLM Stream Guard] psutil installed." else ``` ### Technical Analysis When `psutil` is unavailable and `apt-get` is not present, the script installs `psutil` from the Python package index without specifying a version, hash, approved repository, or lock file. The installed artifact can therefore change over time without any modification to this Skill. Package resolution also depends on the host's pip configuration, DNS, proxy settings, and configured package indexes. A compromised or attacker-controlled index can provide code that executes during installation or is later imported by the watchdog. The `apt-get` branch likewise installs an unspecified repository-selected version, although operating-system repositories commonly provide additional signing controls. ### Attack Path 1. The deployment host does not already have an importable `psutil` package. 2. The host does not provide `apt-get`, causing the script to use pip. 3. The deployment environment resolves packages through a compromised, misconfigured, or attacker-controlled package index or proxy. 4. `python3 -m pip install psutil` downloads an unpinned artifact. 5. Installation-time behavior executes under the privileges used to run `deploy.sh`, or malicious package code executes when the watchdog imports `psutil`. 6. The dependency gains the same filesystem and process access as the installer or watchdog. ### Impact Assess ...[truncated 405 chars]
Remediation
View remediation
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (18)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The documented purpose frames the skill as a defensive gateway guard, but the described deployment also patches application code, creates persistent background monitoring, installs dependencies, and performs host filesystem changes. This mismatch is dangerous because operators may approve it as a narrow safety feature without realizing it has code-injection, persistence, and host-modification behavior.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The documented purpose frames the skill as a defensive gateway guard, but the described deployment also patches application code, creates persistent background monitoring, installs dependencies, and performs host filesystem changes. This mismatch is dangerous because operators may approve it as a narrow safety feature without realizing it has code-injection, persistence, and host-modification behavior.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill declares powerful capabilities implicitly through its behavior but does not define an explicit tool/permission scope. Because it reads environment variables, modifies files, and runs shell operations, the lack of declared scope prevents informed consent and weakens containment around a skill that can alter the host application.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill does disclose some behavior in the deployment and watchdog sections, but it does not present a prominent warning that installation modifies the gateway runtime, may kill process trees, and collects forensic system logs such as journalctl and dmesg excerpts. For a host-level defensive skill, these side effects materially affect availability and privacy, so burying them in operational details increases the chance of unsafe deployment.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The script automatically installs system or Python packages at deploy time using apt-get or pip, expanding its behavior beyond simply deploying the advertised guard logic. This creates supply-chain and change-control risk because it alters the host environment without pinning versions, isolation, or operator approval.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The script installs packages without any interactive confirmation or explicit noninteractive consent flag from the operator. In an administrative deployment context, silent dependency installation can unexpectedly change the host, pull unreviewed code, and violate least surprise and approval requirements.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The deployment script appends executable code directly into the host application's main file, permanently changing application behavior outside normal extension boundaries. This is dangerous because it creates a hard-to-audit persistence point, broadens privilege to everything the app can access, and makes rollback and integrity verification more difficult.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script modifies the target application's main file by appending injected logic without explicit user confirmation. Directly rewriting a production entrypoint is a high-risk change because it can introduce persistence, break upgrades, and conceal ongoing behavior changes from operators.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The injected code starts a background watchdog daemon via execSync, pgrep, nohup, and shell command composition from inside the host application's runtime. Persistent process spawning from injected application code increases stealth, operational complexity, and abuse potential if the path or environment is manipulated.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
94% confidence
Finding

Using nohup and backgrounding creates a persistent detached process that survives the invoking session and can continue operating without direct operator visibility. In this skill's context, that persistence is especially sensitive because it is introduced by code injected into the host application's startup path, effectively establishing a semi-hidden resident component.

Content

Scanner excerpt · deploy.sh (reported line 86)May include surrounding context.

sh
const distDir = new URL("dist/llm_stream_guard/", import.meta.url).pathname;
    const logDir = (process.env.HOME || "/root") + "/.openclaw/workspace/memory/core";
    execSync(`mkdir -p "${logDir}"`);
    execSync(`nohup python3 "${distDir}host-resource-watchdog.py" > "${logDir}/host_watchdog.log" 2>&1 &`);
    console.log("[Host Resource Watchdog] Started.");
  }
} catch (e) {

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The watchdog automatically kills gateway child processes based on heuristic triggers without prominently disclosing this destructive behavior. In this context, false positives could terminate legitimate workloads, disrupt service, and cause data loss or denial of service, especially because the thresholds are heuristic rather than authoritative.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The incident snapshot collects broad host-level logs from journalctl, /var/log/syslog, /var/log/messages, and dmesg, which can expose unrelated system activity, secrets, usernames, service data, and kernel diagnostics beyond the Openclaw gateway's needs. In the context of an agent skill, this expands data access significantly and creates a privacy and information-disclosure risk if snapshots are read, synced, or exfiltrated later.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The watchdog silently writes incident reports containing system and kernel logs to local files without clear disclosure or operator acknowledgment in the skill itself. This is dangerous because users may deploy the skill expecting resource monitoring, not realizing it performs forensic collection of potentially sensitive host data.

Content

No source excerpt is available for this finding.

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 · host-resource-watchdog.py (reported line 327)May include surrounding context.

python
# Collect system logs (journalctl -> syslog -> messages fallback)
            try:
                if shutil.which('journalctl'):
                    sys_logs = subprocess.check_output(
                        ['journalctl', '-u', 'openclaw', '-n', '50', '--no-pager'],
                        text=True, timeout=10, stderr=subprocess.DEVNULL
                    )

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 · host-resource-watchdog.py (reported line 350)May include surrounding context.

python
# Collect kernel segfault / OOM logs
            try:
                dmesg_result = subprocess.check_output(
                    ['dmesg', '-T'],
                    text=True, timeout=5, stderr=subprocess.DEVNULL
                )

Tainted flow: 'report_path' from os.environ.get (line 322, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
95% confidence
Finding

report_path is derived from OPENCLAW_WORKSPACE, which comes from the environment, and is used for file writes without validating or constraining the resolved path. If an attacker can influence the daemon's environment or workspace path, they may redirect incident reports to arbitrary filesystem locations, potentially overwriting files or writing sensitive diagnostic content outside the intended workspace.

Content

Scanner excerpt · host-resource-watchdog.py (reported line 363)May include surrounding context.

python
except Exception:
                dmesg_logs = 'Unable to read dmesg.'

            with open(report_path, 'w') as f:
                f.write(f'# Process Incident Report: {timestamp}\n')
                f.write(f'**Trigger**: {reason} for process `{target_process}`\n')
                if extra_info:

Tainted flow: 'AUDIT_LOG' from os.environ.get (line 39, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
95% confidence
Finding

AUDIT_LOG is derived from the environment-controlled workspace path and opened for append without path validation. In a privileged daemon context, this can become an arbitrary file write primitive or allow sensitive incident metadata to be redirected into attacker-chosen locations.

Content

Scanner excerpt · host-resource-watchdog.py (reported line 373)May include surrounding context.

python
f.write('## 2. Kernel Segfault/OOM Logs\n```bash\n')
                f.write(dmesg_logs + '\n```\n')

            with open(AUDIT_LOG, 'a') as f:
                f.write(f'\n\n**{timestamp} - SYSTEM CRITICAL EVENT**\n')
                f.write(f'{reason}. Snapshot saved to: `{report_path}`\n')
                if extra_info:

Tainted flow: 'AUDIT_LOG' from os.environ.get (line 39, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
95% confidence
Finding

This is the same underlying issue as the earlier AUDIT_LOG write: an environment-influenced path is used for appending audit data without confinement checks. Because the watchdog may run with elevated privileges, an attacker who controls startup environment or deployment config could leverage this to write to unintended files.

Content

Scanner excerpt · host-resource-watchdog.py (reported line 407)May include surrounding context.

python
breach_msg = ', '.join(redline_breached)
            print(f'[WARNING] PHYSICAL REDLINE BREACH: {breach_msg}', file=sys.stderr)
            try:
                with open(AUDIT_LOG, 'a') as f:
                    f.write(f'\n- **{timestamp}**: PHYSICAL REDLINE BREACH: {breach_msg}')
            except Exception:
                pass