T06 · System Persistence
Warning
- Location
- scripts/install.sh:60
- Finding
- Persistent User-Level LaunchAgent Installation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/install.sh:60-98` **Vulnerability Type**: Persistent scheduled execution through a macOS LaunchAgent **Risk Level**: Medium ### Vulnerable Code ```bash cat > "$LAUNCH_AGENT_DIR/com.openclaw.healthcheck.plist" << EOF <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>com.openclaw.healthcheck</string> <key>ProgramArguments</key> <array> <string>$USER_HOME/.openclaw/scripts/openclaw-health-check.sh</string> </array> <key>StartInterval</key> <integer>300</integer> <key>RunAtLoad</key> <true/> <key>StandardOutPath</key> <string>$USER_HOME/.openclaw/logs/health-check-daemon.log</string> <key>StandardErrorPath</key> <string>$USER_HOME/.openclaw/logs/health-check-daemon-error.log</string> <key>KeepAlive</key> <dict> <key>Crashed</key> <true/> <key>NonEmpty</key> <false/> </dict> <key>ProcessType</key> <string>Background</string> <key>ThrottleInterval</key> <integer>60</integer> </dict> </plist> EOF launchctl unload "$LAUNCH_AGENT_DIR/com.openclaw.healthcheck.plist" 2>/dev/null || true sleep 1 launchctl load "$LAUNCH_AGENT_DIR/com.openclaw.healthcheck.plist" ``` ### Technical Analysis The installer creates `~/Library/LaunchAgents/com.openclaw.healthcheck.plist` and immediately registers it with `launchctl`. The configuration executes the installed health-check script when loaded and every 300 seconds. It also asks launchd to relaunch the job after a crash. The persistence is directly related to the declared automatic monitoring functionality and remains within the current user's launchd domain. It does not request root privileges or create a system-wide daemon. Nevertheless, it survives the original Skill execution and continues invoking a m ...[truncated 2829 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Make persistent installation explicitly opt-in: - Default to a manual health-check command. - Add an option such as `--install-launch-agent`. - Display the execution interval, persisted paths, and service-control capabilities before registration. 2. Request separate confirmation immediately before calling `launchctl load` or `launchctl bootstrap`. 3. Provide a monitoring-only mode that does not run `doctor --fix`, restart services, or open Terminal automatically. 4. Remove `KeepAlive` unless crash relaunching is operationally necessary. `StartInterval` already supplies periodic execution. 5. Minimize mutable execution dependencies: - Do not source `$HOME/.nvm/nvm.sh` from the background service. - Resolve the intended OpenClaw executable during installation. - Validate that the resolved executable is a regular file owned by the current user or a trusted package manager and is not group- or world-writable. - Store the validated absolute path in the LaunchAgent configuration or a protected configuration file. 6. Harden installed permissions: - Create directories with restrictive permissions. - Set the installed script to mode `0700` or `0755`, as appropriate. - Set state and log directories to mode `0700`. - Set the LaunchAgent plist to mode `0600` or another deliberately selected restrictive mode. 7. Clearly document that installation creates a cross-session background service capable of modifying OpenClaw configuration and restarting the Gateway. 8. Add a dedicated uninstall script that unloads or boots out the LaunchAgent before deleting it, and verifies that no health-check job remains registered. 9. Consider signing or hashing the installed payload and refusing execution if its integrity changes unexpectedly. ]]>
