find -execdir
is recommended over -exec
, which the manual says has unavoidable security issues, and lists in the bugs section.
man find
says regarding -execdir
:
If you use this option, you must ensure that your
$PATH
environment variable does not reference.
; otherwise, an attacker can run any commands they like by leaving an appropriately- named file in a directory in which you will run-execdir
. The same applies to having entries in$PATH
which are empty or which are not absolute directory names.
In a bash
script, how does one comply with the manual's "must" and remove all relative or empty elements from $PATH
?
You can sanitize your PATH
using the following bash function:
sanitize_PATH()
{
local new_path=""
local dir
while read -r -d: dir
do
if [[ $dir == /* ]]
then
new_path="$new_path:$dir"
else
echo "dropping from PATH: '$dir'"
fi
done <<< "$PATH:"
PATH="${new_path#:}"
echo PATH="$PATH"
}
Testing:
$ PATH=/usr/local/bin:/usr/bin:/bin sanitize_PATH
PATH=/usr/local/bin:/usr/bin:/bin
$ PATH=:/usr/local/bin:/usr/bin:/bin sanitize_PATH
dropping from PATH: ''
PATH=/usr/local/bin:/usr/bin:/bin
$ PATH=/usr/local/bin:/usr/bin:/bin: sanitize_PATH
dropping from PATH: ''
PATH=/usr/local/bin:/usr/bin:/bin
$ PATH=/usr/local/bin:/usr/bin:/bin: sanitize_PATH
dropping from PATH: ''
PATH=/usr/local/bin:/usr/bin:/bin
$ PATH=.:bin:/usr/local/bin:/usr/bin:/bin sanitize_PATH
dropping from PATH: '.'
dropping from PATH: 'bin'
PATH=/usr/local/bin:/usr/bin:/bin
$ PATH=/usr/local/bin::/usr/bin:/bin sanitize_PATH
dropping from PATH: ''
PATH=/usr/local/bin:/usr/bin:/bin