T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/restore.sh:29
- Finding
- Path Traversal Through Unvalidated Restore Date## Vulnerability Details **File Location**: `scripts/restore.sh`, lines 29–41 **Vulnerability Type**: Path traversal caused by insufficient input validation **Risk Level**: Medium ### Vulnerable Code ```bash # Validate date format if [ -z "$RESTORE_DATE" ]; then echo -e "${RED}错误: 请指定恢复日期 (YYYY-MM-DD)${NC}" echo "Usage: $0 <backup_dir> <date>" echo "" echo -e "${BLUE}可用的备份日期:${NC}" find "$BACKUP_ROOT" -maxdepth 1 -type d -name "20[0-9][0-9]-[0-9][0-9]-[0-9][0-9]" | sort -r | xargs -I {} basename "{}" exit 1 fi # Check if backup directory exists RESTORE_DIR="$BACKUP_ROOT/$RESTORE_DATE" if [ ! -d "$RESTORE_DIR" ]; then ``` The value is subsequently used as the source of the restoration operation: ```bash rsync -av --exclude='workspace' --exclude='workspace/**' "$RESTORE_DIR/" "$OPENCLAW_DIR/" ``` ### Technical Analysis The script labels the initial check as date-format validation, but it only verifies that `RESTORE_DATE` is nonempty. It does not enforce the documented `YYYY-MM-DD` format or reject path separators and traversal components such as `..`. `RESTORE_DIR` is constructed by directly concatenating the user-controlled value with `BACKUP_ROOT`. Shell quoting prevents command injection, but it does not prevent filesystem path resolution. Consequently, a value such as `../../attacker-controlled-directory` can resolve outside the designated backup root. The directory-existence check does not mitigate the issue: it accepts any resolved directory that exists. After interactive confirmation, that directory is passed to `rsync` as the restoration source. ### Attack Path 1. An attacker or untrusted caller prepares a readable directory containing files intended to overwrite or augment the victim's OpenClaw configuration. 2. The restore script is invoked with a legitimate backup root and a traversal value in place of the date, for example: ```bash ./scripts/restore.s ...[truncated 1261 chars]
- Remediation
- ## Remediation Suggestions 1. Enforce the date format before constructing a path: ```bash if [[ ! "$RESTORE_DATE" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]; then echo "Error: restore date must use YYYY-MM-DD format" >&2 exit 1 fi ``` 2. Optionally verify that the value represents a valid calendar date rather than only matching its shape: ```bash if [ "$(date -d "$RESTORE_DATE" +%Y-%m-%d 2>/dev/null)" != "$RESTORE_DATE" ]; then echo "Error: invalid restore date" >&2 exit 1 fi ``` 3. Canonicalize the backup root and restore directory, then ensure the restore directory is an immediate child of the backup root: ```bash BACKUP_ROOT_REAL=$(realpath -- "$BACKUP_ROOT") RESTORE_DIR=$(realpath -- "$BACKUP_ROOT_REAL/$RESTORE_DATE") || exit 1 if [ "$(dirname -- "$RESTORE_DIR")" != "$BACKUP_ROOT_REAL" ]; then echo "Error: restore source is outside the backup root" >&2 exit 1 fi ``` 4. Reject symbolic-link backup directories or establish an explicit symlink policy so canonicalization cannot redirect restoration to an unintended source. 5. Display the canonical restore source in the confirmation prompt and consider validating backup integrity or provenance before copying files into `~/.openclaw`.
