From 63780c4c4b5a15b95631bab8abfe86fcd85fc9d0 Mon Sep 17 00:00:00 2001 From: Dennis Fink Date: Tue, 24 Feb 2026 21:13:23 +0100 Subject: fix(preset): refuse to source world-writable preset files Preset files are executed as shell code. A world-writable preset file could be modified by any local user to inject arbitrary commands. Symlinks are resolved before the permission check because stat on a symlink returns the permissions of the link itself (always 777 on Linux) rather than those of the target. readlink -f is used with a fallback to realpath for macOS/BSD compatibility. --- transcode.sh | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/transcode.sh b/transcode.sh index 7a0a9cb..15dba25 100755 --- a/transcode.sh +++ b/transcode.sh @@ -381,6 +381,21 @@ load_preset() { debug "Sourcing preset file:" "$file" + # Reject preset files that are world-writable to prevent arbitrary users + # from injecting shell code. + # + # Symlinks must be resolved first: stat on a symlink returns the permissions + # of the symlink itself (always 777 on Linux), not the target. We use + # readlink -f (GNU) with a fallback to realpath for macOS/BSD. + local resolved_file + resolved_file=$(readlink -f -- "$file" 2>/dev/null || realpath -- "$file") + local preset_perms + preset_perms=$(stat -c '%a' -- "$resolved_file" 2>/dev/null || stat -f '%OLp' -- "$resolved_file") + if [[ "${preset_perms: -1}" =~ [2367] ]]; then + error "Preset file is world-writable, refusing to source:" "$resolved_file" + exit $EXIT_CONFIG_ERROR + fi + unset -v ffargs ffargs=() -- cgit v1.3.1