È sempre sicuro usare `eval echo`?


20

L'uso evalè spesso scoraggiato perché consente l'esecuzione di codice arbitrario. Tuttavia, se usiamo eval echo, allora sembra che il resto della stringa diventerà argomento, echoquindi dovrebbe essere sicuro. Sono corretto su questo?


1
non sempre al sicuro potresti avvolgere una bomba a forcella o una brutta rm -fR *
μολὼν.λαβέ

Forse questo è solo un esperimento mentale, ma se in realtà stavi pensando di farlo per passare più argomenti come -n, puoi semplicemente farlo con una variabile non quotata come echo $argumentso se $argumentsè un array echo "${arguments[@]}". Usando eval echoè inutile, anche se fosse al sicuro.
JoL

Risposte:


40

controesempio:

DANGEROUS=">foo"
eval echo $DANGEROUS

Gli argomenti arbitrari echoavrebbero potuto fare qualcosa di più nefasto della creazione di un file chiamato "pippo".


6
Inoltre DANGEROUS="hello;ls":, per comandi arbitrari al posto di ls.
Kusalananda

2
Inoltre: DANGEROUS='$(ls)'(potrebbe essere necessaria una maggiore fuga).
wizzwizz4,

Funzionerebbe eval echo '"'"$DANGEROUS"'"'? Sembra su goo.gl/L2pPQP
Ismael Miguel il

@IsmaelMiguel Questo non funziona per gli esempi di wizzwizz, Cyker o sorontar, o per qualsiasi cosa con virgolette doppie nella stringa (ad es DANGEROUS='">foo"'.).
Gordon Davisson,

Darn. Pensavo di aver trovato qualcosa che mi aiutasse un po '
Ismael Miguel, il

26

@Celada ha fornito un'ottima risposta. Per dimostrare che evalè davvero malvagio, ecco qualcosa di più nefasto che creare un file chiamato "pippo" :

DANGEROUS='$(rm foo)'
eval echo "$DANGEROUS"

E ovviamente può esserci qualcosa di più nefasto di qualcosa di più nefasto che creare un file chiamato "pippo" .


8
+1 per dimostrare che citare la variabile come "$THIS"invece di averla come $THISnon aiuta nemmeno!
Celada,

L'invio di una coppia di virgolette adizionali sembra aiutare. Qualcosa del genere eval echo '"'"$DANGEROUS"'"'. Provalo su goo.gl/L2pPQP
Ismael Miguel il

In realtà, il tuo esempio non è più nefasto di >foo, perché "creare un file chiamato" pippo "non è necessariamente tutto ciò che >foofa. L'unica vera differenza che il tuo esempio ha è che non lascia indietro un file vuoto. I contenuti sono ancora spariti.
flarn2006,

12

No, è non è sempre sicuro. Un eval potrebbe eseguire qualsiasi comando.

Un comando sicuro, come questo (la data non viene eseguita in quanto racchiusa tra virgolette singole):

$ echo '$(date)'
$(date)

Diventa pericoloso se usato con eval:

$ eval echo '$(date)'
Sat Dec 24 22:55:55 UTC 2016

Naturalmente, la data potrebbe essere qualsiasi comando.

Un modo per migliorare questo è di citare ulteriormente gli argomenti da valutare:

$ eval echo '\$(date)'
$(date)

Ma di solito è difficile citare correttamente due volte un'espressione.

E diventa impossibile controllare la quotazione corretta se l'espressione potrebbe essere impostata da un utente malintenzionato esterno, come:

$ var='$(date);echo Hello!'
$ eval echo "$var"
Sat Dec 24 23:01:48 UTC 2016
Hello!

1

Mentre è vero che evaldeve sempre essere affrontato con cautela, la eval echocostruzione non è sempre inutile e può essere utilizzata in modo sicuro. Di recente ne avevo bisogno per valutare più espansioni di parentesi graffe nell'ordine in cui ne avevo bisogno.

bash fa più espansioni di parentesi graffe da sinistra a destra, quindi

xargs -I_ cat _/{11..15}/{8..5}.jpg

si espande a

xargs -I_ cat _/11/8.jpg _/11/7.jpg _/11/6.jpg _/11/5.jpg _/12/8.jpg _/12/7.jpg _/12/6.jpg _/12/5.jpg _/13/8.jpg _/13/7.jpg _/13/6.jpg _/13/5.jpg _/14/8.jpg _/14/7.jpg _/14/6.jpg _/14/5.jpg _/15/8.jpg _/15/7.jpg _/15/6.jpg _/15/5.jpg

ma avevo bisogno che la seconda espansione della parentesi graffa venisse eseguita per prima, cedendo

xargs -I_ cat _/11/8.jpg _/12/8.jpg _/13/8.jpg _/14/8.jpg _/15/8.jpg _/11/7.jpg _/12/7.jpg _/13/7.jpg _/14/7.jpg _/15/7.jpg _/11/6.jpg _/12/6.jpg _/13/6.jpg _/14/6.jpg _/15/6.jpg _/11/5.jpg _/12/5.jpg _/13/5.jpg _/14/5.jpg _/15/5.jpg

Il meglio che ho potuto inventarmi è stato

xargs -I_ cat $(eval echo _/'{11..15}'/{8..5}.jpg)

Questo funziona perché le virgolette singole proteggono il primo set di parentesi graffe dall'espansione durante l'analisi della evalriga di comando, lasciandole espandere dalla subshell invocata da eval.

Potrebbe esserci qualche astuzia che prevede espansioni di parentesi graffe annidate che consente che ciò avvenga in un solo passaggio, ma se c'è sono troppo vecchio e stupido per vederlo. Ci sono anche conchiglie diverse da quelle bashche consentono modi più ordinati per raggiungere questo tipo di cose. Ma in ogni caso, questo uso di evalè sicuro perché i suoi argomenti sono tutte stringhe fisse che non contengono espansioni di parametri.


Non è necessario l'eco e la sostituzione del comando qui (che ha anche una dipendenza da $ IFS). Si potrebbe fareeval xargs -I_ cat _/'{11..15}'/{8..5}.jpg
Stéphane Chazelas il

Funziona anche questo, ma rende il processo subshell generato da eval stick fino al termine del processo xargs; la versione eval echo fa sparire quella subshell prima ancora che xargs venga avviato. Questo è probabilmente importante solo per gli altri che sono anali come me su ciò che appare nelle viste ad albero htop e imposta i registri -x però :-)
flabdablet
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.