Dlaczego użycie opcji „-execdir” jest niezabezpieczone dla katalogu znajdującego się w zmiennej PATH?

19

Dlaczego nie jest bezpieczne korzystanie z kombinacji -execdirakcji find podczas korzystania, -execnie jest?

Gdy uruchamiam poniższe polecenie, pojawia się następujący komunikat zachęty:

/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)

Co może powodować pojawienie się tego monitu?

αғsнιη
źródło

Odpowiedzi:

22

Możesz uruchomić niewłaściwy program. Ktoś może zmusić cię do uruchomienia ich programu.

The -execdirDziałanie prowadzi swoją komendę z katalogu, który zawiera plik (s) stwierdzono. Gdy $PATHzawiera ścieżki względne, takie jak .cokolwiek, co się nie zaczyna/ , -execdirjest niepewne, ponieważ katalog, w którym znajduje się plik (lub inny katalog rozwiązany względem niego) może również zawierać plik wykonywalny o tej samej nazwie, co ten, którego próbujesz biegać. Ten potencjalnie niezaufany plik wykonywalny zostałby wtedy uruchomiony.

Może to być celowo wykorzystane przez innego użytkownika, aby spowodować uruchomienie jego programu, co może spowodować uszkodzenie lub naruszenie bezpieczeństwa danych, zamiast programu, który próbujesz uruchomić. Lub, rzadziej, może to po prostu spowodować nieumyślne uruchomienie niewłaściwego programu, nawet bez próby spowodowania problemu.

Jeśli wszystko w PATHzmiennej środowiskowej jest ścieżka bezwzględna, ten błąd nie powinien wystąpić, nawet jeśli katalog szukasz i -execdiring z jest zawarty w PATH. (Sprawdziłem, czy to działa.) Jeśli uważasz, że nie masz żadnych katalogów względnych, $PATHale nadal pojawia się ten błąd, zaktualizuj swoje pytanie o szczegóły, w tym dane wyjściowe echo "$PATH".

Konkretny przykład.

Jako przykład tego, co może pójść nie tak, załóżmy:

  • Alice ma .ją, $PATHponieważ chce móc uruchamiać programy w dowolnym katalogu, w którym by się nie znajdowała cd, bez zawracania sobie głowy dodawaniem ich nazwisk ./.
  • Wróg Alicji, Ewa, dzielił się /home/eve/sharedz Alicją.
  • Alice chce statystyk (wierszy, słów, bajtów) w .c plików, które Eve jej udostępniła.

Więc Alice działa:

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

Na nieszczęście dla Alicji Eve stworzyła własny skrypt, nazwał go wc, ustawiła jako wykonywalną ( chmod +x) i umieściła go potajemnie w jednym z katalogów /home/eve/shared. Scenariusz Ewy wygląda następująco:

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

Więc kiedy zastosowania Alice findz -execdirbiec wcna plikach Ewa jest wspólne, a dojdzie do plików znajdujących się w tym samym katalogu co niestandardowego Ewy wcskryptu, Evewc tras - ze wszystkich przywilejów Alicji!

(Podstępna, Ewa sprawiła, że ​​jej wcskrypt działa jak opakowanie systemu wc, więc Alice nawet nie wie, że coś poszło nie tak, tzn. Żedo_evil zostało uruchomione. Jednak możliwe są prostsze - i bardziej wyrafinowane - warianty. )

Jak findtemu zapobiec.

findzapobiega występowaniu tego problemu bezpieczeństwa, odmawiając podjęcia -execdirdziałania, gdy $PATHzawiera katalog względny.

find oferuje dwa komunikaty diagnostyczne w zależności od konkretnej sytuacji.

  • Jeśli .jest $PATH, to (jak widzieliście) mówi:

    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)

    Prawdopodobnie ma specjalny komunikat dla .sprawy, ponieważ jest szczególnie powszechny.

  • Jeżeli względna ścieżka inna niż .--say, foo--appears w $PATHi uruchomić findz -execdir, to mówi:

    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

Lepiej nie mieć ścieżek względnych $PATH .

Ryzyko posiadania .lub innych względnych ścieżek $PATHjest szczególnie zwiększone, gdy używasz narzędzia, które automatycznie zmienia katalog, dlatego findnie pozwalasz na użycie -execdirw tej sytuacji.

Ale posiadanie względnych ścieżek, szczególnie .w twoim, $PATHjest z natury ryzykowne i tak naprawdę najlepiej go unikać. Rozważ sytuację fikcyjną w powyższym przykładzie. Załóżmy, że zamiast biegać find, Alice po prostu cds do ~eve/shared/blahi biegnie wc *.c. Jeśli blahzawiera wcskrypt Eve , do_evildziała jako Alice.

