T09 · Insecure Skill Coding Practices
- 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: MediumVulnerable 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" fibash 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
- 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 fiAlternatively, place all backup and mutation operations inside the
elsebranch.- 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}"-
Verify that every insertion anchor exists exactly once before changing files. Abort if any count is zero or greater than one.
-
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.
-
Add error handling such as
set -euo pipefailand a cleanup trap that restores verified backups if any patching or validation step fails. -
Validate the patched backend with an appropriate Bun/JavaScript syntax check and confirm that each marker, function, startup call, and route occurs exactly once.
-
Preserve file ownership and permissions during atomic replacement, and document a recovery method using a known-good package or versioned external backup.
