Pourquoi l'utilisation de l'action '-execdir' n'est pas sécurisée pour le répertoire qui se trouve dans le CHEMIN?

19

Pourquoi n'est-il pas sûr d'utiliser la combinaison d' -execdiraction de trouver pendant que vous -execne l' utilisez pas?

Lorsque j'exécute la commande ci-dessous, j'obtiens le message d'invite suivant:

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

Qu'est-ce qui a pu faire apparaître cette invite?

αғsнιη
la source

Réponses:

22

Vous pourriez exécuter le mauvais programme. Quelqu'un pourrait vous faire exécuter leur programme.

L' -execdiraction exécute votre commande à partir du répertoire qui contient le ou les fichiers trouvés. Lorsque $PATHcontient des chemins relatifs, tels que .ou tout ce qui ne commence pas/ , -execdirn'est pas sûr car un répertoire où se trouve un fichier (ou un autre répertoire résolu par rapport à lui) peut également contenir un exécutable du même nom que celui que vous essayez courir. Cet exécutable potentiellement non fiable serait alors exécuté à la place.

Cela pourrait être délibérément exploité par un autre utilisateur pour vous obliger à exécuter son programme, ce qui pourrait nuire ou porter atteinte à la sécurité des données, au lieu du programme que vous essayez d'exécuter. Ou, moins souvent, cela peut simplement entraîner l'exécution du mauvais programme par inadvertance, même sans que quiconque essaie de résoudre le problème.

Si tout dans votre PATHvariable d'environnement est un chemin absolu, cette erreur ne devrait pas se produire, même si le répertoire que vous êtes à la recherche et -execdiring de est contenue dans PATH. (J'ai vérifié que cela fonctionne.) Si vous pensez ne pas avoir de répertoires relatifs $PATHmais que vous obtenez toujours cette erreur, veuillez mettre à jour votre question avec les détails, y compris la sortie de echo "$PATH".

Un exemple concret.

À titre d'exemple de ce qui pourrait mal tourner, supposons:

  • Alice a .en elle $PATHparce qu'elle veut être en mesure d'exécuter des programmes dans n'importe quel répertoire cd, sans prendre la peine d'ajouter leurs noms ./.
  • La frenemy d'Alice Eve a partagé /home/eve/sharedavec Alice.
  • Alice veut des statistiques (lignes, mots, octets) sur les .cfichiers qu'Eve a partagés avec elle.

Alors Alice court:

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

Malheureusement pour Alice, Eve a créé son propre script, l'a nommé wc, l'a défini exécutable ( chmod +x) et l'a placé clandestinement dans l'un des répertoires sous /home/eve/shared. Le script d'Eve ressemble à ceci:

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

Donc, quand Alice utilise findavec -execdirpour s'exécuter wcsur les fichiers partagés par Eve, et qu'elle accède aux fichiers dans le même répertoire que le wcscript personnalisé d' Eve, Eve wcs'exécute - avec tous les privilèges d'Alice!

(Étant astucieuse, Eve a fait en sorte que son wcscript agisse comme un wrapper pour le système wc, donc Alice ne saura même pas que quelque chose s'est mal passé, c'est-à-dire qu'elle a do_evilété exécutée. Cependant, des variations plus simples - et aussi plus sophistiquées - sont possibles. )

Comment findempêche cela.

findempêche ce problème de sécurité de se produire en refusant d'effectuer l' -execdiraction lorsqu'il $PATHcontient un répertoire relatif.

find propose deux messages de diagnostic en fonction de la situation spécifique.

  • Si .est $PATHdedans, alors (comme vous l'avez vu), il dit:

    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)

    Il a probablement un message spécial pour le .cas car il est particulièrement courant.

  • Si un chemin relatif autre que .--say, - fooapparaît $PATHet que vous exécutez findavec -execdir, il indique:

    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

Il vaut mieux ne pas avoir de chemin relatif $PATHdu tout.

Le risque d'avoir .ou d'autres chemins d'accès relatifs $PATHest particulièrement accru lors de l'utilisation d'un utilitaire qui modifie automatiquement le répertoire, c'est pourquoi findvous ne pourrez pas l'utiliser -execdirdans cette situation.

Mais avoir des chemins relatifs, en particulier ., dans votre $PATHest intrinsèquement risqué et il vaut mieux éviter de toute façon. Considérez la situation fictive dans l'exemple ci-dessus. Supposons au lieu de courir find, Alice simplement cds à ~eve/shared/blahet fonctionne wc *.c. Si blahcontient le wcscript d'Eve , do_evils'exécute en tant qu'Alice.

Eliah Kagan
la source
2
Je ne sais pas si vous avez entendu cela auparavant que vous feriez un très bon professeur :)
heemayl
5
@heemayl tous ceux qui écrivent des trucs utiles sur le net, sont déjà des enseignants :-)
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
5

