Принуждение cURL для получения пароля из среды

Этот вопрос об использовании cURL с именем пользователя и паролем имеет субоптимальные ответы для меня:

  • curl -u "user:pw" https://example.com помещает pw в список процессов
  • curl "https://user:[email protected]" помещает pw в список процессов
  • curl -u "user:$(cat ~/.passwd)" https://example.com помещает pw в список процессов
  • curl -u user https://example.com запрашивает pw
  • curl --netrc-file ~/.netrc https://example.com требуется файл

# 4 безопасен, но я могу выполнять эту команду сотни раз в день, поэтому это утомительно. # 5 близок к безопасности, но этот файл может быть прочитан кем-то с правами доступа root.

страница cURL говорит (обратите внимание на жирный текст):

-u/--user <user:password>

Укажите имя пользователя и пароль для аутентификации сервера. Переопределяет -n/--netrc и --netrc-optional.

Если вы просто укажете имя пользователя (без ввода двоеточия), завиток будет введите пароль.

Если вы используете двоичный ключ с включенным SSPI и выполняете аутентификацию NTLM, вы может заставить curl забрать имя пользователя и пароль из вашей среды.просто указав один двоеточие с этой опцией: -u :.

Я попытался установить $USER и $PASSWORD$CURLOPT_PASSWORD и другие) в среде, но cURL doesn ' t выбирает любой из них при вызове curl -u : https://example.com (и не работает без -u :).

Я не делаю NTLM, так что это не работает. Если я что-то не упустил.

 

Есть ли способ передать учетные данные в curl только через среду?

 

(Обходной путь перешел к ответу)

Ответ 1

Это решение bash, по-видимому, наилучшим образом соответствует моим потребностям. Он прилично защищает, переносит и быстро.

#!/bin/bash
SRV="example.com"
URL="https://$SRV/path"
curl --netrc-file <(cat <<<"machine $SRV login $USER password $PASSWORD") "$URL"

Здесь используется замещение процесса (<( command ) выполняется command в под-оболочке для заполнения файловый дескриптор, который будет передан как "файл" родительской команде, которая в этом случае curl). Подстановка процесса содержит here-string (cat <<< text, вариант echo text, который не внесет ничего в ваш список процессов), создание файлового дескриптора для файла netrc для передачи учетных данных на удаленный веб-сервер.

Безопасность, обеспечиваемая заменой процесса, на самом деле довольно проста: ее дескриптор файла не является временным файлом и недоступен даже из других вызовов в одном экземпляре оболочки, поэтому этот выглядит безопасным в этом контексте; противнику придется вырыть память или запустить сложную атаку, чтобы найти ее содержимое. Поскольку переменная среды $PASSWORD также находится в памяти, это не должно увеличивать поверхность атаки .

Пока вы не использовали export PASSWORD, трюк вроде ps ewwp $$ не должен раскрывать пароль (как отмечено в этом комментарии). Было бы также разумно использовать менее понятное имя переменной.

Вот упрощенная небезопасная версия вышеуказанного кода, которая может помочь объяснить, как это работает:

#!/bin/sh
# INSECURE VERSION, DO NOT USE
SRV=example.com
URL="https://$SRV/path"
TMP=$(mktemp)
printf "machine %s login %s password %s\n" "$SRV" "$USER" "$PASSWORD" > "$TMP"
curl --netrc-file "$TMP" "$URL"
rm -f "$TMP"

В этой небезопасной версии есть много недостатков, все из которых решены в предыдущей версии:

  • Он хранит пароль в файле (хотя этот файл доступен только для чтения)
  • Он очень коротко имеет пароль в командной строке
  • Временной файл остается до тех пор, пока curl не выйдет из
  • Ctrl + c выйдет без удаления временного файла

Некоторые из них могут быть решены с помощью:

#!/bin/sh
SRV=example.com
URL="https://$SRV/path"
TMP=$(mktemp /dev/shm/.XXXXX)  # assumes /dev/shm is a ramdisk
trap "rm -f $TMP" 0 18
cat << EOF > "$TMP"
machine $SRV login $USER password $PASSWORD
EOF
(sleep 0.1; rm -f "$TMP") &  # queue removing temp file in 0.1 seconds
curl --netrc-file "$TMP" "$URL"

Я считаю, что эта версия является грязной, неоптимальной и, возможно, менее безопасной (хотя она более переносима). Он также требует версию sleep, которая понимает десятичные знаки (и 0,1 секунды могут быть слишком быстрыми, если система сильно загружена).

 


Я изначально разместил обходное решение, в которое входил мой вопрос perl с одним вкладышем, затем (с помощью от Etan Reisner). Я проработал несколько лучше методы, прежде чем опираться на этот метод здесь-строки, который является более легким (быстрее) и более портативным.

На данный момент он достаточно изящный, что я считаю его "ответом", а не "уродливым обходным путем", поэтому я перенес его, чтобы быть официальным ответом. Я дал @ghoti +1 для своего ответа, в котором правильно указано, что программа командной строки cURL неспособный делать то, что я хочу сам по себе, но я не принимаю этот ответ, потому что он не помогает решить проблему.

Ответ 2

Есть ли способ передать учетные данные curl только через среду?

Нет, я не думаю, что есть.

Документация CURLOPT_USERPWD. Я думаю, что описываю, что вам нужно, но это вариант, который будет доступен с использованием библиотеки curl в некоторых других язык. PHP, Perl, C и т.д.

Бинарный файл curl, который вы запускаете из своей оболочки, является еще одним интерфейсом в этой библиотеке, но способ, которым такие вещи, как CURLOPT_USERPWD, передается в библиотеку через двоичный файл curl, - это использование параметров командной строки в двоичном формате.

Вы могли бы теоретически написать свой собственный двоичный файл как переднюю часть библиотеки curl и написать в поддержку переменных среды.

Вы можете поочередно взламывать поддержку среды, так как вы надеетесь увидеть ее в существующем двоичном файле curl и скомпилировать свои собственные локальные функции.

Остерегайтесь, однако, что даже переменные среды могут быть просочились вашей оболочкой в ​​таблицу процессов. (Что вы видите при запуске ps ewwp $$?)

Возможно, файл .netrc с ограниченными правами будет самым безопасным способом. Возможно, вам понадобится создать временный файл .netrc, который будет использоваться опцией --netrc-file curl.

Я думаю, вам нужно либо выбрать наименее рискованное решение для вашей среды, либо написать что-то на реальном языке, который правильно защищает.

Ответ 3

Пользователь "Tom, Bom" предоставляет достойное решение для этого здесь: https://coderwall.com/p/dsfmwa/securely-use-basic-auth-with-curl

curl --config - https://example.com <<< 'user = "username:password"'

Это предотвращает отображение паролей в списке процессов, хотя это не касается конкретно исходного вопроса OP:

Есть ли способ передать учетные данные, чтобы свернуться исключительно через среду?

Я все еще даю очки @ghoti за более полный и информативный ответ.

Ответ 4

Предыдущие ответы верны, лучший вариант - использовать -n для curl (при условии, что вы работаете в Linux):

  1. создать файл (используйте свой любимый редактор)

vi ~YOUR_USER_NAME/.netrc

  1. добавить следующие

machine example.com login YOUR_USER_NAME password THE_ACTUAL_PASSWORD

  1. бежать

curl -n https://example.com/some_end_point