Почему действие '-execdir' небезопасно для каталога, который находится в PATH?

Почему небезопасно использовать комбинацию -execdir действия поиска при использовании -exec - нет?

Когда я запускаю указанную ниже команду, я получаю следующее сообщение:

/path/to/currentDir/$ find . -type f -name 'partOfFileNames*' -execdir rm -- {} +

find: The current directory is included in the PATH environment variable, which is insecure 
in combination with the -execdir action of find.  Please remove the current directory 
from your $PATH (that is, remove "." or leading or trailing colons)

Что может вызвать появление этого приглашения?

19
задан 9 April 2019 в 13:28

5 ответов

Вы могли запустить неправильную программу. Кто-то мог заставить Вас запустить их программу.

-execdir действие выполняет Вашу команду из каталога, который содержит найденный файл (файлы). Когда $PATH содержит относительные пути, такой как . или что-либо, что не запускается с /, -execdir небезопасно, потому что каталог, где файл найден (или другой каталог, разрешенный относительно него), мог также содержать исполняемый файл того же имени как то, которое Вы пытаетесь выполнить. Тот потенциально недоверяемый исполняемый файл затем выполнить вместо этого.

Это могло быть сознательно использовано другим пользователем, чтобы заставить Вас запускать их программу, которая могла бы нанести ущерб или нарушить безопасность данных вместо программы, которую Вы пытаетесь запустить. Или менее часто это могло бы просто привести к неправильной программе, непреднамеренно выполняемой, даже ни с кем пытающимся заставить проблему произойти.

Если все в Вашем PATH переменная среды является полным путем, эта ошибка не должна происходить, даже если каталог Вы ищете и -execdirлуг от содержится в PATH. (Я проверил, что это работает.), Если Вы верите, у Вас нет относительных каталогов в $PATH но все еще получают эту ошибку, обновите свой вопрос с деталями включая вывод echo "$PATH".

Конкретный пример.

Как пример того, что могло пойти не так, как надо, предположите:

  • Alice имеет . в ней $PATH потому что она хочет смочь запустить программы в любом каталоге, она cd'd к, не потрудившись предварительно ожидать их имена с ./.
  • Заклятая подруга Alice Eve совместно использовала /home/eve/shared с Alice.
  • Alice хочет статистику (строки, слова, байты) на .c файлы Eve совместно использовали с нею.

Так выполнения Alice:

find ~eve/shared -name \*.c -execdir wc {} \;

К сожалению для Alice Канун создал ее собственный сценарий, названный им wc, установите его исполняемый файл (chmod +x), и помещенный это тайно в один из каталогов под /home/eve/shared. Сценарий кануна похож на это:

#!/bin/sh
/usr/bin/wc "$@"
do_evil    # Eve replaces this command with whatver evil she wishes to do

Таким образом, когда Alice использует find с -execdir работать wc на файлах Eve совместно использовала, и это добирается до файлов в том же каталоге как пользовательская Eve wc сценарий, Eve wc выполнения - со всеми полномочиями Alice!

(бывший лукавым, Eve сделала ее wc действие сценария как обертка для системы wc, таким образом, Alice не будет даже знать, что что-то пошло не так, как надо, т.е. это do_evil был выполнен. Однако более простой - и также более сложный - изменения возможны.)

Как find предотвращает это.

find предотвращает эту проблему безопасности, отказываясь брать -execdir действие, когда $PATH содержит относительный каталог.

