Прочитайте и подтвердите сценарий оболочки перед передачей из curl в sh (curl -s [url] | sh)

11

Всякий раз, когда мне нужно выполнить сценарий оболочки из Интернета curl -s [url] | sh, я сначала открываю urlв своем веб-браузере, чтобы убедиться, что сценарий не является вредоносным и безопасен для запуска.

Я помню трюк из командной строки, который позволил прочитать сценарий из командной строки и затем подтвердить выполнение после чтения сценария. Если я правильно помню, это выглядело примерно так curl -s [url] | something...here | shи не требовало никакой установки программного обеспечения.

Кто-нибудь знает этот трюк?

Оливье Лалонд
источник

Ответы:

5

В moreutilsвызываемой программе есть утилита, vipeкоторая показывает stdin в редакторе, где вы можете просмотреть и изменить файл, прежде чем он будет передан в stdout.

Если вы не хотите устанавливать moreutils, вы можете сделать что-то похожее на это:

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

mktempнаходится coreutilsи, скорее всего, уже установлен в вашей системе.

Шон Дж. Гофф
источник
2

Я не могу придумать ни одной утилиты, которая бы делала то, что вы описываете, но достаточно легко сделать это фрагментом оболочки.

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

Это предполагает, что скрипт представляет собой текстовый файл. Нулевые байты не поддерживаются: в зависимости от оболочки они могут быть удалены или могут привести к усечению строки или всего файла. Также удаляются все новые строки в конце файла (конструкция heredoc добавляет один обратно). Обычно это не проблема для сценария, но это может быть, например, если сценарий заканчивается архивом в двоичном формате, который он извлекает. Это не очень надежный способ распространения файла, поскольку существует значительный риск того, что такой бинарный скрипт в какой-то момент будет неправильно закодирован. Тем не менее, вы можете справиться с этим, записав скрипт во временный файл.

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"
Жиль "ТАК - прекрати быть злым"
источник
$()должны быть указаны в первой строке. Кроме того, это приведет к удалению NUL-символов во входных данных, что может быть фатальным (например, в случае самораспаковывающегося скрипта).
10
1
@ l0b0 Вам не нужно цитировать в задании, хотя, возможно, это хороший стиль . Нулевые байты действительно теряются, как и последние символы новой строки; если вы собираетесь включить архив в скрипт оболочки, я рекомендую использовать кодировку текста, например base64.
Жиль "ТАК - перестань быть злым"
Все действительные баллы, как обычно. +1
l0b0
@ l0b0 Если подумать, хотя это несколько рискованно, это верный вариант использования. Я обновил свой ответ. Я также исправил дефект в своем исходном ответе, который не позволял сценарию использовать его стандартный ввод (потому что сценарий был передан на стандартный ввод без уважительной причины).
Жиль "ТАК - перестань быть злым"
1

Трудно представить, почему вы вообще захотите это сделать, не говоря уже о том, где вы найдете источник (или источники) сценариев, которые можно загружать и запускать так часто, что для этого требуется специальный инструмент.

Почему бы просто не скачать скрипт с помощью curl(или, wgetили с snarfчем-то еще), изучить и отредактировать его (это редкий скрипт, который не требует какой-либо настройки для вашей конкретной системы), а затем запустить его - сделав его исполняемым с chmodили с sh scriptname?

саз
источник
Я не хочу специального инструмента. Я помню, что был простой способ сделать это стандартными инструментами.
Оливье Лалонд
2
Нетрудно написать небольшой сценарий оболочки (вероятно, всего около 5 строк), чтобы загрузить сценарий, представить его для просмотра с lessчем-то или чем-то еще, а затем спросить вас, хотите ли вы запустить его. Я не вижу, что это было бы лучше, чем просто загрузить скрипт, просмотреть его, а затем запустить его, если он кажется нормальным. IMO было бы хуже, это не дало бы никаких преимуществ, но лишило бы гибкости, которую вы получаете, просто работая в своей оболочке.
Cas
0

Используйте эту командную строку:

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

Вы можете использовать небольшую функцию для этого:

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

И чем использовать это так:

curlsh http://site.in.net/path/to/script
Игорь Чубин
источник
0

Предполагая, что ваше чтение знает -p (приглашение), и сценарий не должен выполняться с интерпретатором, указанным в shebang:

curl URL | tee /tmp/x && read -p "execute?" key ; test $key = y && sh /tmp/x
неизвестный пользователь
источник