Perché l'uso dell'azione '-execdir' non è sicuro per la directory che si trova nel PERCORSO?


19

Perché non è sicuro utilizzare la combinazione di -execdirazione di find mentre -execnon lo è?

Quando eseguo il comando seguente ricevo il seguente messaggio di richiesta:

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

Cosa può aver causato la visualizzazione di questo messaggio?

Risposte:


22

Potresti eseguire il programma sbagliato. Qualcuno potrebbe farti eseguire il loro programma.

L' -execdirazione esegue il comando dalla directory che contiene i file trovati. Quando $PATHcontiene percorsi relativi, come .o tutto ciò che non inizia/ , -execdirè insicuro perché una directory in cui viene trovato un file (o un'altra directory risolta rispetto ad esso) potrebbe contenere anche un eseguibile con lo stesso nome di quello che stai provando correre. L'eseguibile potenzialmente non attendibile verrebbe invece eseguito.

Questo potrebbe essere deliberatamente sfruttato da un altro utente per farti eseguire il suo programma, il che potrebbe causare danni o violare la sicurezza dei dati, invece del programma che stai tentando di eseguire. O, meno spesso, potrebbe semplicemente comportare l'esecuzione involontaria del programma sbagliato, anche senza che nessuno provi a far accadere il problema.

Se tutto nella PATHvariabile di ambiente è un percorso assoluto, questo errore non dovrebbe verificarsi, anche se la directory da cui stai cercando e -execdirin cui è contenuta è contenuta PATH. (Ho verificato che funzioni.) Se ritieni di non avere alcuna directory relativa $PATHma stai ancora riscontrando questo errore, aggiorna la tua domanda con i dettagli, incluso l'output di echo "$PATH".

Un esempio concreto.

Come esempio di cosa potrebbe andare storto, supponiamo:

  • Alice ha .in lei $PATHperché vuole essere in grado di eseguire programmi in qualunque directory si trovi cd, senza preoccuparsi di anteporre i loro nomi ./.
  • La frenetica Eva /home/eve/shareddi Alice ha condiviso con Alice.
  • Alice vuole statistiche (righe, parole, byte) sui .cfile che Eva ha condiviso con lei.

Quindi Alice corre:

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

Sfortunatamente per Alice, Eva ha creato la sua sceneggiatura, l'ha nominata wc, l'ha impostata come eseguibile ( chmod +x) e l'ha collocata clandestinamente in una delle directory sotto /home/eve/shared. La sceneggiatura di Eva appare così:

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

Quindi, quando Alice usa findcon -execdirper essere eseguita wcsui file che Eva ha condiviso e arriva ai file nella stessa directory dello wcscript personalizzato di Eva, Eva wccorre, con tutti i privilegi di Alice!

(Essendo furbo, Eva ha fatto in modo che la sua wcsceneggiatura agisca come un involucro per il sistema wc, quindi Alice non saprà nemmeno che qualcosa è andato storto, cioè che è do_evilstato eseguito. Tuttavia, sono possibili variazioni più semplici - e anche più sofisticate. )

Come findimpedisce questo.

findimpedisce che si verifichi questo problema di sicurezza rifiutando di eseguire l' -execdirazione quando $PATHcontiene una directory relativa.

find offre due messaggi diagnostici a seconda della situazione specifica.

  • Se .è dentro $PATH, allora (come hai visto) dice:

    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)

    Probabilmente ha un messaggio speciale per il .caso in quanto è particolarmente comune.

  • Se un percorso relativo diverso .--say, foo--appears in $PATHe si esegue findcon -execdir, si dice:

    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

È meglio non avere affatto percorsi relativi $PATH.

Il rischio di avere .o altri percorsi relativi $PATHè particolarmente accentuato quando si utilizza un'utilità che modifica automaticamente la directory, motivo findper cui non è possibile utilizzarlo -execdirin questa situazione.

Ma avere percorsi relativi, in particolare ., nel tuo $PATHè intrinsecamente rischioso ed è comunque davvero meglio evitarlo. Considera la situazione immaginaria nell'esempio sopra. Supponiamo che invece di correre find, Alice semplicemente cdS per ~eve/shared/blahe corre wc *.c. Se blahcontiene la wcsceneggiatura di Eva , do_evilfunziona come Alice.


