T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/install.sh:5
- Finding
- Unescaped Script Path Allows Persistent Cron Command Injection<![CDATA[ ## Vulnerability Details **File Location**: `scripts/install.sh`, lines 5–15 **Vulnerability Type**: Cron command injection through an unescaped installation path **Risk Level**: Medium ### Vulnerable Code ```bash SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" CHECK_SCRIPT="$SCRIPT_DIR/check-gateway.sh" WORKSPACE="${OPENCLAW_WORKSPACE:-$HOME/.openclaw/workspace}" HEARTBEAT="$WORKSPACE/HEARTBEAT.md" CRON_MARKER="# openclaw-openclaw-gatewaykeeper" chmod +x "$CHECK_SCRIPT" # Install cron job (every 15 minutes) CRON_LINE="*/15 * * * * $CHECK_SCRIPT $CRON_MARKER" (crontab -l 2>/dev/null | grep -v "$CRON_MARKER"; echo "$CRON_LINE") | crontab - ``` ### Technical Analysis The installer obtains its directory dynamically and inserts the resulting `CHECK_SCRIPT` path directly into a crontab command without quoting or validating it. Although the shell variable is quoted while constructing `CRON_LINE`, those quotes do not become literal quoting in the generated crontab entry. Cron later passes the command portion to a shell. Consequently, spaces and shell metacharacters in the installation path can change how the command is parsed. Cron also assigns special meaning to percent characters, which can further alter command execution unless correctly escaped. The scheduled task itself is consistent with the Skill's declared watchdog functionality and runs only as the user who invokes `crontab`; therefore, the use of cron is not independently an unauthorized persistence mechanism. The vulnerability is that an attacker-controlled installation path can transform this legitimate recurring task into persistent arbitrary command execution. ### Attack Path 1. An attacker causes the Skill package to be installed or extracted under a directory name containing shell-significant characters, spaces, or cron-special characters. 2. The victim executes `scripts/install.sh`. 3. The installer embeds the unescaped absolute path into `CRON_LINE`. 4. The malformed command is written ...[truncated 912 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Install or copy the health-check script to a fixed, trusted location with a predictable path rather than scheduling execution directly from an arbitrary package directory. 2. Reject paths containing line breaks, carriage returns, control characters, percent characters, or other values unsafe in crontab records. 3. Generate the command using a robust shell-quoting routine compatible with the shell used by cron. Account separately for cron's special handling of `%`; ordinary shell quoting alone is insufficient. 4. Prefer a fixed wrapper script whose path contains only a conservative character set, such as letters, digits, `/`, `_`, `.`, and `-`. 5. Write the generated crontab to a temporary file, validate the complete entry, and then install it only after validation succeeds. 6. Document that the installer must not be run as root unless system-wide watchdog operation is explicitly required. 7. Preserve the existing marker-based uninstall behavior, but use exact matching to avoid deleting unrelated user crontab entries that happen to contain the same marker text. ]]>
