Принуждение 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):
- создать файл (используйте свой любимый редактор)
vi ~YOUR_USER_NAME/.netrc
- добавить следующие
machine example.com login YOUR_USER_NAME password THE_ACTUAL_PASSWORD
- бежать
curl -n https://example.com/some_end_point