T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/check_session_state.sh:21
- Finding
- Predictable Temporary File Allows Symlink-Based File Clobbering<![CDATA[ ## Vulnerability Details **File Location**: `scripts/check_session_state.sh`, lines 21-50 **Vulnerability Type**: Predictable temporary file and unsafe file replacement **Risk Level**: Medium ### Vulnerable Code ```bash truncate_if_needed() { local line_count line_count=$(wc -l < "$SESSION_STATE" 2>/dev/null || echo "0") if [ "$line_count" -gt "$MAX_LINES" ]; then echo "⚠️ SESSION-STATE.md has $line_count lines (>$MAX_LINES), truncating to last $KEEP_LINES lines..." local truncated_count=$((line_count - KEEP_LINES)) echo " (Truncating $truncated_count lines of history)" tail -"$KEEP_LINES" "$SESSION_STATE" > "${SESSION_STATE}.tmp" { echo "---" echo "## 📋 历史截断通知" echo "" echo "**时间**: $(date -Iseconds)" echo "**原因**: 文件超过 ${MAX_LINES} 行(当前 ${line_count} 行)" echo "**操作**: 保留最近 ${KEEP_LINES} 行,截断 ${truncated_count} 行历史" echo "**建议**: 重要内容已归档至 SESSION-STATE-history.md" echo "" echo "---" echo "" cat "${SESSION_STATE}.tmp" } > "$SESSION_STATE" rm -f "${SESSION_STATE}.tmp" echo "✅ Truncation complete. New size: $(wc -l < "$SESSION_STATE") lines" fi } ``` ### Technical Analysis The script uses the fixed path `${SESSION_STATE}.tmp` as a temporary file. Shell output redirection creates or truncates that path without exclusive creation, ownership verification, or symlink rejection. If the script is executed with elevated privileges and an attacker can create entries in the workspace directory, the attacker can pre-create `SESSION-STATE.md.tmp` as a symbolic link. The redirection used by `tail` will follow that link and truncate or overwrite the linked target with the last 1,000 lines of the session-state file. The script hardcodes the workspace under `/root/.openclaw/workspace`, increasing the potential ...[truncated 1197 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Create temporary files with `mktemp` rather than a predictable filename. - Set `umask 077` before creating temporary or tracker files. - Create the temporary file in the same directory as the destination so that the final rename remains atomic. - Use a cleanup trap to remove the temporary file on interruption. - Validate that the destination and workspace directory are not attacker-controlled. - Replace the original file using an atomic `mv` only after all temporary output has been written successfully. Example hardening pattern: ```bash umask 077 tmp_file=$(mktemp "${SESSION_STATE}.tmp.XXXXXX") trap 'rm -f -- "$tmp_file"' EXIT tail -n "$KEEP_LINES" -- "$SESSION_STATE" > "$tmp_file" final_file=$(mktemp "${SESSION_STATE}.new.XXXXXX") trap 'rm -f -- "$tmp_file" "$final_file"' EXIT { printf '%s\n' "---" printf '%s\n' "## History truncation notice" printf '%s\n\n' "**Time**: $(date -Iseconds)" cat -- "$tmp_file" } > "$final_file" mv -f -- "$final_file" "$SESSION_STATE" rm -f -- "$tmp_file" trap - EXIT ``` ]]>
