T09 · Insecure Skill Coding Practices
- Location
scripts/cleanup.sh:5- Finding
Unvalidated retention value permits find expression injection and unintended file deletion
- Content
View full analysis
Vulnerability Details
File Location:
scripts/cleanup.sh, lines 5-18
Vulnerability Type: Unvalidated environment-variable injection into afindexpression
Risk Level: Mediumbash SESSIONS_DIR="${SESSIONS_DIR:-$HOME/.openclaw/workspace/sessions}" RETENTION_DAYS="${RETENTION_DAYS:-7}" LOG_FILE="${LOG_FILE:-$HOME/.openclaw/workspace/logs/session-cleanup.log}" # Create log directory if needed mkdir -p "$(dirname "$LOG_FILE")" mkdir -p "$SESSIONS_DIR" echo "[$(date '+%Y-%m-%d %H:%M:%S')] Starting session cleanup..." >> "$LOG_FILE" echo "[$(date '+%Y-%m-%d %H:%M:%S')] Sessions dir: $SESSIONS_DIR" >> "$LOG_FILE" echo "[$(date '+%Y-%m-%d %H:%M:%S')] Retention: $RETENTION_DAYS days" >> "$LOG_FILE" # Count files before BEFORE=$(find "$SESSIONS_DIR" -name "*.md" -type f 2>/dev/null | wc -l) # Delete files older than retention period find "$SESSIONS_DIR" -name "*.md" -type f -mtime +$RETENTION_DAYS -delete -print 2>/dev/null | while read -r file; doTechnical Analysis
RETENTION_DAYScan be supplied through the process environment and is neither validated as an integer nor safely passed as one argument. The unquoted expansion in-mtime +$RETENTION_DAYSundergoes shell word splitting. Consequently, a value containing spaces and additionalfindpredicates is interpreted as part of the expression rather than solely as an age value.For example, a value such as
7 -o -type ftransforms the effective expression into:bash find "$SESSIONS_DIR" -name "*.md" -type f -mtime +7 -o -type f -delete -printBecause
findevaluates conjunction before-o, the injected second branch can apply-deleteto every regular file under the selected directory, bypassing the intended Markdown filename and retention-age restrictions.The danger is amplified because
SESSIONS_DIRis also environment-configurable. Although it is correctly quoted against shell injection, it is not constrained to ...[truncated 1568 chars]- Remediation
View remediation
Remediation Suggestions
-
Validate
RETENTION_DAYSbefore using it:bash case "$RETENTION_DAYS" in ''|*[!0-9]*) echo "Invalid RETENTION_DAYS: must be a non-negative integer" >&2 exit 1 ;; esac -
Pass the complete age expression as one quoted argument:
bash find "$SESSIONS_DIR" -name '*.md' -type f -mtime "+${RETENTION_DAYS}" -delete -print -
Canonicalize
SESSIONS_DIRand verify that it is the expected sessions directory or a descendant of an explicitly approved workspace before performing deletion. -
Reject dangerous target directories, including empty paths,
/,$HOME, and the workspace root. -
Run cleanup as an unprivileged user and avoid installing the cron entry under
root. -
Consider removing the environment override for
SESSIONS_DIRunless configurability is required. If it is required, accept the path through a validated configuration file or explicit command-line option. -
Add a dry-run mode and log the candidate files before deletion, particularly for initial setup or retention-policy changes.
-
