Fix security and robustness issues

- Replace eval with getent passwd to prevent command injection
- Use glob array instead of parsing ls output for .deb detection
- Handle multiple .deb files by selecting the newest one
- Add fstab duplicate check to prevent duplicate entries on re-run
- Validate mount point (must be absolute path) and filesystem type
- Handle mount -a failure gracefully instead of killing the script
- Add set -o pipefail

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
28allday 2026-03-28 12:14:36 +00:00
parent a2714aac1d
commit d972949159

View file

@ -25,7 +25,7 @@
# - Run with sudo: sudo ./plexint.sh # - Run with sudo: sudo ./plexint.sh
# ============================================================================== # ==============================================================================
set -e # Exit immediately if any command fails set -eo pipefail # Exit immediately if any command fails; catch pipe failures too
# Root is required because this script modifies /etc/fstab (system mount # Root is required because this script modifies /etc/fstab (system mount
# config), installs packages with apt, and manages systemd services. # config), installs packages with apt, and manages systemd services.
@ -86,6 +86,10 @@ else
echo echo
read -rp "Enter the mount point (e.g. /mnt/data): " MOUNT_POINT read -rp "Enter the mount point (e.g. /mnt/data): " MOUNT_POINT
if [[ -z "$MOUNT_POINT" || "$MOUNT_POINT" != /* ]]; then
echo "ERROR: Mount point must be an absolute path (e.g. /mnt/data)."
exit 1
fi
if [[ ! -d "$MOUNT_POINT" ]]; then if [[ ! -d "$MOUNT_POINT" ]]; then
echo "Creating mount point directory: ${MOUNT_POINT}" echo "Creating mount point directory: ${MOUNT_POINT}"
mkdir -p "$MOUNT_POINT" mkdir -p "$MOUNT_POINT"
@ -93,6 +97,10 @@ else
echo echo
read -rp "Enter the file system type (e.g., ext4, ntfs, xfs, exfat): " FS_TYPE read -rp "Enter the file system type (e.g., ext4, ntfs, xfs, exfat): " FS_TYPE
if [[ -z "$FS_TYPE" || "$FS_TYPE" =~ [[:space:]] ]]; then
echo "ERROR: Invalid filesystem type."
exit 1
fi
# If exfat is chosen, assume the system has exFAT support already (e.g., Ubuntu 20.04+). # If exfat is chosen, assume the system has exFAT support already (e.g., Ubuntu 20.04+).
if [[ "$FS_TYPE" == "exfat" ]]; then if [[ "$FS_TYPE" == "exfat" ]]; then
@ -115,11 +123,19 @@ else
read -rp "Proceed with adding to /etc/fstab? (y/n): " CONFIRM_MOUNT read -rp "Proceed with adding to /etc/fstab? (y/n): " CONFIRM_MOUNT
if [[ "$CONFIRM_MOUNT" =~ ^[Yy]$ ]]; then if [[ "$CONFIRM_MOUNT" =~ ^[Yy]$ ]]; then
# Check if this device/UUID is already in fstab to prevent duplicates
if grep -qF "$DEVICE_IDENTIFIER" /etc/fstab; then
echo "WARNING: An entry for ${DEVICE_IDENTIFIER} already exists in /etc/fstab. Skipping."
else
echo "Adding line to /etc/fstab..." echo "Adding line to /etc/fstab..."
echo "${FSTAB_LINE}" >> /etc/fstab echo "${FSTAB_LINE}" >> /etc/fstab
fi
echo "Attempting to mount all file systems now (mount -a)..." echo "Attempting to mount all file systems now (mount -a)..."
mount -a if ! mount -a; then
echo "WARNING: mount -a failed. Check the fstab entry. Continuing to Part B..."
else
echo "Drive mount process complete." echo "Drive mount process complete."
fi
else else
echo "Skipping drive mount configuration." echo "Skipping drive mount configuration."
fi fi
@ -151,7 +167,7 @@ if [[ "$INSTALL_PLEX" =~ ^[Yy]$ ]]; then
else else
ORIGINAL_USER="$USER" ORIGINAL_USER="$USER"
fi fi
DOWNLOADS_DIR="$(eval echo ~${ORIGINAL_USER})/Downloads" DOWNLOADS_DIR="$(getent passwd "${ORIGINAL_USER}" | cut -d: -f6)/Downloads"
# Update the package database and install prerequisites: # Update the package database and install prerequisites:
# curl: For downloading files (used by Plex internally) # curl: For downloading files (used by Plex internally)
@ -165,15 +181,23 @@ if [[ "$INSTALL_PLEX" =~ ^[Yy]$ ]]; then
# Look for the Plex .deb in the user's Downloads folder. The filename # Look for the Plex .deb in the user's Downloads folder. The filename
# typically looks like "plexmediaserver_1.40.0.1234-abcdef_amd64.deb". # typically looks like "plexmediaserver_1.40.0.1234-abcdef_amd64.deb".
PLEX_DEB=$(ls -1 "${DOWNLOADS_DIR}"/plexmediaserver*.deb 2>/dev/null || true) # We use a glob array instead of parsing ls output, which is safer for
# filenames with spaces and gives us control over multiple matches.
shopt -s nullglob
plex_debs=("${DOWNLOADS_DIR}"/plexmediaserver*.deb)
shopt -u nullglob
if [[ -z "$PLEX_DEB" ]]; then if [[ ${#plex_debs[@]} -eq 0 ]]; then
echo "ERROR: No 'plexmediaserver*.deb' file found in ${DOWNLOADS_DIR}." echo "ERROR: No 'plexmediaserver*.deb' file found in ${DOWNLOADS_DIR}."
echo "Please place the downloaded Plex .deb file there and rerun if needed." echo "Please place the downloaded Plex .deb file there and rerun if needed."
else else
echo "Found Plex .deb file(s):" if [[ ${#plex_debs[@]} -gt 1 ]]; then
echo "$PLEX_DEB" echo "Multiple .deb files found. Using the newest one:"
echo "Installing Plex Media Server..." PLEX_DEB="$(ls -1t "${plex_debs[@]}" | head -n1)"
else
PLEX_DEB="${plex_debs[0]}"
fi
echo "Installing: ${PLEX_DEB}"
# Install the .deb package. dpkg -i may fail if dependencies are missing # Install the .deb package. dpkg -i may fail if dependencies are missing
# (it doesn't resolve them automatically). That's OK — apt-get -f install # (it doesn't resolve them automatically). That's OK — apt-get -f install