Eliah Kagan
źródło
2
Nie wiem, czy słyszałeś to wcześniej, że
byłbyś
5
@ heemayl wszyscy, którzy piszą przydatne rzeczy w sieci, są już nauczycielami :-)
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
5

Jest znacznie Szczegółowe informacje tutaj . Kolejna doskonała referencja jest tutaj . Cytat z pierwszego odniesienia:

Opcja -execdir jest bardziej nowoczesną opcją wprowadzoną w GNU find, jest próbą stworzenia bezpieczniejszej wersji -exec. Ma taki sam semantyczny jak -exec z dwoma ważnymi ulepszeniami:

Zawsze zapewnia bezwzględną ścieżkę do pliku (użycie ścieżki względnej do pliku jest naprawdę niebezpieczne w przypadku opcji -exec).

Oprócz podania ścieżki bezwzględnej sprawdza również zmienność PATH pod kątem bezpieczeństwa (jeśli kropka jest obecna w zmiennej PATH env, możesz pobrać plik wykonywalny z niewłaściwego katalogu)

Od drugiego odniesienia:

Akcja „-execdir” odmawia wykonania jakichkolwiek czynności, jeśli bieżący katalog znajduje się w zmiennej środowiskowej $ PATH. Jest to konieczne, ponieważ „-execdir” uruchamia programy w tym samym katalogu, w którym znajduje pliki - na ogół taki katalog może być zapisywany przez niezaufanych użytkowników. Z podobnych powodów „-execdir” nie pozwala na pojawienie się „{}” w nazwie polecenia do uruchomienia.

Ron
źródło
Czy możesz rozszerzyć swoją odpowiedź, dlaczego „jeśli kropka jest obecna w zmiennej PATH env, możesz pobrać plik wykonywalny z niewłaściwego katalogu” ? który zły katalog ? I dlaczego musimy to zrobić, aby było bezpieczne ? Dzięki
αғsнιη
Mam nadzieję, że drugi link w moim zaktualizowanym poście odpowie na twoje pytanie
Ron
3

Głównym problemem jest wartość zmiennej systemowej, PATHktóra zawiera w sobie foldery względne, więc ze względów bezpieczeństwa findpolecenie nie pozwala na uruchamianie plików binarnych, ponieważ potencjalnie może on uruchamiać niewłaściwe programy.


Na przykład, jeśli masz bieżący katalog w ŚCIEŻCE zgodnie z ostrzeżeniem, które otrzymujesz:

Bieżący katalog jest zawarty w zmiennej środowiskowej PATH.

a ty wykonasz polecenie:

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

na wypadek gdybyś miał w nim skrypt lokalny ( rmz flagami wykonywalnymi) rm -fr /, może usunąć wszystkie twoje pliki, ponieważ zamiast wykonywania oczekiwanego /bin/rm, wykonasz rmz bieżącego katalogu, więc prawdopodobnie nie jest to, czego chciałeś.


Na marginesie, jest to znany problem w Travis CI ( GH # 2811 ), gdy kończy się błędem:

find: ścieżka względna `./node_modules/.bin 'jest zawarta w zmiennej środowiskowej PATH, która nie jest bezpieczna w połączeniu z działaniem -execdir funkcji find. Usuń ten wpis z $ PATH

Rozwiązaniem jest więc usunięcie zmienionego wpisu ze zmiennej PATH, np

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

jak zaproponował drogus . Postęp tego błędu można śledzić na GH # 4862 .


Oto obejście wersji Bash:

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

Przykładowe użycie (przekazanie filtrowane PATHdo określonego polecenia):

env PATH=${PATH//:\.\/node_modules\/\.bin/} find . -type f
kenorb
źródło
Oto coś, sedco wydaje się usuwać wszystkie rzeczy, findktórych nie lubi: askubuntu.com/questions/621132/…
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
3

xargsi bash -c cdobejście

Ok, poddaję się:

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

sed obejście

Nieco mniej przyjemne niż poprzednie obejście:

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

Testcase:

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

W renameszczególności możesz także obejść niektóre perge regex-fu: /programming/16541582/finding-multiple-files-recursively-and-renaming-in-linux/54163971#54163971

RTFS miażdży nadzieję

Dla tych, którzy mają nadzieję, że istnieje sposób na zignorowanie opinii find, pozwólcie, że zmiażdżę to jakimś źródłem:

Z tego wynika, że ​​wydaje się, że nie ma możliwości wyłączenia sprawdzania ścieżki.

Dokładna reguła, którą sprawdza, to: niepowodzenie, jeśli PATHjest albo puste, albo nie zaczyna się od /.

Ciro Santilli
źródło