find предложения два сообщения диагностики в зависимости от определенной ситуации.

  • Если . находится в $PATH, затем (как Вы видели) это говорит:

    find: The current directory is included in the PATH environment variable, which is insecure in combination with the -execdir action of find. Please remove the current directory from your $PATH (that is, remove "." or leading or trailing colons)

    Это, вероятно, имеет специальное сообщение для . случай, поскольку это особенно распространено.

  • Если относительный путь кроме .- скажите, foo- появляется в $PATH и Вы работаете find с -execdir, это говорит:

    find: The relative path `foo' is included in the PATH environment variable, which is insecure in combination with the -execdir action of find. Please remove that entry from $PATH

Лучше не иметь относительные пути в $PATH вообще.

Риск наличия . или другие относительные пути в $PATH особенно усилен при использовании утилиты, которая автоматически изменяет каталог, который является почему find не позволит Вам использовать -execdir в этой ситуации.

Но имея относительные пути, особенно ., в Вашем $PATH по сути опасно и действительно лучше всего избегается так или иначе. Рассмотрите вымышленную ситуацию в примере выше. Предположим вместо выполнения find, Alice просто cds к ~eve/shared/blah и выполнения wc *.c. Если blah содержит Eve wc сценарий, do_evil выполнения как Alice.

22
ответ дан 9 April 2019 в 13:28

Существует много подробной информации здесь . Другая превосходная ссылка здесь . Заключить в кавычки из первой ссылки:

опция-execdir является более современной опцией, представленной в находке GNU, попытка создать более безопасную версию - должностное лицо. Это имеет то же, семантическое как - должностное лицо с двумя важными улучшениями:

Это всегда обеспечивает, полный путь в файл (использующий относительный путь для файла действительно опасно в случае - должностное лицо).

В дополнение к обеспечению полного пути это также проверяет переменную ПУТИ на безопасность (если точка присутствует в переменной ENV ПУТИ, Вы можете исполняемый файл погрузки из неправильного каталога)

Из второй ссылки:

†˜-execdir’ действие отказывается делать что-либо, если текущий каталог включен в переменную среды $PATH. Это необходимо, потому что †˜-execdir’ запускает программы в том же каталоге, в котором он находит файлы †“в целом, такой каталог мог бы быть перезаписываем недоверяемыми пользователями. По подобным причинам †˜-execdir’ не позволяет †˜ {} ’, казаться, от имени команды быть выполненным.

0
ответ дан 9 April 2019 в 13:28

Основная проблема со значением системной переменной PATH который содержит относительные папки в нем, таким образом, из соображений безопасности find команда не позволит Вам выполнять двоичные файлы, потому что потенциально она может выполнить неправильные программы.


Так, например, если у Вас есть свой текущий dir в Вашем ПУТИ согласно предупреждению, которое Вы получаете:

Текущий каталог включен в переменную окружения PATH.

и Вы выполните свою команду:

find . -type f -name 'partOfFileNames*' -execdir rm -- {} +

в случае, если у Вас будет локальный сценарий (rm с исполняемыми флагами) содержащий rm -fr / в нем он может удалить все Ваши файлы, потому что вместо того, чтобы выполниться ожидал /bin/rm, Вы выполнитесь rm от текущего dir так вероятно, это не то, что Вы хотели.


Как примечание стороны, это известно проблема в Travis CI (GH № 2811), когда это перестало работать с ошибкой:

найдите: относительный путь './node_modules/.bin' включен в переменную окружения PATH, которая небезопасна в сочетании с-execdir действием находки. Удалите ту запись из $PATH

Таким образом, решение состоит в том, чтобы удалить затронутую запись из переменной ПУТИ, например.

PATH=`echo $PATH | sed -e 's/:\.\/node_modules\/\.bin//'`

как предложено drogus. Прогресс этой ошибки, может сопровождаться в № 4862 GH.


Вот обходное решение версии Bash:

PATH=${PATH//:\.\/node_modules\/\.bin/}

Использование в качестве примера (передающий фильтрованный PATH к определенной команде):

env PATH=${PATH//:\.\/node_modules\/\.bin/} find . -type f
3
ответ дан 9 April 2019 в 23:28
  • 1
    Это m.2 места размещения SSD при более чем 2 500 чтениях и более чем 1 500 записях (yikes!). Используя те же аппаратные и операционные системы, просто изменившись на btrfs, я надеваю чтение 500 МБ и записи не кэшируемые файлы. Я ценю Ваш вход и поддержку, но с успехом до сих пор с btrfs я собираюсь попробовать это некоторое время. Я просто обновил свое ядро и btrfs-progs к 4,7, таким образом, у меня есть последний btrfs теперь. Система очень стабильна. – CB40 10 August 2016 в 11:18

xargs и bash -c cd обходное решение

хорошо, я сдаюсь:

find . -type f |
  xargs -I '{}' bash -c 'cd "$(dirname "{}")" && pwd && echo "$(basename "{}")"'

sed обходное решение

Немного менее хороший, чем предыдущее обходное решение:

PATH="$(echo "$PATH" | sed -E 's/(^|:)[^\/][^:]*//g')" find . -execdir echo '{}' \;

тестовый сценарий А:

[ "$(printf '/a/b::c/d:/e/f\n' | sed -E 's/(^|:)[^\/][^:]*//g')" = '/a/b:/e/f' ] || echo fail

Для rename а именно, можно также работать вокруг с некоторым Perl regex-fu: https://надежда stackoverflow.com/questions/16541582/finding-multiple-files-recursively-and-renaming-in-linux/54163971#54163971

RTFS, сокрушительная

Для тех, у кого есть надежды, что там существует способ проигнорировать find самоуверенность, позвольте мне сокрушить это с некоторым источником:

От этого, мы видим, что там, кажется, не способ выключить проверку пути.

точное правило, которое это проверяет: перестали работать, если эти PATH или пусто или не запускается с /.

0
ответ дан 18 April 2019 в 00:31

Временное решение - передать пользовательский ПУТЬ перед командой, например

PATH=/usr/bin find . -type f -name 'partOfFileNames*' -execdir echo rm -- {} +

Вышеупомянутый обходной путь предотвратит загрузку глобального $ PATH , но нашего собственного.


Вот еще один пример (более гибкий), предполагающий, что мы хотим запустить команду cat :

PATH=$(dirname $(which find)):$(dirname $(which cat)) find /etc -name hosts -execdir cat {} ';'

или:

PATH=$(dirname $(which cat find) | paste -sd:) find ...

, запустив $ (dirname $ (which cat)) мы вычисляем, где находится наша команда для запуска.

2
ответ дан 2 May 2020 в 17:40

Другие вопросы по тегам:

Похожие вопросы: