T09 · Insecure Skill Coding Practices
- Location
scripts/arr-all-calendar.sh:19- Finding
Predictable Temporary Files Permit Symlink-Based File Overwrite
- Content
View full analysis
Vulnerability Details
File Location:
scripts/arr-all-calendar.sh:19-30, 37-40, 47-50, 74
Vulnerability Type: Insecure predictable temporary-file creation
Risk Level: MediumVulnerable Code
bash # Temp file for aggregating results TMP_CAL="/tmp/arr-all-calendar-$$.json" echo "[]" > "$TMP_CAL" # RADARR if load_config "radarr"; then res=$(api_request "radarr" "GET" "/api/v3/calendar?start=$START_DATE&end=$END_DATE") echo "$res" | jq '[.[] | {date: (.inCinemas // .physicalRelease // .digitalRelease // .status), type: "[M]", title: "\(.title) (\(.year))", hasFile: .hasFile, sortKey: (.inCinemas // .physicalRelease // .digitalRelease // .status)}]' > "${TMP_CAL}.radarr" jq -s '.[0] + .[1]' "$TMP_CAL" "${TMP_CAL}.radarr" > "${TMP_CAL}.tmp" && mv "${TMP_CAL}.tmp" "$TMP_CAL" rm "${TMP_CAL}.radarr" fi # SONARR if load_config "sonarr"; then res=$(api_request "sonarr" "GET" "/api/v3/calendar?start=$START_DATE&end=$END_DATE&includeSeries=true") echo "$res" | jq '[.[] | {date: .airDate, type: "[TV]", title: "\(.series.title // "Unknown") S\(.seasonNumber)E\(.episodeNumber) - \(.title // "TBA")", hasFile: .hasFile, sortKey: .airDate}]' > "${TMP_CAL}.sonarr" jq -s '.[0] + .[1]' "$TMP_CAL" "${TMP_CAL}.sonarr" > "${TMP_CAL}.tmp" && mv "${TMP_CAL}.tmp" "$TMP_CAL" rm "${TMP_CAL}.sonarr" fi # LIDARR if load_config "lidarr"; then res=$(api_request "lidarr" "GET" "/api/v1/calendar?start=$START_DATE&end=$END_DATE") echo "$res" | jq '[.[] | {date: .releaseDate, type: "[Music]", title: "\(.artist.artistName) - \(.title)", hasFile: (.grabbed or .hasFile), sortKey: .releaseDate}]' > "${TMP_CAL}.lidarr" jq -s '.[0] + .[1]' "$TMP_CAL" "${TMP_CAL}.lidarr" > "${TMP_CAL}.tmp" && mv "${TMP_CAL}.tmp" "$TMP_CAL" rm "${TMP_CAL}.lidarr" fi # Later cleanup rm "$TMP_CAL"Technical Analysis
The calendar script constructs temporary paths in the shared
/tmpdirectory using the process ID. Process IDs are predictabl ...[truncated 2131 chars]- Remediation
View remediation
Remediation Suggestions
- Create a private temporary directory atomically:
bash umask 077 TMP_DIR=$(mktemp -d "${TMPDIR:-/tmp}/arr-all-calendar.XXXXXX") || { echo "Failed to create temporary directory" >&2 exit 1 } trap 'rm -rf -- "$TMP_DIR"' EXIT INT TERM HUP TMP_CAL="$TMP_DIR/calendar.json" RADARR_CAL="$TMP_DIR/radarr.json" SONARR_CAL="$TMP_DIR/sonarr.json" LIDARR_CAL="$TMP_DIR/lidarr.json" MERGED_CAL="$TMP_DIR/merged.json" printf '%s\n' '[]' > "$TMP_CAL"- Place every intermediate file inside that private directory rather than constructing adjacent predictable paths.
- Preserve
umask 077while sensitive temporary files are created so only the current user can access them. - Use a cleanup trap to remove temporary data on success, error, or interruption.
- Abort immediately if temporary-file or directory creation fails.
- Do not run the Skill under a privileged account unless strictly necessary.
