T09 · Insecure Skill Coding Practices
- Location
bin/lib/backup.sh:49- Finding
Configuration-Based Command Injection in Backup Exclusion Handling
- Content
View full analysis
Vulnerability Details
File Location:
bin/lib/backup.sh, lines 49-63
Vulnerability Type: Shell command injection througheval
Risk Level: HighVulnerable Code
bash # Build rsync exclude arguments local rsync_args="-a" while IFS= read -r exclude; do if [[ -n "$exclude" ]]; then rsync_args+=" --exclude=$exclude" fi done <<< "$dir_excludes" # Default excludes if none specified if [[ -z "$dir_excludes" ]]; then rsync_args+=" --exclude=.venv --exclude=node_modules --exclude=*.pyc --exclude=__pycache__" fi # Copy to temp dir eval rsync $rsync_args "$dir_path/" "$tmp_backup_dir/$dir_label/" 2>/dev/null || {Technical Analysis
Values from
backup_paths[].excludein~/.openclaw/update-plus.jsonare concatenated into a shell command string. The resulting string is passed toeval, which causes the shell to parse configuration content as executable syntax.An exclusion value containing command substitution, shell separators, redirections, or other metacharacters can therefore execute arbitrary commands. Quoting the source and destination arguments in the original statement does not prevent exploitation because
evalreparses the complete expanded command.Attack Path
- An attacker gains the ability to create or modify the OpenClaw configuration file.
- The attacker inserts a malicious value into
backup_paths[].exclude, such as a value containing command substitution or a shell separator followed by a command. - The user or installed cron job invokes an operation that creates a backup.
create_backupreads the malicious exclusion value and appends it torsync_args.- The
evalstatement reparses the value as shell syntax. - The attacker's command executes with the privileges and environment of the account running Update Plus.
Impact Assessment
Successful exploitation provides arbitrary command execution as the current use ...[truncated 277 chars]
- Remediation
View remediation
Remediation Suggestions
Remove
evalentirely and construct the command with a Bash array:bash local rsync_args=(-a) while IFS= read -r exclude; do if [[ -n "$exclude" ]]; then rsync_args+=(--exclude="$exclude") fi done <<< "$dir_excludes" if [[ -z "$dir_excludes" ]]; then rsync_args+=( --exclude=".venv" --exclude="node_modules" --exclude="*.pyc" --exclude="__pycache__" ) fi rsync "${rsync_args[@]}" \ "$dir_path/" \ "$tmp_backup_dir/$dir_label/" 2>/dev/nullIn addition:
- Validate that
backup_pathsis an array of objects with string paths, labels, and exclusion entries. - Reject labels containing path separators or traversal sequences.
- Restrict configuration-file permissions to the owning user, preferably mode
0600. - Fail closed when configuration types are invalid instead of continuing with partially parsed values.
- Validate that
