Back to skill

Security audit

Gateway Monitor Installer

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly a disclosed macOS monitor installer, but it includes under-disclosed network-exposed monitoring, credential use, and a configuration-restore endpoint that can change local OpenClaw state.

Review before installing. This skill should be treated as requiring trust in a persistent local service, not just a simple installer. It can read OpenClaw logs/session data, use a MiniMax credential from the local auth profile, make outbound requests, expose unauthenticated HTTP APIs on the network, and change the active OpenClaw config through a GET endpoint. Prefer a version that binds only to localhost, requires authentication for APIs, removes or gates config restore, documents credential use, and includes the missing LaunchAgent templates.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
assets/bin/gateway-monitor-server.js:28
Finding
Authentication Credential Transmitted to a Configurable Remote Endpoint<![CDATA[ ## Vulnerability Details **File Location**: `assets/bin/gateway-monitor-server.js:28-30, 273-289, 301-335, 411-414` **Vulnerability Type**: Credential disclosure through an unrestricted outbound destination **Risk Level**: Critical ### Vulnerable Code ```javascript const MINIMAX_REMAINS_URL = process.env.MINIMAX_REMAINS_URL || 'https://www.minimaxi.com/v1/api/openplatform/coding_plan/remains'; const MINIMAX_CACHE_TTL_MS = clampNumber(process.env.MINIMAX_CACHE_TTL_MS, 20000, 5000, 120000); const MINIMAX_AUTH_PROFILE_PATH = path.join(HOME, '.openclaw/agents/main/agent/auth-profiles.json'); ``` ```javascript function resolveMiniMaxApiKey() { const envKey = String(process.env.MINIMAX_CP_KEY || '').trim(); if (envKey) { return { key: envKey, source: 'env' }; } try { const raw = fs.readFileSync(MINIMAX_AUTH_PROFILE_PATH, 'utf8'); const data = JSON.parse(raw); const key = String(data?.profiles?.['minimax-portal:default']?.access || '').trim(); if (key) { return { key, source: 'auth-profile' }; } } catch { // ignore } return { key: '', source: null }; } ``` ```javascript function fetchJson(urlString, headers = {}, timeoutMs = 6000) { return new Promise((resolve, reject) => { const u = new URL(urlString); const req = https.request({ protocol: u.protocol, hostname: u.hostname, port: u.port || 443, path: `${u.pathname}${u.search}`, method: 'GET', headers, timeout: timeoutMs }, (res) => { let body = ''; res.setEncoding('utf8'); res.on('data', (chunk) => { body += chunk; }); res.on('end', () => { if (res.statusCode < 200 || res.statusCode >= 300) { return reject(new Error(`HTTP ${res.statusCode}: ${body.slice(0, 220)}`)); } try { resolve(JSON.parse(body)); } catch (err) { reject(new Error(`JSON parse failed: ${e ...[truncated 2482 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove implicit access to `~/.openclaw/agents/main/agent/auth-profiles.json`. 2. Make MiniMax integration explicitly opt-in and document all credential access and outbound network behavior. 3. Require a dedicated, narrowly scoped token supplied specifically for monitoring rather than reusing an existing authentication profile. 4. Remove support for an arbitrary `MINIMAX_REMAINS_URL`, or validate it against a strict allowlist of expected HTTPS hostnames and paths. 5. Reject non-HTTPS URLs, unexpected ports, redirects, and URLs containing embedded credentials. 6. Disable automatic quota refresh unless the integration has been explicitly configured. 7. Apply restrictive permissions to the LaunchAgent configuration so other local users cannot modify its environment. 8. Provide a mode in which the local monitor performs no outbound network requests. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
assets/bin/gateway-monitor-server.js:1111
Finding
Sensitive Monitoring APIs Exposed on All Network Interfaces Without Authentication<![CDATA[ ## Vulnerability Details **File Location**: `assets/bin/gateway-monitor-server.js:1111-1206, 1307-1308` **Vulnerability Type**: Unauthenticated network exposure of operational and session data **Risk Level**: High ### Vulnerable Code ```javascript const server = http.createServer((req, res) => { const parsed = url.parse(req.url, true); const pathname = parsed.pathname; if (pathname === '/') return serveIndex(res); if (pathname === '/api/logs/stream') { return handleLogStream(req, res, parsed.query || {}); } if (pathname === '/api/minimax-coding-plan') { const force = String(parsed.query.force || '').trim() === '1'; loadMiniMaxCodingPlan(force) .then((payload) => json(res, payload)) .catch((err) => json(res, { now: new Date().toISOString(), ok: false, statusMsg: 'request_failed', keyMasked: null, source: null, windowHours: 5, models: [], error: String(err?.message || err) }, 500)); return; } if (pathname === '/api/gateway-status') { const gateway = gatewayStatus(); return json(res, { now: new Date().toISOString(), gateway, model: currentModel(), context: sessionContextStatus(), metrics: buildMetrics(gateway) }); } if (pathname === '/api/context-status') { return json(res, { now: new Date().toISOString(), context: sessionContextStatus() }); } if (pathname === '/api/sessions') { const ctx = sessionContextStatus(); return json(res, { now: new Date().toISOString(), ok: ctx.ok, primary: ctx.ok ? { percentUsed: ctx.percentUsed, totalTokens: ctx.totalTokens, contextTokens: ctx.contextTokens, remainingTokens: ctx.remainingTokens, model: ctx.model, abortedLastRun: ctx.abortedLastRun } : null, sessions: ctx.sessions || [], error: ctx.error || null }); } if (pathname === '/api ...[truncated 2930 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Bind the server to `127.0.0.1` and, if needed, separately to `::1`: ```javascript server.listen(PORT, '127.0.0.1', callback); ``` 2. If remote monitoring is required, use TLS and strong authentication with per-user authorization. 3. Reject requests with unexpected `Host` and `Origin` headers. 4. Add a comprehensive log-redaction layer for credentials, tokens, authorization headers, cookies, local paths, and personal identifiers. 5. Reduce API responses to the minimum data needed for monitoring. 6. Protect the Server-Sent Events endpoint with the same authentication and authorization controls as normal API routes. 7. Document the network listener and provide firewall guidance. 8. Add automated tests confirming that unauthenticated remote clients cannot access sensitive endpoints. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
assets/bin/gateway-monitor-server.js:1208
Finding
Unauthenticated GET Endpoint Can Overwrite the Active OpenClaw Configuration<![CDATA[ ## Vulnerability Details **File Location**: `assets/bin/gateway-monitor-server.js:1208-1270` **Vulnerability Type**: Unauthenticated state-changing operation and unsafe configuration rollback **Risk Level**: High ### Vulnerable Code ```javascript if (pathname === '/api/restore-config') { // 只允许 GET 请求 if (req.method !== 'GET') { res.writeHead(405, { 'Content-Type': 'application/json' }); return res.end(JSON.stringify({ error: 'Method not allowed', allowed: ['GET'] })); } const confirm = String(parsed.query.confirm || '').trim(); if (confirm !== 'true') { return json(res, { ok: false, error: 'Confirmation required', message: 'Add ?confirm=true to confirm restore of latest backup' }, 400); } try { const configBackupDir = path.join(HOME, '.openclaw/config-backups'); const openclawJsonPath = path.join(HOME, '.openclaw/openclaw.json'); // 查找最新的备份文件(按修改时间排序) const backupFiles = fs.readdirSync(configBackupDir) .filter(f => f.startsWith('openclaw.json.bak.')) .map(f => { const p = path.join(configBackupDir, f); return { name: f, path: p, mtime: fs.statSync(p).mtimeMs }; }) .sort((a, b) => b.mtime - a.mtime); if (backupFiles.length === 0) { return json(res, { ok: false, error: 'No backup files found', configBackupDir }, 404); } const latestBackup = backupFiles[0].name; const backupPath = backupFiles[0].path; // 复制备份到配置文件 fs.copyFileSync(backupPath, openclawJsonPath); // 验证 JSON 格式 const content = fs.readFileSync(openclawJsonPath, 'utf8'); JSON.parse(content); // 如果无效会抛出异常 return json(res, { ok: true, restored: latestBackup, backupPath, configPath: openclawJsonPath, message: 'Configuration restored successfully. Gateway restart may be required.' }); } catch (err) { return json(res, { ok: false, ...[truncated 2011 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove configuration restoration from the network-facing monitoring server unless it is essential. 2. Require authenticated and authorized `POST` requests rather than GET. 3. Add CSRF protection for browser-accessible deployments. 4. Require a short-lived, unpredictable confirmation token rather than a static query parameter. 5. Validate the selected backup completely before changing the active configuration. 6. Create a protected backup of the current active configuration immediately before restoration. 7. Write the validated configuration to a temporary file in the same directory, set restrictive permissions, and atomically rename it into place. 8. Restrict backup selection to regular files owned by the expected user and reject symbolic links. 9. Record an audit event identifying who initiated the restore and which backup was selected. 10. Keep the endpoint loopback-only even after authentication is introduced. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
assets/bin/gateway-monitor-server.js:24
Finding
Environment-Controlled Shell Commands Permit Arbitrary Command Execution<![CDATA[ ## Vulnerability Details **File Location**: `assets/bin/gateway-monitor-server.js:24-25, 519-525, 566-572` **Vulnerability Type**: Shell command injection through environment-defined command strings **Risk Level**: Medium ### Vulnerable Code ```javascript const OPENCLAW_STATUS_CMD = process.env.OPENCLAW_STATUS_CMD || '/opt/homebrew/opt/node/bin/node /opt/homebrew/lib/node_modules/openclaw/dist/index.js gateway status --json'; const OPENCLAW_FULL_STATUS_CMD = process.env.OPENCLAW_FULL_STATUS_CMD || '/opt/homebrew/opt/node/bin/node /opt/homebrew/lib/node_modules/openclaw/dist/index.js status --json'; ``` ```javascript function readGatewayStatus() { try { const out = execSync(OPENCLAW_STATUS_CMD, { encoding: 'utf8', timeout: 3200, stdio: ['ignore', 'pipe', 'ignore'] }); ``` ```javascript function readSessionContextStatus() { try { const out = execSync(OPENCLAW_FULL_STATUS_CMD, { encoding: 'utf8', timeout: 4200, stdio: ['ignore', 'pipe', 'ignore'] }); ``` ### Technical Analysis `OPENCLAW_STATUS_CMD` and `OPENCLAW_FULL_STATUS_CMD` are complete command strings obtained from environment variables and passed to `execSync()`. Node.js executes string commands through a shell, so shell metacharacters, command substitutions, pipelines, and redirections contained in these values are interpreted. The default command strings are fixed, but the environment override creates a command-injection boundary. An attacker who can influence the persistent service environment can execute arbitrary commands whenever status collection occurs. Status collection is invoked during cache prewarming and through multiple API routes, making the malicious command easy to trigger after environment modification. This does not by itself allow an unauthenticated remote caller to choose the command. Exploitation requires prior influence over the LaunchAgent or process environment. ### Attack Path 1. An attacker gains the abilit ...[truncated 884 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace `execSync()` with `execFileSync()` or `spawnSync()` using a fixed executable and an explicit argument array: ```javascript execFileSync(nodePath, [ openclawScriptPath, 'gateway', 'status', '--json' ], options); ``` 2. Do not accept complete shell command strings from environment variables. 3. If path overrides are necessary, validate each path separately: - Require an absolute path. - Resolve symbolic links where appropriate. - Verify ownership and permissions. - Reject shell metacharacters and unexpected file types. 4. Use a sanitized, minimal environment for child processes. 5. Apply strict permissions to the LaunchAgent plist and installed scripts. 6. Log configuration errors without falling back to shell evaluation. 7. Add tests proving that environment values containing shell syntax cannot cause additional commands to execute. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (41)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared purpose is a local installer/manager, but the detected behavior includes operating a local monitoring API server, exposing diagnostics/log streaming endpoints, reading auth material, restoring configs, and reaching out to an external service. This mismatch is dangerous because users and orchestrators may grant trust for a simple installer while the skill actually handles sensitive data and network-facing functionality beyond that scope.

Ae1

High
Category
analysis-evasion
Content
- If node path differs, edit `assets/bin/gateway-watchdog.sh` before install
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The monitoring server exposes functionality outside the declared install/update/run/remove/health-check scope by adding a configuration restore capability that overwrites ~/.openclaw/openclaw.json. Because this is served over the same HTTP interface and not gated by authentication or stronger authorization, it expands the attack surface from passive monitoring into active state-changing administration.

Context-Inappropriate Capability

High
Confidence
99% confidence
Finding
The /api/restore-config route performs a state-changing file overwrite via unauthenticated HTTP GET with only a query-string confirm=true check. Since the server listens on 0.0.0.0, any reachable host or browser-triggered request from the local network could invoke the restore, enabling unauthorized rollback of configuration and possible service disruption.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
print_agent "$MONITOR_LABEL"
print_agent "$WATCHDOG_LABEL"

rm -f /tmp/.gm_status.$$

echo "\n[health]"
if command -v curl >/dev/null 2>&1; then
Confidence
95% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
unload_agent "$WATCHDOG_LABEL"

echo "[uninstall] removing plist files"
rm -f "$LAUNCH_DIR/${MONITOR_LABEL}.plist"
rm -f "$LAUNCH_DIR/${WATCHDOG_LABEL}.plist"

echo "[uninstall] removing binaries"
Confidence
95% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
echo "[uninstall] removing plist files"
rm -f "$LAUNCH_DIR/${MONITOR_LABEL}.plist"
rm -f "$LAUNCH_DIR/${WATCHDOG_LABEL}.plist"

echo "[uninstall] removing binaries"
rm -rf "$TARGET_BASE"
Confidence
95% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill invokes shell-based installer, status, and uninstall scripts but declares no explicit tool scope or permission boundaries. That makes its effective capabilities broader and less transparent to the user or calling agent, increasing the chance of unintended command execution and unsafe system changes.

Session Persistence

Medium
Category
Rogue Agent
Content
---
name: gateway-monitor-installer
description: Install, update, run, and remove OpenClaw Gateway Monitor + Gateway Watchdog on macOS via LaunchAgent. Use when user asks to deploy one-click monitoring, recover broken gateway daemon automatically, check launchctl health, or uninstall monitor/watchdog services.
---

# Gateway Monitor Installer
Confidence
90% confidence
Finding
The skill is explicitly designed to create or manage LaunchAgent-based services, which establishes persistence across user sessions. Even if intended for legitimate monitoring, persistence increases risk because compromised or misconfigured components will automatically restart and continue running in the background.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The skill describes installing binaries, writing LaunchAgents, backing up configuration, enabling services, and uninstalling them, but does not prominently warn that it will persist processes and modify user files. Without an explicit warning, users may trigger system-impacting changes without understanding persistence, rollback implications, or service side effects.

Session Persistence

Medium
Category
Rogue Agent
Content
- Copy monitor and watchdog binaries to `~/.openclaw/tools/gateway-monitor/bin/`
- Render LaunchAgent templates into `~/Library/LaunchAgents/`
- Backup existing plist files to `~/.openclaw/config-backups/`
- Bootstrap + enable + kickstart both agents
- Run post-install status check
Confidence
88% confidence
Finding
The LaunchAgent/plist workflow shows the skill writes service definitions into the user's LaunchAgents directory and bootstraps them, creating durable session persistence. This is security-relevant because persistent agents can keep running local servers, watchdog logic, or recovery routines beyond the user's immediate session intent.

Context-Inappropriate Capability

Medium
Confidence
91% confidence
Finding
The service includes unrelated MiniMax API integration and credential lookup from environment variables and a local auth profile, which is not necessary for basic gateway monitoring. This broadens the privilege and data-access scope of the process, increasing the blast radius if the monitor is compromised and creating undisclosed outbound data flow.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The code loads a MiniMax API key from environment or a local auth profile and makes outbound authenticated requests without clear user-facing disclosure in a service marketed as a gateway monitor. Even if the key is masked in responses, the silent credential access and network egress violate least surprise and can expose billing, metadata, and trust boundaries.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The restore operation overwrites a live configuration file after only a trivial query parameter confirmation and without substantial warning, preview, or rollback safeguards. This makes accidental or induced restores easier and can cause loss of intended configuration, service instability, or reintroduction of insecure settings from old backups.

Session Persistence

Medium
Category
Rogue Agent
Content
status_json=""
if ! status_json="$($NODE_BIN $OPENCLAW_JS gateway status --json 2>>"$ERR_FILE")"; then
  echo "[$(date '+%F %T')] status check failed -> reload plist" >> "$LOG_FILE"
  launchctl unload "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" 2>/dev/null || true
  launchctl load "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" >> "$LOG_FILE" 2>>"$ERR_FILE"
  exit 0
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
status_json=""
if ! status_json="$($NODE_BIN $OPENCLAW_JS gateway status --json 2>>"$ERR_FILE")"; then
  echo "[$(date '+%F %T')] status check failed -> reload plist" >> "$LOG_FILE"
  launchctl unload "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" 2>/dev/null || true
  launchctl load "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" >> "$LOG_FILE" 2>>"$ERR_FILE"
  exit 0
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
status_json=""
if ! status_json="$($NODE_BIN $OPENCLAW_JS gateway status --json 2>>"$ERR_FILE")"; then
  echo "[$(date '+%F %T')] status check failed -> reload plist" >> "$LOG_FILE"
  launchctl unload "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" 2>/dev/null || true
  launchctl load "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" >> "$LOG_FILE" 2>>"$ERR_FILE"
  exit 0
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
status_json=""
if ! status_json="$($NODE_BIN $OPENCLAW_JS gateway status --json 2>>"$ERR_FILE")"; then
  echo "[$(date '+%F %T')] status check failed -> reload plist" >> "$LOG_FILE"
  launchctl unload "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" 2>/dev/null || true
  launchctl load "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" >> "$LOG_FILE" 2>>"$ERR_FILE"
  exit 0
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
status_json=""
if ! status_json="$($NODE_BIN $OPENCLAW_JS gateway status --json 2>>"$ERR_FILE")"; then
  echo "[$(date '+%F %T')] status check failed -> reload plist" >> "$LOG_FILE"
  launchctl unload "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" 2>/dev/null || true
  launchctl load "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" >> "$LOG_FILE" 2>>"$ERR_FILE"
  exit 0
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
status_json=""
if ! status_json="$($NODE_BIN $OPENCLAW_JS gateway status --json 2>>"$ERR_FILE")"; then
  echo "[$(date '+%F %T')] status check failed -> reload plist" >> "$LOG_FILE"
  launchctl unload "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" 2>/dev/null || true
  launchctl load "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" >> "$LOG_FILE" 2>>"$ERR_FILE"
  exit 0
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
status_json=""
if ! status_json="$($NODE_BIN $OPENCLAW_JS gateway status --json 2>>"$ERR_FILE")"; then
  echo "[$(date '+%F %T')] status check failed -> reload plist" >> "$LOG_FILE"
  launchctl unload "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" 2>/dev/null || true
  launchctl load "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" >> "$LOG_FILE" 2>>"$ERR_FILE"
  exit 0
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
status_json=""
if ! status_json="$($NODE_BIN $OPENCLAW_JS gateway status --json 2>>"$ERR_FILE")"; then
  echo "[$(date '+%F %T')] status check failed -> reload plist" >> "$LOG_FILE"
  launchctl unload "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" 2>/dev/null || true
  launchctl load "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" >> "$LOG_FILE" 2>>"$ERR_FILE"
  exit 0
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
status_json=""
if ! status_json="$($NODE_BIN $OPENCLAW_JS gateway status --json 2>>"$ERR_FILE")"; then
  echo "[$(date '+%F %T')] status check failed -> reload plist" >> "$LOG_FILE"
  launchctl unload "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" 2>/dev/null || true
  launchctl load "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" >> "$LOG_FILE" 2>>"$ERR_FILE"
  exit 0
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
status_json=""
if ! status_json="$($NODE_BIN $OPENCLAW_JS gateway status --json 2>>"$ERR_FILE")"; then
  echo "[$(date '+%F %T')] status check failed -> reload plist" >> "$LOG_FILE"
  launchctl unload "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" 2>/dev/null || true
  launchctl load "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" >> "$LOG_FILE" 2>>"$ERR_FILE"
  exit 0
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
status_json=""
if ! status_json="$($NODE_BIN $OPENCLAW_JS gateway status --json 2>>"$ERR_FILE")"; then
  echo "[$(date '+%F %T')] status check failed -> reload plist" >> "$LOG_FILE"
  launchctl unload "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" 2>/dev/null || true
  launchctl load "$HOME/Library/LaunchAgents/${GATEWAY_LABEL}.plist" >> "$LOG_FILE" 2>>"$ERR_FILE"
  exit 0
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.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
assets/bin/gateway-monitor-server.js:26