É sempre seguro usar 'eval echo'?

20

O uso de eval costuma ser desencorajado porque permite a execução de código arbitrário. No entanto, se usarmos eval echo , então parece que o resto da string se tornará argumentos de echo , então deve ser seguro. Estou certo sobre isso?

    
por Cyker 24.12.2016 / 20:28

4 respostas

40

Contra-exemplo:

DANGEROUS=">foo"
eval echo $DANGEROUS

Os argumentos arbitrários para echo poderiam ter feito algo mais nefasto do que criar um arquivo chamado "foo".

    
por 24.12.2016 / 20:35
26

@Celada forneceu uma excelente resposta. Para demonstrar eval é realmente mal, aqui está algo mais nefasto do que criar um arquivo chamado "foo" :

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

E é claro que pode haver algo mais nefasto do que algo mais nefasto do que criar um arquivo chamado "foo" .

    
por 24.12.2016 / 23:19
12

Não, é não sempre seguro. Um eval poderia executar qualquer comando.

Um comando seguro, como este (a data não é executada como está entre aspas simples):

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

Torna-se perigoso se usado com eval:

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

É claro que data pode ser qualquer comando .

Uma maneira de melhorar isso é citar adicionalmente os argumentos para eval:

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

Mas geralmente é difícil citar corretamente duas vezes uma expressão.

E torna-se impossível controlar a citação correta se a expressão puder ser definida por um invasor externo, como:

$ var='$(date);echo Hello!'
$ eval echo "$var"
Sat Dec 24 23:01:48 UTC 2016
Hello!
    
por 25.12.2016 / 00:02
1

Embora seja verdade que eval sempre precisa ser abordado com cuidado, a construção eval echo nem sempre é inútil e pode ser usada com segurança. Recentemente, precisei dele para obter várias expansões de chaves avaliadas na ordem que eu precisava delas.

bash faz múltiplas expansões de chaves da esquerda para a direita, então

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

expande para

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

mas eu precisava da segunda expansão de chave primeiro, produzindo

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

O melhor que eu pude fazer foi

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

Isso funciona porque as aspas simples protegem o primeiro conjunto de chaves da expansão durante a análise da linha de comando eval , deixando-as para serem expandidas pelo subshell chamado por eval .

Pode haver algum esquema astucioso envolvendo expansões de chaves aninhadas que permitem que isso aconteça em uma etapa, mas se houver, sou muito velho e estúpido para vê-lo. Há também outros shells que não bash que permitem maneiras mais fáceis de alcançar esse tipo de coisa. Mas em qualquer caso, esse uso de eval é seguro porque seus argumentos são todos sequências fixas que não contêm expansões de parâmetros.

    
por 05.01.2018 / 10:28

Tags