Bash script arg0 уязвимость?

Можно ли явно использовать аргумент $ 0 скрипта оболочки (скрипт bash) при запуске скрипта?

Рассмотрим следующий сценарий:

readonly SCRIPT_HELP="$(cat <<EOF Usage: $(basename "$0") [-h] EOF )" echo "${SCRIPT_HELP}" 

Можно ли передать что-то еще в качестве аргумента 0 в этот сценарий bash, поэтому оценка $(basename... будет выполнена с некоторым кодом, предоставленным пользователем (потенциально опасным)?

И вообще, если можно использовать тот факт, что аргумент 0 не дезактивируется должным образом в конкретном сценарии оболочки?

Тривиально можно решить, что такое $0 . Просто создайте ссылку:

 $ cat foo.sh #! /bin/bash readonly SCRIPT_HELP="$(cat <<EOF Usage: $(basename "$0") [-h] EOF )" echo "${SCRIPT_HELP}" $ ./foo.sh Usage: foo.sh [-h] EOF $ ln -s foo.sh bar.sh $ ./bar.sh Usage: bar.sh [-h] EOF 

В этом конкретном случае нет, я не думаю, что это будет возможно использовать с любым большим преимуществом. "$0" и SCRIPT_HELP цитируются при использовании (внутри вложенных подстановок команд и heredocs, но тем не менее цитируются), и они не eval .

 $ ln -s ./foo.sh '"; echo rm -rf ~; echo"' $ ./\"\;\ echo\ rm\ -rf\ \~\;\ echo\" Usage: "; echo rm -rf ~; echo" [-h] EOF 

$0 может быть любым вызовом сценария. Это путь к скрипту, и вызывающий может сделать копию или ссылку на скрипт в любом месте.

Однако это не является уязвимостью в себе, если скрипт не работает с большим количеством привилегий, чем его вызывающий. Если исполняемый файл сценария не является привилегированным, вызывающий может запускать другую программу. Это может стать уязвимостью, если вызывающий абонент сам обладает привилегиями и может быть убежден в том, что передал другой $0 .

Если скрипт работает с привилегиями, то какой $0 может быть зависеть от метода, используемого для повышения привилегий. Если скрипт вызывается через символическую ссылку на исполняемый файл setuid, тогда $0 может быть произвольным (однако большинство систем отказываются от исполняемых файлов setuid).

Независимо от отсутствия влияния на безопасность в большинстве сценариев в данном конкретном случае, ваш скрипт не полностью устойчив к произвольным $0 . Двойные кавычки в "$0" заставляют использовать значение как есть (тогда как некорректный $0 будет рассматривать его как список шаблонов подстановочных знаков). Но когда команда basename видит это значение как аргумент, он будет обрабатывать его по-разному в зависимости от того, начинается ли значение с. Если значение начинается с a - (и не просто - ), то это опция. По крайней мере, с basename GNU, необязательный аргумент является обязательным, поэтому вызов его одним аргументом, который начинается с - приведет только к ошибке. Но это большая проблема с некоторыми другими командами . Чтобы справиться с произвольными значениями, включая те, которые начинаются с - , поместите -- перед аргументом, чтобы указать, что больше нет параметров: basename -- "$0" .