Warum ist die Verwendung der Aktion '-execdir' für Verzeichnisse im Pfad unsicher?


19

Warum ist es unsicher, die Kombination -execdiraus Suchen und -execNicht- Suchen zu verwenden ?

Wenn ich den folgenden Befehl ausführe, wird die folgende Eingabeaufforderung angezeigt:

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

Was kann dazu führen, dass diese Eingabeaufforderung angezeigt wird?

Antworten:


22

Sie könnten das falsche Programm ausführen. Jemand könnte Sie dazu bringen, ihr Programm auszuführen.

Die -execdirAktion führt Ihren Befehl aus dem Verzeichnis aus, das die gefundenen Dateien enthält. Wenn $PATHrelative Pfade enthalten sind, wie z. B. .oder alles, was nicht damit beginnt/ , -execdirist dies unsicher, da ein Verzeichnis, in dem sich eine Datei befindet (oder ein anderes Verzeichnis, das relativ dazu aufgelöst wurde), möglicherweise auch eine ausführbare Datei mit demselben Namen enthält wie die, die Sie versuchen zu rennen. Diese möglicherweise nicht vertrauenswürdige ausführbare Datei würde dann stattdessen ausgeführt.

Dies könnte absichtlich von einem anderen Benutzer ausgenutzt werden, um zu bewirken, dass Sie dessen Programm ausführen, was zu einem Schaden oder einer Verletzung der Datensicherheit führen kann, anstatt des Programms, das Sie ausführen möchten. Oder, seltener, es kann einfach dazu führen, dass versehentlich das falsche Programm ausgeführt wird, auch ohne dass jemand versucht, das Problem zu lösen.

Wenn alles in Ihrer PATHUmgebungsvariable ein absoluter Pfad ist, sollte dieser Fehler nicht auftreten, selbst wenn das Verzeichnis Sie suchen und -execdiring aus ist in enthalten PATH. (Ich habe überprüft, ob dies funktioniert.) Wenn Sie der Meinung sind, dass Sie keine relativen Verzeichnisse haben $PATH, diese Fehlermeldung jedoch weiterhin erhalten, aktualisieren Sie Ihre Frage mit Details, einschließlich der Ausgabe von echo "$PATH".

Ein konkretes Beispiel.

Nehmen wir als Beispiel an, was schief gehen könnte:

  • Alice hat es .in sich, $PATHweil sie Programme in jedem Verzeichnis ausführen möchte, in dem sie sich gerade befindet cd, ohne sich die Mühe zu machen, ihren Namen voran zu stellen ./.
  • Alice's frenemy Eve hat /home/eve/sharedmit Alice geteilt.
  • Alice möchte Statistiken (Zeilen, Wörter, Bytes) über die .cDateien, die Eve mit ihr geteilt hat.

Also läuft Alice:

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

Unglücklicherweise für Alice hat Eve ihr eigenes Skript erstellt, benannt wc, ausführbar gemacht ( chmod +x) und es heimlich in eines der Verzeichnisse darunter gestellt /home/eve/shared. Evas Skript sieht folgendermaßen aus:

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

Also , wenn Alice Anwendungen findmit -execdirlaufen wcauf die Dateien Eve geteilt hat, und es wird auf Dateien im selben Verzeichnis wie Eves benutzerdefinierten wcSkript, Evas wcläuft - mit allen Alices Privilegien!

(Eve hat ihr wcSkript als Wrapper für das System eingerichtet wc, sodass Alice nicht einmal weiß, dass etwas schiefgelaufen ist, dh dass do_eviles ausgeführt wurde. Es sind jedoch einfachere - und auch komplexere - Variationen möglich. )

Wie findverhindert man das?

findVerhindert das Auftreten dieses Sicherheitsproblems, indem die Ausführung der -execdirAktion verweigert wird, wenn $PATHein relatives Verzeichnis enthalten ist.

find bietet je nach Situation zwei Diagnosemeldungen an.

  • Wenn .ist in $PATH, dann (wie Sie gesehen haben) heißt es:

    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)

    Es hat wahrscheinlich eine besondere Botschaft für den .Fall, wie es besonders häufig ist.

  • Wenn ein relativer Pfad anders als .--say, foo--appears in $PATHund Sie laufen findmit -execdir, heißt es:

    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

Es ist besser, überhaupt keine relativen Pfade zu haben $PATH.

Das Risiko von .Pfaden oder anderen relativen Pfaden $PATHist besonders hoch, wenn Sie ein Dienstprogramm verwenden, das das Verzeichnis automatisch ändert, weshalb findSie dies -execdirin dieser Situation nicht zulassen .

Aber mit relativen Pfaden, vor allem .in Ihrer $PATHNatur aus riskant ist und wirklich sowieso am besten vermieden werden. Betrachten Sie die fiktive Situation im obigen Beispiel. Angenommen, anstatt zu rennen find, rennt Alice einfach cdzu ~eve/shared/blahund davon wc *.c. Wenn blahEvas wcSkript enthalten ist, wird es do_evilals Alice ausgeführt.


