Чому використання дії "-execdir" небезпечно для каталогу, який знаходиться в PATH?


19

Чому не можна використовувати комбінацію -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)

Що може спричинити появу цієї підказки?

Відповіді:


22

Ви можете запустити неправильну програму. Хтось може змусити вас запустити їх програму.

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

Це може бути навмисно використане іншим користувачем, щоб змусити вас запускати їх програму, що може спричинити шкоду або порушити безпеку даних замість програми, яку ви намагаєтеся запустити. Або, рідше, це може просто призвести до того, що неправильна програма буде ненавмисно запущена, навіть без того, щоб хтось намагався зробити цю проблему.

Якщо все в вашій PATHзмінній середовища це абсолютний шлях, ця помилка не повинна виникати, навіть якщо каталог , який ви шукаєте , і -execdirІНГ від це міститься в PATH. (Я перевірив, що це працює.) Якщо ви вважаєте, що у вас немає жодних відносних каталогів, $PATHале ви все ще отримуєте цю помилку, будь ласка, оновіть своє запитання деталями, включаючи вихідні дані echo "$PATH".

Конкретний приклад.

Прикладіть, наприклад, що може піти не так:

  • Аліса має .в своєму розпорядженні, $PATHтому що вона хоче мати змогу запускати програми в будь-якому каталозі, в якому вона була cdб, не намагаючись привласнити свої імена ./.
  • Вільшанка Аліса Єва поділилася /home/eve/sharedз Алісою.
  • Аліса хоче статистика (рядки, слова, байти) щодо .cфайлів, якими Єва поділилася з нею.

Отже, Аліса працює:

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

На жаль для Аліси, Єва створила свій власний сценарій, назвала його wc, встановила його виконуваним ( chmod +x) і підпільно розмістила його в одному з каталогів під /home/eve/shared. Сценарій Єви виглядає так:

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

Тому , коли Аліса використовує findз -execdirбігти wcна файлах Єва поділилася, і він отримує файли в тому ж каталозі, що і призначені для користувача Єви wcсценарію, Єви wcпробігів - з усіма привілеями Аліси!

(Будучи хитрою, Єва змусила wcсценарій виконувати функцію обгортки для системи wc, тому Аліса навіть не знає, що щось пішло не так, тобто це 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, Аліса просто cdперебирається ~eve/shared/blahі працює wc *.c. Якщо blahмістить wcсценарій Єви , do_evilпрацює як Аліса.


2
Я не знаю, чи чули ви це раніше, ви зробили б дуже гарного вчителя :)
heemayl

5
@heemayl всі, хто пише корисні речі в мережі, вже є вчителями :-)
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

5

Існує набагато більше докладна інформація тут . Ще одна відмінна довідка - тут . Цитую з першої посилання:

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

Він завжди забезпечує абсолютний шлях до файлу (використання відносного шляху до файлу дійсно небезпечно у випадку -exec).

Окрім надання абсолютного шляху, він також перевіряє змінну PATH на безпеку (якщо крапка присутня у змінній PATH env, ви можете забрати виконуваний файл із неправильного каталогу)

З другого посилання:

Дія '-execdir' відмовляється робити що-небудь, якщо поточна директорія включена в змінну середовища $ PATH. Це необхідно, тому що '-execdir' запускає програми в тому самому каталозі, в якому він знаходить файли - загалом такий каталог може бути доступним для запису недовіреними користувачами. З подібних причин "-execdir" не дозволяє "{}" з'являтися в імені команди, яку потрібно запустити.


Чи можете ви, будь ласка, розширити свою відповідь, чому "якщо крапка присутня у змінній PATH env, ви можете забрати виконуваний файл із неправильної директорії" ? який неправильний каталог ? І чому ми повинні це робити, щоб зробити це безпечним ? Спасибі
αғsnιη

Я сподіваюся , що друга ланка в моїй оновленої пост буде відповісти на ваше запитання
Рон

3

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


Так, наприклад, якщо у вас є ваш поточний рейтинг у вашому PATH відповідно до попередження, яке ви отримуєте:

Поточний каталог включений в змінну середовища PATH.

і ти запустиш свою команду:

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

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


Як бічна примітка, це відома проблема в Travis CI ( GH # 2811 ), коли вона не вдається з помилкою:

find: Відносний шлях `./node_modules/.bin 'включений в змінну середовища PATH, яка є небезпечною у поєднанні з дією -execdir пошуку. Видаліть цей запис із $ PATH

Таким чином, рішення полягає в тому, щоб видалити постраждалий запис із змінної PATH, наприклад

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

як запропоновано drogus . Прогрес цієї помилки можна спостерігати в GH # 4862 .


Ось спосіб вирішення версії Bash:

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

Приклад використання (передача відфільтрована PATHдо певної команди):

env PATH=${PATH//:\.\/node_modules\/\.bin/} find . -type f

Ось такий, sedякий, здається, видаляти всі речі findне любить: askubuntu.com/questions/621132/…
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

3

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 регулярний вираз-фу: /programming/16541582/finding-multiple-files-recursively-and-renaming-in-linux/54163971#54163971

RTFS сподівання розбиття

Для тих, хто сподівається, що існує спосіб ігнорувати findсамовпевненість, дозвольте мені це зв'язати з деяким джерелом:

З цього ми бачимо, що, здається, немає можливості вимкнути перевірку шляху.

Точне правило, яке воно перевіряє, таке: помилка, якщо PATHзначення пусте або не починається з /.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.