T09 · Insecure Skill Coding Practices
- Location
scripts/script.sh:5- Finding
Insecure Persistent Logging and Symlink-Following File Writes
- Content
View full analysis
Vulnerability Details
File Location:
scripts/script.sh:5-7, 34, 38-83
Vulnerability Type: Plaintext argument logging, unsafe file permissions, and symlink-following writes
Risk Level: MediumVulnerable Code
bash DATA_DIR="${COZE_STUDIO_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/coze-studio}" DB="$DATA_DIR/data.log" mkdir -p "$DATA_DIR" _log() { echo "$(date '+%m-%d %H:%M') $1: $2" >> "$DATA_DIR/history.log"; } cmd_run() { echo " Running: $1" _log "run" "${1:-}" } cmd_config() { echo " Config: $DATA_DIR/config.json" _log "config" "${1:-}" } cmd_status() { echo " Status: ready" _log "status" "${1:-}" } cmd_init() { echo " Initialized in $DATA_DIR" _log "init" "${1:-}" } cmd_list() { [ -f "$DB" ] && cat "$DB" || echo " (empty)" _log "list" "${1:-}" } cmd_add() { echo "$(date +%Y-%m-%d) $*" >> "$DB"; echo " Added: $*" _log "add" "${1:-}" } cmd_remove() { echo " Removed: $1" _log "remove" "${1:-}" } cmd_search() { grep -i "$1" "$DB" 2>/dev/null || echo " Not found: $1" _log "search" "${1:-}" } cmd_export() { [ -f "$DB" ] && cat "$DB" || echo "No data" _log "export" "${1:-}" } cmd_info() { echo " Version: $VERSION | Data: $DATA_DIR" _log "info" "${1:-}" }Technical Analysis
The script creates its data directory and append-only data files without setting a restrictive
umaskor explicitly enforcing permissions. Consequently, the resulting directory and files inherit the caller's environment-dependent default permissions. In environments with a permissive umask or a sharedCOZE_STUDIO_DIR,data.logandhistory.logmay be readable or writable by other local users.User-controlled command arguments are stored in plaintext. The
addcommand writes every argument todata.log, while most operational commands pas ...[truncated 2706 chars]- Remediation
View remediation
Remediation Suggestions
-
Set a restrictive process umask before creating any storage:
bash umask 077 -
Create and verify the storage directory with owner-only permissions:
bash mkdir -p -- "$DATA_DIR" chmod 700 -- "$DATA_DIR" -
Canonicalize the selected directory and verify that it is owned by the current user. Reject shared, world-writable, or unexpectedly redirected paths.
-
Refuse symbolic-link targets before writing. Prefer opening files with a mechanism that enforces
O_NOFOLLOW; where only shell facilities are available, verify that the destination is not a symbolic link immediately before use and avoid privileged execution because shell checks alone can remain susceptible to race conditions. -
Create
data.logandhistory.logwith mode0600, then verify their ownership, type, and permissions before every write. -
Do not log raw command arguments by default. Remove argument logging where it is not essential, or redact secrets, tokens, credentials, and other sensitive values. Clearly document any persistent logging behavior.
-
Use
printfinstead ofechofor data writes to avoid implementation-dependent handling of values beginning with options or containing escape sequences:bash printf '%s %s\n' "$(date +%Y-%m-%d)" "$*" >> "$DB" -
Do not run the utility as root or through privileged automation unless the storage path is fixed, trusted, owner-controlled, and protected against link-based file writes.
-
