Do manual do findutils:
Por exemplo, construções como esses dois comandos
# risky find -exec sh -c "something {}" \; find -execdir sh -c "something {}" \;são muito perigosos. A razão para isso é que o '{}' é expandido para um nome de arquivo que pode conter ponto-e-vírgula ou outros caracteres especiais para o shell. Se, por exemplo, alguém criar o arquivo
/tmp/foo; rm -rf $HOME, os dois comandos acima poderão excluir o diretório inicial de alguém.Portanto, por esse motivo, não execute nenhum comando que transmita dados não confiáveis (como nomes de arquivos) para comandos que interpretam argumentos como comandos a serem interpretados posteriormente (por exemplo, 'sh').
No caso do shell, há uma solução inteligente para esse problema:
# safer find -exec sh -c 'something "$@"' sh {} \; find -execdir sh -c 'something "$@"' sh {} \;Não é garantido que essa abordagem evite todos os problemas, mas é muito mais segura do que substituir dados da escolha de um invasor pelo texto de um comando do shell.
- A causa do problema é
find -exec sh -c "something {}" \;que a substituição de{}é sem aspas e, portanto, não é tratada como uma única sequência? Na solução
find -exec sh -c 'something "$@"' sh {} \;,primeiro
{}é substituído, mas como{}não está entre aspas,"$@"também não tem o mesmo problema que o comando original? Por exemplo,"$@"será expandido para"/tmp/foo;","rm","-rf"e"$HOME"?por que
{}não é escapado ou citado?
- Você poderia dar outros exemplos (ainda com
sh -c, ou sem, se aplicável; com ou sem ofindque pode não ser necessário) onde o mesmo tipo de problema e solução se aplica e quais são exemplos mínimos para que possamos focar no problema e na solução com pouca distração possível? Veja Maneiras de fornecer argumentos para um comando executado por `bash -c`
Obrigado.