Back to skill

Security audit

Fnos Openclaw Autostart

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it says, but it directly patches live OpenClaw application files in a way that can break the service or make rollback unreliable if repeated or partially applied.

Install only if you are comfortable modifying live OpenClaw files on the NAS. Before applying it, make separate timestamped backups, confirm each insertion point appears exactly once, stop if the patch marker already exists, validate the edited files before restart, and keep a known-good package or backup for recovery.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:55
Finding

Non-Idempotent Patching Can Corrupt the Application and Its Rollback Copy

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 55–59, 69–70, 83–143
Vulnerability Type: Non-idempotent and non-atomic file modification
Risk Level: Medium

Vulnerable Code

bash
# Check whether the patch already exists
if grep -q "AUTOSTART_CONF" "$MONITOR_JS"; then
  echo "Already patched; skip injection"
else
  echo "Not patched; continue"
fi
bash
cp "$MONITOR_JS" "${MONITOR_JS}.bak"
cp "$UI_HTML" "${UI_HTML}.bak"
bash
sed -i '/^async function startRuntimeReconciler\|^startRuntimeReconciler()/i\
const AUTOSTART_CONF = "\/vol1\/@appdata\/trim.openclaw\/.autostart";\
async function autoStartDefaultInstance() { try {\
    const autoStartFlag = import.meta.require("fs").existsSync(AUTOSTART_CONF)\
      ? import.meta.require("fs").readFileSync(AUTOSTART_CONF, "utf8").trim()\
      : "1";\
    if (autoStartFlag === "0" || autoStartFlag === "false" || autoStartFlag === "disable") {\
      console.log("[monitor] Auto-start is disabled by " + AUTOSTART_CONF); return;\
    }\
    const instance = ensureDefaultInstance();\
    const runtime = await probeInstanceRuntime(instance);\
    if (runtime.running) { console.log("[monitor] OpenClaw gateway is already running, skipping auto-start"); return; }\
    if (!runtime.installed) { console.log("[monitor] OpenClaw is not installed, skipping auto-start"); return; }\
    console.log("[monitor] Auto-starting OpenClaw gateway on boot...");\
    let port = runtime.port;\
    if (!port) { port = randomPort(); await writeInstancePort(instance, port); }\
    const noopEnqueue = () => {};\
    await startOpenclaw(instance, port, noopEnqueue, null);\
    console.log("[monitor] OpenClaw gateway auto-started successfully");\
  } catch (err) { console.error("[monitor] Auto-start failed:", err); }\
}' "$MONITOR_JS"
bash
sed -i '/^ *registerBackgroundTaskSafetyHandlers()/a\
autoStartDefaultInstance().catch((err) => {\
  console.error("[monitor] auto-start default instance failed:", er
...[truncated 3641 chars]
Remediation
View remediation

Remediation Suggestions

  1. Make the procedure genuinely idempotent by terminating successfully when the marker is found:
bash
if grep -q "AUTOSTART_CONF" "$MONITOR_JS"; then
  echo "Patch already installed; no changes made."
  exit 0
fi

Alternatively, place all backup and mutation operations inside the else branch.

  1. Do not overwrite the original backup. Use a timestamped or content-addressed backup and fail if the designated pristine backup already exists:
bash
timestamp="$(date +%Y%m%d-%H%M%S)"
cp -- "$MONITOR_JS" "${MONITOR_JS}.bak.${timestamp}"
cp -- "$UI_HTML" "${UI_HTML}.bak.${timestamp}"
  1. Verify that every insertion anchor exists exactly once before changing files. Abort if any count is zero or greater than one.

  2. Copy the targets to temporary files in the same filesystem, apply all edits to those copies, and validate the results before replacement. Only then atomically rename the validated files over the originals.

  3. Add error handling such as set -euo pipefail and a cleanup trap that restores verified backups if any patching or validation step fails.

  4. Validate the patched backend with an appropriate Bun/JavaScript syntax check and confirm that each marker, function, startup call, and route occurs exactly once.

  5. Preserve file ownership and permissions during atomic replacement, and document a recovery method using a known-good package or versioned external backup.

Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (2)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill directs users to patch live application files and later kill the monitoring process to apply the change, which can interrupt service or leave the application in a broken state if the injected edits are incorrect. Although backups and rollback are mentioned elsewhere, the disruptive steps themselves are not accompanied by an immediate warning about downtime, restart behavior, or validation before process termination.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The skill’s user-facing description and instructions are entirely in Chinese, and there is no indication that this is a region-specific skill or that other languages are unsupported by design. Under the policy, forcing a specific language without opt-in or justification can be a natural-language policy violation.

Content

No source excerpt is available for this finding.