Lisez et confirmez le script shell avant de passer de curl à sh (curl -s [url] | sh)


11

Chaque fois que je dois exécuter un script shell à partir du Web curl -s [url] | sh, je l'ouvre d'abord urldans mon navigateur Web pour m'assurer que le script n'est pas malveillant et peut être exécuté en toute sécurité.

Je me souviens avoir vu une astuce de ligne de commande qui permettait de lire le script à partir de la ligne de commande, puis de confirmer l'exécution après avoir lu le script. Si je me souviens bien, cela ressemblait à quelque chose curl -s [url] | something...here | shet ne nécessitait aucune installation de logiciel.

Est-ce que quelqu'un connaît cette astuce?

Réponses:


5

Il existe un utilitaire moreutilsappelé vipequi montre stdin dans un éditeur, où vous pouvez récupérer et modifier le fichier avant qu'il ne soit transmis à stdout.

Si vous ne voulez pas installer moreutils, vous pouvez accomplir quelque chose de similaire comme ceci:

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

mktempest coreutilsinstallé et est probablement déjà installé sur votre système.


2

Je ne peux pas penser à un seul utilitaire qui ferait ce que vous décrivez, mais il est assez facile d'en faire un extrait 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

Cela suppose que le script est un fichier texte. Les octets nuls ne sont pas pris en charge: selon le shell, ils peuvent être supprimés, ou ils peuvent tronquer une ligne ou tout le fichier. De plus, tous les sauts de ligne à la fin du fichier sont supprimés (la construction heredoc en ajoute un). Ce n'est normalement pas un problème pour un script, mais il pourrait l'être, par exemple, si le script se termine par une archive au format binaire qu'il extrait. Ce n'est pas un moyen très fiable de distribuer un fichier car il existe un risque important qu'un tel script binaire soit mal codé à un moment donné. Néanmoins, vous pouvez le gérer en écrivant le script dans un fichier temporaire.

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"

$()doit être cité sur la première ligne. En outre, cela supprimerait les caractères NUL dans l'entrée, ce qui pourrait éventuellement être fatal (par exemple dans le cas d'un script auto-extractible).
l0b0

1
@ l0b0 Vous n'avez pas besoin de citer dans une affectation, mais c'est sans doute un bon style . Les octets nuls sont en effet perdus, tout comme les nouvelles lignes finales; si vous allez inclure une archive dans un script shell, je recommande d'utiliser un encodage de texte tel que base64.
Gilles 'SO- arrête d'être méchant'

Tous les points valides, comme d'habitude. +1
l0b0

@ l0b0 Après réflexion, bien qu'il soit quelque peu sujet aux risques, il s'agit d'un cas d'utilisation valide. J'ai mis à jour ma réponse. J'ai également corrigé un défaut dans ma réponse d'origine qui ne permettait pas au script d'utiliser son stdin (car le script a été transmis à stdin, sans raison valable).
Gilles 'SO- arrête d'être méchant'

1

Il est difficile d'imaginer pourquoi vous voudriez même le faire, et encore moins où vous trouveriez une source (ou des sources) de scripts à télécharger et à exécuter comme ceci assez fréquemment pour qu'il ait besoin d'un outil spécial.

Pourquoi ne pas simplement télécharger le script avec curl(ou wgetou snarfou quoi que ce soit), l'examiner et le modifier (c'est un script rare qui n'aura pas besoin de personnalisation pour votre système particulier), puis l'exécuter - soit en le rendant exécutable avec chmodou avec sh scriptname?


Je ne veux pas d'un outil spécial. Je me souviens qu'il y avait un moyen facile de le faire avec des outils standard.
Olivier Lalonde

2
Il ne serait pas difficile d'écrire un petit script shell (probablement seulement 5 lignes environ) pour télécharger un script, le présenter pour visualisation avec lessou quelque chose, puis vous demander si vous vouliez l'exécuter. Je ne vois pas que ce serait mieux que de simplement télécharger le script, le visualiser, puis l'exécuter si cela semblait OK. OMI, ce serait pire, cela n'offrirait aucun avantage mais supprimerait la flexibilité que vous obtenez en travaillant simplement dans votre shell.
cas

0

Utilisez cette ligne de commande:

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

Vous pouvez utiliser une petite fonction pour cela:

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

Et puis utilisez-le de cette façon:

curlsh http://site.in.net/path/to/script

0

En supposant que votre lecture connaît -p (invite), et que le script n'a pas besoin d'être exécuté avec l'interpréteur, spécifié par le shebang:

curl URL | tee /tmp/x && read -p "execute?" key ; test $key = y && sh /tmp/x
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.