T09 · Insecure Skill Coding Practices
- Location
scripts/setup.sh:7- Finding
Persistent Arbitrary Network Requests Through an Unvalidated Heartbeat URL
- Content
View full analysis
[INTERVAL_SECONDS]}" INTERVAL="${2:-180}" LABEL="ai.openclaw.device-heartbeat" PLIST_PATH="$HOME/Library/LaunchAgents/${LABEL}.plist" SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" HEARTBEAT_SCRIPT="${SCRIPT_DIR}/heartbeat.sh" cat > "$PLIST_PATH" << EOF Label ${LABEL} ProgramArguments /bin/bash ${HEARTBEAT_SCRIPT} ${PING_URL} ${INTERVAL} RunAtLoad KeepAlive EOF launchctl bootstrap "gui/$(id -u)" "$PLIST_PATH" ``` From `scripts/heartbeat.sh`: ```bash PING_URL="${1:?Usage: heartbeat.sh [INTERVAL_SECONDS]}" INTERVAL="${2:-180}" while true; do HTTP_CODE=$(curl -fsS --retry 2 --max-time 10 -o /dev/null -w "%{http_code}" "$PING_URL" 2>/dev/null) if [ "$HTTP_CODE" = "200" ]; then FAIL_COUNT=0 update_state "up" else FAIL_COUNT=$((FAIL_COUNT + 1)) update_state "down" fi sleep "$INTERVAL" done ``` ### Technical Analysis The Skill's declared purpose requires periodic requests to a Healthchecks.io ping endpoint, so installing a user-level LaunchAgent and sending outbound heartbeats are functionally justified. However, `PING_URL` is accepted without validating its scheme, hostname, port, path, or UUID format. The unvalidated value is written into a persistent LaunchAgent and repeatedly passed t ...[truncated 2063 chars]- Remediation
View remediation
[INTERVAL_SECONDS]}" if ! [[ "$CHECK_UUID" =~ ^[0-9a-fA-F-]{32,36}$ ]]; then echo "Invalid Healthchecks.io check UUID" >&2 exit 1 fi PING_URL="https://hc-ping.com/${CHECK_UUID}" ``` ]]>
