Leia e confirme o script do shell antes de passar de curl para sh (curl -s [url] | sh)

11

Sempre que preciso executar um script de shell da Web curl -s [url] | sh, abro primeiro urlno meu navegador da Web para garantir que o script não seja malicioso e seja seguro para executar.

Lembro-me de ver um truque de linha de comando que tornou possível ler o script na linha de comando e confirmar a execução depois de ler o script. Se bem me lembro, parecia algo curl -s [url] | something...here | she não exigia nenhuma instalação de software.

Alguém conhece esse truque?

Olivier Lalonde
fonte

Respostas:

5

Existe um utilitário moreutilschamado vipeque mostra stdin em um editor, no qual você pode revisar e modificar o arquivo antes que ele seja passado para o stdout.

Se você não deseja instalar moreutils, você pode realizar algo semelhante como este:

file=$(mktemp); curl -s "$url" > $file; $EDITOR $file; sh $file; rm $file

mktempestá dentro coreutilse provavelmente já está instalado no seu sistema.

Shawn J. Goff
fonte
2

Não consigo pensar em um único utilitário que faria o que você descreve, mas é fácil o suficiente para torná-lo um snippet de shell.

script=$(curl -s "$url")
printf "%s\nDo you want to run this script? [yN]" "$script"
read line
case $line in
  [Yy]|[Yy][Ee][Ss]) sh -c "$script";;
esac

Isso pressupõe que o script é um arquivo de texto. Bytes nulos não são suportados: dependendo do shell, eles podem ser removidos ou podem causar uma linha ou todo o arquivo ser truncado. Além disso, todas as novas linhas no final do arquivo são removidas (a construção heredoc adiciona uma volta). Normalmente, isso não é um problema para um script, mas pode ser, por exemplo, se o script terminar com um arquivo no formato binário que ele extrai. Essa não é uma maneira muito confiável de distribuir um arquivo, pois existe um risco significativo de que um script binário seja codificado incorretamente em algum momento. No entanto, você pode lidar com isso escrevendo o script em um arquivo temporário.

script_file=$(mktemp)
curl -s "$url" | tee "$script_file"
printf "Do you want to run this script? [yN]"
read line
case $line in
  [Yy]|[Yy][Ee][Ss]) sh "$script_file";;
esac
rm "$script_file"
Gilles 'SO- parar de ser mau'
fonte
$()deve ser citado na primeira linha. Além disso, isso removeria caracteres NUL na entrada, o que pode ser fatal (por exemplo, no caso de um script de extração automática).
L0b0
1
@ l0b0 Você não precisa citar uma tarefa, embora seja um estilo sem dúvida bom . Os bytes nulos são realmente perdidos, assim como as novas linhas finais; se você incluir um arquivo morto em um script de shell, recomendo usar uma codificação de texto como base64.
Gilles 'SO- stop be evil'
Todos os pontos válidos, como de costume. 1
l0b0 23/01
@ l0b0 Pensando bem, embora seja um pouco propenso a riscos, este é um caso de uso válido. Eu atualizei minha resposta. Também corrigi um defeito na minha resposta original que não permitia que o script usasse seu stdin (porque o script foi passado no stdin, sem uma boa razão).
Gilles 'SO- stop be evil'
1

É difícil imaginar por que você iria querer fazer isso, e muito menos onde você encontraria uma fonte (ou fontes) de scripts para baixar e executar dessa forma com frequência suficiente para que ele precise de uma ferramenta para fins especiais.

Por que não apenas baixar o script com curl(ou wgetou snarfqualquer outra coisa), examiná-lo e editá-lo (é um script raro que não precisará de personalização para seu sistema específico) e depois executá-lo - tornando-o executável com chmodou com sh scriptname?

cas
fonte
Não quero uma ferramenta para fins especiais. Lembro que havia uma maneira fácil de fazer isso com as ferramentas padrão.
precisa saber é o seguinte
2
Não seria difícil escrever um pequeno script de shell (provavelmente com apenas cinco linhas) para fazer o download de um script, apresentá-lo para visualização lessou algo assim e perguntar se você deseja executá-lo. Não consigo ver que isso seria melhor do que apenas baixar o script, visualizá-lo e executá-lo se parecesse bom. Na IMO, seria pior, não ofereceria nenhuma vantagem, mas removeria a flexibilidade que você obtém ao trabalhar em seu shell.
cas
0

Use esta linha de comando:

curl URL | ( cat > /tmp/file; read REPLY; [[ ! $REPLY =~ ^[Yy]$ ]] && cat /tmp/file ) | sh

Você pode usar uma pequena função para isso:

curlsh()
{
    curl "$1" \
    | ( cat > /tmp/file;read REPLY; [[ ! $REPLY =~ ^[Yy]$ ]] && cat /tmp/file ) \
    | sh
}

E do que usá-lo desta maneira:

curlsh http://site.in.net/path/to/script
Igor Chubin
fonte
0

Supondo que sua leitura saiba -p (prompt), e o script não precise ser executado com o intérprete, especificado pelo shebang:

curl URL | tee /tmp/x && read -p "execute?" key ; test $key = y && sh /tmp/x
Usuário desconhecido
fonte