/usr/bin/env как хижина - и ее последствия для безопасности

/usr/bin/env как хижина - и ее последствия для безопасности

Я видел в нескольких местах советы использовать следующую фразу:

#!/usr/bin/env bash

вместо

#!/usr/bin/bash

Моя инстинктивная реакция: «А что, если кто-то заменит этот исполняемый файл своим собственным, скажем, в ~/.local/bin?» Этот каталог часто устанавливается в пути пользователя перед общесистемными путями. Я вижу, что это часто поднимается как проблема безопасности как побочное замечание, а не что-то, что следует воспринимать всерьез, но я хотел проверить теорию.

Чтобы попробовать это, я сделал следующее:

echo -e "#!/usr/bin/python\nprint 'Hacked!'" > $HOME/.local/bin/bash
chmod 755 $HOME/.local/bin/bash
PATH=$HOME/.local/bin env bash

Это дает

/usr/bin/env: ‘bash’: No such file or directory

Чтобы проверить, улавливает ли он вообще что-нибудь, я также сделал

echo -e "#!/usr/bin/python\nprint 'Hacked!'" > $HOME/.local/bin/perl
chmod 755 $HOME/.local/bin/perl
PATH=$HOME/.local/bin env perl

который печатает, как я и ожидал,

Hacked!

Может кто-нибудь объяснить мне, почему заменитель bashне найден, а заменитель perlесть? Это какая-то мера "безопасности", которая (с моей точки зрения) не соответствует сути?

EDIT: Поскольку мне подсказали: я не спрашиваю, чем /usr/bin/env bashэто отличается от использования /bin/bash. Я задаю вопрос, как указано выше.

EDIT2: Должно быть, я что-то делал не так. Попробовал еще раз сегодня (используя явный путь envвместо неявного), и никакого поведения "не найдено".

решение1

«что если кто-то заменит этот исполняемый файл своим собственным, скажем, в ~/.local/bin ?

Тогда сценарий для них не работает.

Но это не имеет значения, поскольку они могли бы взломать скрипт другими способами или запустить другую программу напрямую, не вмешиваясь PATHв env.

Если только ваши пользователи не имеютдругойкаталоги пользователей в их PATH, или могут редактировать каталоги PATHдругих пользователей, на самом деле нет никакой возможности, что один пользователь испортит другой.


Однако если бы это был не скрипт оболочки, а что-то, что предоставляет дополнительные привилегии, например, setuid-обертка для какой-то программы, то все было бы иначе. В этом случае это было бынеобходимыйиспользовать абсолютный путь для запуска программы, поместить ее в каталог, который непривилегированные пользователи не смогут изменить, и очистить среду при запуске программы.

решение2

Что касается разницы в поведении между оболочкой и perl, perlто в отличие от нее оболочка проверяет первую строку, чтобы определить, что именно следует запустить:

$ cat tcl
#!/usr/bin/env tclsh
puts "TCL running as [pid]"
$ perl tcl
TCL running as 39689
$ cat sbcl
#!/opt/local/bin/sbcl --script
(format t "~a running as ~a~%" 'lisp (sb-unix:unix-getpid))
$ perl sbcl
LISP running as 39766
$ 

Использование этой функции включает в себя:написание тестов на каком-либо другом языке, кроме perlпоэтому можно иметь TAP-совместимые скрипты на других языках и proveчто-то еще будет запускать их правильно.

решение3

Здесь нет риска для безопасности. /usr/bin/envпредполагается, что он выбирает соответствующий двоичный файл в соответствии со средой пользователя. Так что если пользователь установил свой собственный bashв ~/.local/bin, то /usr/bin/envон действительно должен попытаться использовать его (например, он мог скомпилировать версию с дополнительными функциями, которые недоступны в общесистемной версии, и предпочел бы использовать ее вместо общесистемной версии). То же самое касается любого другого двоичного файла/интерпретатора. Нет риска для безопасности, потому что пользователь не сможет запустить ничего, что он бы не смог запустить в любом случае.

Что касается того, почему в вашем случае подстановка не срабатывает, я сомневаюсь, что это как-то связано с /usr/bin/env. Попробуйте запустить PATH=~/.local/bin bash, PATH=~/.local/bin bash <path-to-script>(так он будет называться при запуске скрипта) и PATH=~/.local/bin /usr/bin/env bashпосмотрите, какой из них не сработает. Это должно дать подсказку о том, на что ссылается ошибка "файл не найден".

Связанный контент