2
Ich weiß nicht, ob Sie das schon einmal gehört haben, dass Sie einen sehr guten Lehrer
abgeben

5
@heemayl alle die nützliche sachen ins netz schreiben, sind schon
lehrer

5

Es gibt eine viel detaillierten Informationen hier . Eine weitere hervorragende Referenz ist hier . Um aus der ersten Referenz zu zitieren:

Die Option -execdir ist eine modernere Option, die in GNU eingeführt wurde. Find ist ein Versuch, eine sicherere Version von -exec zu erstellen. Es hat die gleiche Semantik wie -exec mit zwei wichtigen Verbesserungen:

Es gibt immer den absoluten Pfad zur Datei an (die Verwendung des relativen Pfads zu einer Datei ist im Fall von -exec wirklich gefährlich).

Zusätzlich zur Angabe des absoluten Pfads wird auch die PATH-Variable auf Sicherheit überprüft (wenn in der PATH-Umgebungsvariablen ein Punkt vorhanden ist, können Sie die ausführbare Datei aus dem falschen Verzeichnis abrufen).

Aus der zweiten Referenz:

Die Aktion '-execdir' weigert sich, etwas zu tun, wenn das aktuelle Verzeichnis in der Umgebungsvariablen $ PATH enthalten ist. Dies ist erforderlich, da '-execdir' Programme in demselben Verzeichnis ausführt, in dem sie Dateien finden. Im Allgemeinen kann ein solches Verzeichnis von nicht vertrauenswürdigen Benutzern beschrieben werden. Aus ähnlichen Gründen lässt '-execdir' nicht zu, dass '{}' im Namen des auszuführenden Befehls erscheint.


Können Sie bitte Ihre Antwort erweitern, warum "wenn Punkt in der PATH-Umgebungsvariablen vorhanden ist, können Sie ausführbare Dateien aus dem falschen Verzeichnis abholen" ? Welches falsche Verzeichnis ? Und warum müssen wir das tun, um es sicher zu machen ? Thanks
α 8sнιη

Ich hoffe, der zweite Link in meinem aktualisierten Beitrag beantwortet Ihre Frage
Ron

3

Das Hauptproblem ist der Wert der Systemvariablen, PATHdie relative Ordner enthält. Aus Sicherheitsgründen findkönnen Sie mit dem Befehl keine Binärdateien ausführen, da möglicherweise falsche Programme ausgeführt werden.


Wenn Sie zum Beispiel Ihr aktuelles Verzeichnis gemäß der Warnung in Ihrem PATH haben, die Sie erhalten:

Das aktuelle Verzeichnis ist in der Umgebungsvariablen PATH enthalten.

und du wirst deinen Befehl ausführen:

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

Falls Sie ein lokales Skript ( rmmit ausführbaren Flags) haben, rm -fr /in dem es enthalten ist, können alle Ihre Dateien entfernt werden, da Sie statt der erwarteten /bin/rmAusführung rmaus dem aktuellen Verzeichnis ausführen , sodass dies wahrscheinlich nicht das ist, was Sie wollten.


Als Randnotiz ist dieses Problem in Travis CI ( GH # 2811 ) bekannt, wenn es mit dem Fehler fehlschlägt:

find: Der relative Pfad `./node_modules/.bin 'ist in der Umgebungsvariablen PATH enthalten, die in Kombination mit der Aktion -execdir von find unsicher ist. Bitte entfernen Sie diesen Eintrag aus $ PATH

Die Lösung besteht also darin, den betroffenen Eintrag aus der PATH-Variablen zu entfernen, z

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

wie von drogus vorgeschlagen . Der Fortschritt dieses Fehlers kann unter GH # 4862 verfolgt werden .


Hier ist die Problemumgehung für die Bash-Version:

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

Beispielverwendung (Übergabe gefiltert PATHan bestimmten Befehl):

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

Hier ist ein sed, der anscheinend alle Dinge entfernt, finddie nicht gefallen: askubuntu.com/questions/621132/…
Ciro Santilli Am

3

xargsund bash -c cdProblemumgehung

OK ich gebe auf:

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

sed Problemumgehung

Ein bisschen weniger schön als die vorherige Problemumgehung:

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

Ein Testfall:

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

Für renamespeziell, können Sie auch mit einigen Perl regex-fu umgehen: /programming/16541582/finding-multiple-files-recursively-and-renaming-in-linux/54163971#54163971

RTFS-Hoffnung zermalmt

Für diejenigen, die hoffen, dass es einen Weg gibt, die findMeinungsäußerung zu ignorieren , lassen Sie mich das mit einer Quelle zerschlagen:

Daraus ergibt sich, dass es anscheinend keine Möglichkeit gibt, die Pfadprüfung auszuschalten.

Die genaue Regel, die überprüft wird, lautet: Fehler, wenn die PATHentweder leer ist oder nicht mit beginnt /.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.