Il y a une information très détaillée ici . Une autre excellente référence est ici . Pour citer la première référence:

L'option -execdir est une option plus moderne introduite dans GNU find est une tentative de créer une version plus sûre de -exec. Il a la même sémantique que -exec avec deux améliorations importantes:

Il fournit toujours un chemin absolu vers le fichier (utiliser un chemin relatif vers un fichier est vraiment dangereux dans le cas de -exec).

En plus de fournir un chemin absolu, il vérifie également la sécurité de la variable PATH (si un point est présent dans la variable env PATH, vous pouvez récupérer l'exécutable dans le mauvais répertoire)

De la deuxième référence:

L'action '-execdir' refuse de faire quoi que ce soit si le répertoire courant est inclus dans la variable d'environnement $ PATH. Ceci est nécessaire car '-execdir' exécute les programmes dans le même répertoire dans lequel il trouve les fichiers - en général, un tel répertoire peut être accessible en écriture par des utilisateurs non fiables. Pour des raisons similaires, '-execdir' ne permet pas à '{}' d'apparaître dans le nom de la commande à exécuter.

Ron
la source
Pouvez-vous s'il vous plaît étendre votre réponse pourquoi "si le point est présent dans la variable env PATH, vous pouvez récupérer l'exécutable dans le mauvais répertoire" ? quel mauvais répertoire ? Et pourquoi devons-nous le faire pour le sécuriser ? Merci
αғsнιη
J'espère que le deuxième lien dans mon article mis à jour répondra à votre question
Ron
3

Le problème principal est avec la valeur de la variable système PATHqui contient des dossiers relatifs, donc pour des raisons de sécurité, la findcommande ne vous permettra pas d'exécuter des binaires, car elle peut potentiellement exécuter de mauvais programmes.


Ainsi, par exemple, si vous avez votre répertoire actuel dans votre PATH selon l'avertissement que vous obtenez:

Le répertoire actuel est inclus dans la variable d'environnement PATH.

et vous exécuterez votre commande:

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

au cas où vous auriez un script local ( rmavec des drapeaux exécutables) contenant rm -fr /, il peut supprimer tous vos fichiers, car au lieu de l'exécuter /bin/rm, vous l'exécuterez à rmpartir du répertoire actuel, donc ce n'est probablement pas ce que vous vouliez.


En remarque, il s'agit d'un problème connu dans Travis CI ( GH # 2811 ) lorsqu'il échoue avec l'erreur:

find: Le chemin relatif `./node_modules/.bin 'est inclus dans la variable d'environnement PATH, qui n'est pas sécurisé en combinaison avec l'action -execdir de find. Veuillez supprimer cette entrée de $ PATH

La solution consiste donc à supprimer l'entrée affectée de la variable PATH, par exemple

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

tel que proposé par drogus . La progression de ce bug peut être suivie sur GH # 4862 .


Voici la solution de contournement de la version Bash:

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

Exemple d'utilisation (passage filtré PATHà une commande spécifique):

env PATH=${PATH//:\.\/node_modules\/\.bin/} find . -type f
kenorb
la source
Voici un sedqui semble supprimer tout ce qui findn'aime pas: askubuntu.com/questions/621132/…
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
3

xargset bash -c cdsolution de contournement

OK, j'abandonne:

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

sed solution de contournement

Un peu moins sympa que la solution de contournement précédente:

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

Un cas d'essai:

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

Pour plus renameprécisément, vous pouvez également contourner certains regex-fu Perl: /programming/16541582/finding-multiple-files-recursively-and-renaming-in-linux/54163971#54163971

RTFS espère écraser

Pour ceux qui espèrent qu'il existe un moyen d'ignorer findl'opinionnisme, laissez-moi l'écraser avec une source:

De cela, nous voyons qu'il ne semble pas y avoir de moyen de désactiver la vérification du chemin.

La règle exacte qu'il vérifie est: échouer si le PATHest vide ou ne commence pas par /.

Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
la source