T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/bilibili_ai_subtitle.sh:109
- Finding
- Predictable Temporary File Allows Symlink-Based File Overwrite## Vulnerability Details **File Location**: `scripts/bilibili_ai_subtitle.sh`, lines 109–123 **Vulnerability Type**: Predictable temporary file and unsafe symbolic-link handling **Risk Level**: Medium ### Vulnerable Code ```bash " "$VIDEO_TITLE" "$VIDEO_AUTHOR" > /tmp/safe_name_$$ SAFE_NAME=$(cat /tmp/safe_name_$$) DATE_SHORT=$(echo "$VIDEO_DATE" | sed 's/-//g') # Simplify duration DURATION_SIMPLE=$(echo "$VIDEO_DURATION" | sed 's/分/./g; s/秒//g') [ -z "$SAFE_NAME" ] && SAFE_NAME="video_unknown" # Filename: video title, uploader, date, duration, and BVID FILENAME="${SAFE_NAME}_${DATE_SHORT}_${DURATION_SIMPLE}_${BVID}.txt" OUTPUT_FILE="${OUTPUT_DIR}/${FILENAME}" rm -f /tmp/safe_name_$$ ``` The first line shown is the closing portion of a multiline `python3 -c` command whose standard output is redirected to the temporary path. ### Technical Analysis The script constructs a temporary filename in the shared `/tmp` directory using the process ID: ```bash /tmp/safe_name_$$ ``` A process ID is predictable and does not provide secure uniqueness. The file is opened through ordinary shell redirection without atomic exclusive creation, ownership verification, restrictive permissions, or symbolic-link rejection. If the path already exists as a symbolic link, the shell follows that link when processing `>`, truncating and writing to its target with the privileges of the user running the script. The subsequent `cat` and `rm` operations do not mitigate the initial unsafe write. In addition, `rm` removes the symbolic link itself rather than reversing modifications made to its target. Exploitation requires local access sufficient to create entries in `/tmp`, an ability normally available to local users. The attacker must predict or observe the victim process ID and win the race before the redirection occurs. ### Attack Path 1. A local attacker predicts or observes the process ID that will be assigned to the script. 2. The attacker creates `/tmp/safe_name_<PI ...[truncated 1194 chars]
- Remediation
- ## Remediation Suggestions Avoid creating the temporary file because the Python output can be captured directly: ```bash SAFE_NAME=$(python3 -c ' import sys title = sys.argv[1] author = sys.argv[2] # Apply the existing sanitization logic here. print(f"{title}_{author}") ' "$VIDEO_TITLE" "$VIDEO_AUTHOR") || exit 1 ``` If a temporary file is necessary: 1. Create it atomically with `mktemp` rather than constructing a PID-based path. 2. Restrict permissions with `umask 077`. 3. verify that `mktemp` succeeded before writing. 4. Register a quoted cleanup trap immediately after creation. 5. Do not use a caller-controlled directory for security-sensitive temporary files. Example: ```bash umask 077 SAFE_NAME_FILE=$(mktemp "${TMPDIR:-/tmp}/bilibili-safe-name.XXXXXX") || { echo "Failed to create a secure temporary file" >&2 exit 1 } trap 'rm -f -- "$SAFE_NAME_FILE"' EXIT HUP INT TERM python3 -c '...' "$VIDEO_TITLE" "$VIDEO_AUTHOR" > "$SAFE_NAME_FILE" || exit 1 SAFE_NAME=$(cat -- "$SAFE_NAME_FILE") || exit 1 ``` Direct command substitution is preferable because it removes the temporary-file attack surface entirely.
