T05 · Unauthorized Access and Privilege Escalation
Error
- Location
- scripts/kill-download.sh:24
- Finding
- Untrusted PID Files Allow Unauthorized Process Termination<![CDATA[ ## Vulnerability Details **File Location**: `scripts/kill-download.sh:24-61` **Vulnerability Type**: Untrusted process identifier and insufficient process ownership validation **Risk Level**: High ### Vulnerable Code ```bash SESSION_FILE="/tmp/${SESSION_ID}.session" PID_FILE="/tmp/${SESSION_ID}.pid" LOG_FILE="/tmp/${SESSION_ID}.log" if [ ! -f "$PID_FILE" ]; then echo "Error: Process not found for session: $SESSION_ID" exit 1 fi PID=$(cat "$PID_FILE") # Check if process exists if ! kill -0 "$PID" 2>/dev/null; then echo "Process already terminated (PID: $PID)" rm -f "$SESSION_FILE" "$PID_FILE" "$LOG_FILE" exit 0 fi echo "Stopping download process..." echo "Session: $SESSION_ID" echo "PID: $PID" if [ "$FORCE" = "--force" ]; then # Force kill kill -9 "$PID" 2>/dev/null echo "✅ Force killed process $PID" else # Graceful kill kill "$PID" 2>/dev/null sleep 2 # Check if still running if kill -0 "$PID" 2>/dev/null; then echo "Process still running, forcing kill..." kill -9 "$PID" 2>/dev/null fi echo "✅ Process stopped" fi ``` ### Technical Analysis The script trusts a PID read from a file under the shared `/tmp` directory. It does not validate that the file was created by the download script, that its contents are a positive decimal PID, or that the referenced process is the expected `yt-dlp` process belonging to the recorded session. The caller also controls `SESSION_ID`, which determines the PID file path. An attacker able to create or replace a corresponding file can insert the PID of an unrelated process. Negative process selectors are not rejected. For example, a PID value of `-1` can cause the shell's `kill` command to signal all processes that the executing account is permitted to signal. The `kill -0` check only establishes that a signalable matching process or process set exists. It does not establish ownership by this skill or bind the PID to the original proc ...[truncated 1753 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Create a private runtime directory owned by the executing account: ```bash umask 077 RUNTIME_DIR="${XDG_RUNTIME_DIR:-$HOME/.local/run}/video-download-faas" mkdir -p -- "$RUNTIME_DIR" chmod 700 -- "$RUNTIME_DIR" ``` 2. Strictly validate session identifiers against the generated format: ```bash [[ "$SESSION_ID" =~ ^video_dl_[0-9]+_[0-9]+$ ]] || exit 1 ``` 3. Validate the PID as a positive decimal integer and explicitly reject zero and negative values: ```bash [[ "$PID" =~ ^[1-9][0-9]*$ ]] || exit 1 ``` 4. Use the end-of-options marker for signal operations: ```bash kill -0 -- "$PID" kill -TERM -- "$PID" kill -KILL -- "$PID" ``` 5. Bind each session to the original process identity by recording and verifying: - PID. - Process start time from `/proc/<pid>/stat`. - Executable path or command identity. - Owning user. 6. Refuse to terminate the process if any recorded identity attribute differs. 7. Create state files atomically and reject symbolic links. 8. Run the skill as a dedicated, unprivileged account and never as root. ]]>
