T07 · Tool Hijacking and Spoofing
- Location
src/stream-entropy-breaker.cjs:132- Finding
Process-Wide Hijacking of the Global Fetch API
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
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.
src/stream-entropy-breaker.cjs:132Process-Wide Hijacking of the Global Fetch API
deploy.sh:66Persistent Gateway Modification and Detached Watchdog Execution
deploy.sh:82Shell Command Injection Through the HOME Environment Variable
host-resource-watchdog.py:153Overbroad Process Identification Enables Destructive Termination of Legitimate Workloads
deploy.sh:35Unpinned Runtime Installation of a Third-Party Python Package
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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) {
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.
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.
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.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
# 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 calls execute external commands. Without careful input validation, this enables command injection.
# Collect kernel segfault / OOM logs
try:
dmesg_result = subprocess.check_output(
['dmesg', '-T'],
text=True, timeout=5, stderr=subprocess.DEVNULL
)
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.
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:
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.
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:
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.
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