2
Non so se l'hai già sentito prima che diventeresti un ottimo insegnante :)
heemayl

5
@heemayl tutti coloro che scrivono cose utili in rete, sono già insegnanti :-)
Ciro Santilli 13 改造 中心 法轮功 六四 事件

5

Ci sono informazioni molto dettagliate qui . Un altro riferimento eccellente è qui . Per citare dal primo riferimento:

L'opzione -execdir è un'opzione più moderna introdotta in GNU find è un tentativo di creare una versione più sicura di -exec. Ha lo stesso semantico di -exec con due importanti miglioramenti:

Fornisce sempre il percorso assoluto del file (l'utilizzo del percorso relativo di un file è davvero pericoloso in caso di -exec).

Oltre a fornire il percorso assoluto, controlla anche la variabile PATH per sicurezza (se il punto è presente nella variabile env PATH, è possibile prelevare l'eseguibile dalla directory sbagliata)

Dal secondo riferimento:

L'azione '-execdir' rifiuta di fare qualsiasi cosa se la directory corrente è inclusa nella variabile d'ambiente $ PATH. Ciò è necessario perché '-execdir' esegue i programmi nella stessa directory in cui trova i file - in generale, tale directory potrebbe essere scrivibile da utenti non attendibili. Per motivi simili, '-execdir' non consente di visualizzare '{}' nel nome del comando da eseguire.


Puoi estendere la tua risposta perché "se il punto è presente nella variabile ENV PATH, puoi prelevare l'eseguibile dalla directory sbagliata" ? quale directory sbagliata ? E perché dobbiamo farlo per renderlo sicuro ? Grazie
αғsнιη

Spero che il secondo link nel mio post aggiornato risponderà alla tua domanda
Ron,

3

Il problema principale è con il valore della variabile di sistema PATHche contiene cartelle relative al suo interno, quindi per motivi di sicurezza il findcomando non ti permetterà di eseguire binari, perché potenzialmente può eseguire programmi sbagliati.


Quindi, ad esempio, se hai la tua directory corrente nel PERCORSO come da avviso che ottieni:

La directory corrente è inclusa nella variabile d'ambiente PATH.

e eseguirai il tuo comando:

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

nel caso tu abbia uno script locale ( rmcon flag eseguibili) contenente rm -fr /al suo interno, puoi rimuovere tutti i tuoi file, perché invece di eseguire previsto /bin/rm, eseguirai rmdalla directory corrente, quindi probabilmente non è quello che volevi.


Come nota a margine, questo è un problema noto in Travis CI ( GH # 2811 ) quando fallisce con l'errore:

find: il percorso relativo `./node_modules/.bin 'è incluso nella variabile d'ambiente PATH, che non è sicura in combinazione con l'azione -execdir di find. Rimuovi quella voce da $ PATH

Quindi la soluzione è rimuovere la voce interessata dalla variabile PATH, ad es

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

come proposto da drogus . L'avanzamento di questo errore può essere seguito su GH # 4862 .


Ecco la soluzione alternativa alla versione di Bash:

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

Esempio di utilizzo (passaggio filtrato PATHa comando specifico):

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

Eccone uno sedche sembra rimuovere tutto ciò findche non piace: askubuntu.com/questions/621132/…
Ciro Santilli 13 改造 中心 法轮功 六四 事件

3

xargse bash -c cdsoluzione alternativa

Ok, ci rinuncio:

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

sed soluzione

Un po 'meno bello della soluzione precedente:

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

Una prova:

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

In renameparticolare, puoi anche aggirare un po 'di Perl regex-fu: /programming/16541582/finding-multiple-files-recursively-and-renaming-in-linux/54163971#54163971

La speranza di RTFS è schiacciante

Per coloro che hanno speranze che esista un modo per ignorare findl'opinione pubblica, permettetemi di schiacciarlo con una fonte:

Da ciò vediamo che non sembra esserci alcun modo per disattivare il controllo del percorso.

La regola esatta che controlla è: fallire se PATHè vuota o non inizia /.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.