T05 · Unauthorized Access and Privilege Escalation
Error
- Location
- scripts/jobctl.sh:100
- Finding
- Unvalidated Job Identifiers Enable Path Traversal and Unauthorized Process Control<![CDATA[ ## Vulnerability Details **File Location**: `scripts/jobctl.sh:100-117`, `scripts/jobctl.sh:533-550`, `scripts/jobctl.sh:645-656`, `scripts/jobctl.sh:873-890` **Vulnerability Type**: Path traversal, arbitrary file operations, and unsafe PID-file trust **Risk Level**: High ### Vulnerable Code ```bash get_state_file() { echo "${STATE_DIR}/${1}.json" } get_pid_file() { echo "${RUN_DIR}/${1}.pid" } get_log_file() { echo "${LOG_DIR}/${1}.log" } get_output_file() { echo "${STATE_DIR}/${1}.output" } get_feedback_file() { echo "${FEEDBACK_DIR}/${1}.feedback" } ``` The only validation performed by `cmd_start` is an empty-value check: ```bash # Validate job_id if [[ -z "$job_id" ]]; then log "ERROR" "Job ID is required" echo "Error: Job ID is required" >&2 exit 1 fi ``` The resulting paths are subsequently trusted for process management and file deletion: ```bash local pid_file=$(get_pid_file "$job_id") if [[ ! -f "$pid_file" ]]; then log "ERROR" "Job $job_id not found or already stopped" echo "Error: Job $job_id not found" >&2 exit 1 fi local pid=$(cat "$pid_file") if is_process_running "$pid"; then log "INFO" "Stopping job $job_id (PID: $pid)" kill -TERM "$pid" 2>/dev/null || true ``` ```bash rm -f "$(get_pid_file "$job_id")" \ "$(get_state_file "$job_id")" \ "$(get_log_file "$job_id")" \ "$(get_output_file "$job_id")" \ "$(get_feedback_file "$job_id")" \ "$RUN_DIR/${job_id}.wrapper.sh" ``` ### Technical Analysis The `job_id` value is directly concatenated into paths without restricting path separators, `..` components, control characters, absolute paths, or symlink behavior. Shell quoting prevents ordinary shell word splitting, but it does not prevent filesystem path traversal. Consequently, a value containing traversal components can cause state, PID, log, output, feedback, or wrapper operations to resolve outside their intended directories. The `stop` ope ...[truncated 1374 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Validate `job_id` centrally before any path construction. For example, require `^[A-Za-z0-9_-]{1,64}$`. - Reject path separators, `..`, absolute paths, newlines, and control characters. - Canonicalize each generated path and verify that it remains beneath its designated directory. - Reject symlinks and use secure, exclusive file creation where possible. - Store process ownership metadata and verify the actual process identity before sending signals. - Consider checking `/proc/<pid>` start time or a random per-job token to prevent stale or substituted PID-file attacks. - Add tests covering traversal, absolute paths, symlinks, malformed identifiers, and forged PID files. ]]>
