Используя cURL с именем пользователя и паролем?


469

Я хочу получить доступ к URL, который требует имя пользователя / пароль. Я хотел бы попробовать получить к нему доступ с помощью curl. Прямо сейчас я делаю что-то вроде:

curl http://api.somesite.com/test/blah?something=123

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

Как я могу это сделать?

Ответы:


696

Используйте -uфлаг, чтобы включить имя пользователя, и curl запросит пароль:

curl -u username http://example.com

Вы также можете включить пароль в команду, но тогда ваш пароль будет виден в истории bash:

curl -u username:password http://example.com

109
Обратите внимание, что если вы сделаете это с консоли, пароль останется в истории, что ... неверно. Вы должны указать только -u user, и CURL попросит вас ввести пароль в режиме no-echo.
— Кристиан Враби

25
@CristianVrabie Технически правильно, но неверно, если вы запускаете его из автоматического скрипта, который не разрешает запросы. Было бы интересно узнать о решении этой проблемы.
— Ligemer

26
@OmarOthman, если вы запускаете curl из скрипта, учетные данные (очевидно) не окажутся в вашей истории, но они будут видны в ps (1). исправить:print -- '-u username:password' > somewhere && curl -K somewhere http://...
— просто кто-то

7
@Jay Переменные среды будут оцениваться до выполнения команды. Пароль будет все еще виден в выводе ps.
— Роберт Важан

8
Не говоря уже о сути, но я считаю, что мой ответ ( stackoverflow.com/a/27894407/758174 т.е. использование --netrc-file) более безопасен. Он хранит пароль вне истории, ps, вашего скрипта и т. Д. Это единственная форма, которую я использую во всех моих скриптах и ​​для всех аутентифицированных способов использования curl.
— Pierre D

255

Это безопаснее сделать:

curl --netrc-file my-password-file http://example.com

... так как передача простой строки user / password в командной строке - плохая идея.

Формат файла паролей (согласно man curl):

machine <example.com> login <username> password <password>

Замечания:

  1. Имя машины не должно включать https://или подобное! Просто имя хоста.
  2. Слова ' machine', ' login' и ' password' являются просто ключевыми словами; фактическая информация - это материал после этих ключевых слов.

10
Да, это не позволяет ввести пароль в список процессов и историю команд. Гораздо предпочтительный способ сделать это, и только немного больше работы :)
— AC Capehart

8
Это определенно должен быть принятый ответ; пароли в командной строке - ужасная практика. (И это широко известный факт.)
— ELLIOTTCABLE

6
Вы также можете использовать флаг -K <file>или --config <file>для получения флагов скручивания через файл или стандартный ввод. (Предупреждение: не путать с -kили --insecure!)
— Rufflewind

2
Этот метод curl хранит учетные данные вне истории и статуса процесса, но оставляет имя пользователя и пароль открытым текстом в файле my-password, создавая еще один вектор атаки - хуже, чем наличие информации в файле истории: например, bash автоматически ограничивает разрешения файла истории. Аналогичная проблема возникает при использовании переменных среды, например, с помощью скрипта для установки имени пользователя / пароля. Если сценарий не является безопасным, ни учетные данные не являются.
— Стивен легко

5
@SteventheEasilyAmused Я не согласен, гораздо лучше использовать .netrcфайл открытого текста с соответствующими строгими разрешениями, чтобы его мог прочитать только ваш пользователь, чем другие механизмы (например, аргументы командной строки), которые позволяют другим пользователям читать информацию.
— Кен Уильямс

77

Или то же самое, но другой синтаксис

curl http://username:password@api.somesite.com/test/blah?something=123

1
Я использую этот синтаксис, потому что может использоваться во многих других ситуациях. Как из Windows cmd без cURL и wGet, используя start "" "http://username:password@api.somesite.com/test/blah?something=123". Его можно запустить из любого места. Это также относится к
— входам

9
Чтобы использовать смешные символы, необходимо URL-адрес, кодирование имени пользователя и пароля
— diachedelic

2
Я знаю, что большинство людей знают, что не нужно отправлять пароли (или даже имена пользователей) в URL-адресах, как в этом примере, так как их легко понюхать. С этим сказал; Я не рекомендую его, но использую только тогда, когда вы знаете, что делаете.
— LosManos

1
Это архаика suuuuuper и не должна использоваться. Это из дней FTP: o
— Qix - МОНИКА БЫЛА НЕПРАВИЛЬНОЙ

2
К сожалению, это оставляет пароль видимым в списке процессов.
— Марк

63

Вы также можете просто отправить имя пользователя, написав:

curl -u USERNAME http://server.example

Curl попросит вас ввести пароль, и пароль не будет отображаться на экране (или, если вам нужно скопировать / вставить команду).


28

Чтобы безопасно передать пароль в сценарии (то есть предотвратить его появление с помощью ps auxf или logs), вы можете сделать это с флагом -K- (чтение конфигурации из stdin) и heredoc:

curl --url url -K- <<< "--user user:password"

2
Спасибо за ссылку на --configопцию (-K) ... возможно, лучшим решением было бы поместить "--user user: password" в файл и просто, -K the fileчтобы у вас была только одна копия пароля, а не копия в каждом скрипте , Гораздо проще обезопасить один файл.
— Крис Когдон

1
Подобный вариант, где только пароль в файле: cat "${password_filepath}" | sed -e "s/^/-u ${username}:/" | curl --url "${url}" -K-. Мне пришлось поставить -K-перед URL для старого MacOS Bash, YMMV.
— Марк

12

Обычно команда CURL называется

curl https://example.com\?param\=ParamValue -u USERNAME:PASSWORD

если у вас нет пароля или вы хотите пропустить командную строку для запроса пароля, просто оставьте раздел пароля пустым.

т.е. curl https://example.com\?param\=ParamValue -u USERNAME:


1
ПРИМЕЧАНИЕ. Пароль будет отображаться в истории оболочки и списке процессов.
— Марк

10
curl -X GET -u username:password  {{ http://www.example.com/filename.txt }} -O

1
ПРИМЕЧАНИЕ. Пароль будет отображаться в истории оболочки и списке процессов.
— Марк

8

Чтобы пароль как минимум не всплывал в вашем .bash_history:

curl -u user:$(cat .password-file) http://example-domain.tld

6
В этом случае пароль все равно останется в списке процессов, например, он виден кому-то, кто делает ps auxw |grep curlв нужное время. Точно так же пароль будет зарегистрирован, если запущен черезsudo
— Адам Кац

1
С помощью этого метода пароль будет представлен в файле (.password-file), который может быть более небезопасным, чем история .bash. Хорошей частью этого является то, что это только пароль - URL и имя пользователя не просочились в .password-файл.
— Стивен легко


6

Другие ответы предложили netrc указать имя пользователя и пароль, основываясь на том, что я прочитал, я согласен. Вот некоторые детали синтаксиса:

https://ec.haxx.se/usingcurl-netrc.html

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

Хотя я не эксперт, я нашел эти ссылки проницательными:

https://ec.haxx.se/cmdline-passwords.html

Обобщить:

Использование зашифрованных версий протоколов (HTTPS против HTTP) (FTPS против FTP) может помочь избежать утечки в сети.

Использование netrc может помочь избежать утечки командной строки.

Чтобы пойти дальше, кажется, вы также можете зашифровать файлы netrc с помощью gpg

https://brandur.org/fragments/gpg-curl

При этом ваши учетные данные не «в состоянии покоя» (хранятся) в виде простого текста.


5

Проще говоря, самым безопасным способом было бы использование переменных среды для хранения / получения ваших учетных данных. Таким образом, команда curl вроде:

curl -Lk -XGET -u "${API_USER}:${API_HASH}" -b cookies.txt -c cookies.txt -- "http://api.somesite.com/test/blah?something=123"

Затем вызовет ваш API apful и передаст WWW_Authenticationзаголовок http с закодированными в Base64 значениями API_USERи API_HASH. Команда -Lkjust указывает curl следовать перенаправлениям http 30x и использовать небезопасную обработку tls (т.е. игнорировать ошибки ssl). В то время как double --- это просто синтаксис bash, чтобы остановить обработку флагов командной строки. Кроме того, -b cookies.txtи -c cookies.txtфлаги обрабатывать печенье с -bотправкой печенья и -cхранить печенье локально.

В руководстве есть больше примеров методов аутентификации .


1
Имейте в виду, что использование «-Lk» может открыть вас для атак «человек посередине» (MITM), поэтому будьте осторожны с этой опцией.
— GuyPaddock

4
Это не работает ... так как bash расширяет эти переменные для вас, расширение появляется в списке процессов.
— Крис Когдон


4

Самый безопасный способ передачи учетных данных в curl - это ввести их. Это то, что происходит при передаче имени пользователя, как предлагалось ранее ( -u USERNAME).

Но что, если вы не можете передать имя пользователя таким образом? Например, имя пользователя может быть частью URL-адреса, и только пароль должен быть частью полезной нагрузки json.

tl; dr: Вот как безопасно использовать curl в этом случае:

read -p "Username: " U; read -sp "Password: " P; curl --request POST -d "{\"password\":\"${P}\"}" https://example.com/login/${U}; unset P U

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

Я расскажу, почему другие решения не идеальны.

Почему переменные среды небезопасны

  1. Режим доступа и доступа к содержимому переменной среды не может быть отслежен (ps -eww), поскольку среда неявно доступна для процесса
  2. Часто приложения захватывают всю среду и регистрируют ее для целей отладки или мониторинга (иногда в виде файлов журнала на незашифрованном диске, особенно после сбоя приложения)
  3. Переменные среды передаются дочерним процессам (поэтому нарушается принцип наименьших привилегий)
  4. Поддержание их является проблемой: новые инженеры не знают, что они там есть, и не знают о требованиях вокруг них - например, не передавать их подпроцессам - так как они не применяются или не документированы.

Почему небезопасно вводить его непосредственно в команду в командной строке, потому что ваш секрет в конечном итоге становится видимым для любого другого пользователя, работающего из-за того, ps -auxчто в нем перечислены команды, отправленные для каждого выполняющегося в данный момент процесса. Кроме того, потому что ваш секрет затем попадает в историю Bash (после завершения оболочки).

Почему включать его в локальный файл небезопасно Строгое ограничение доступа POSIX к файлу может снизить риск в этом сценарии. Тем не менее, это все еще файл в вашей файловой системе, незашифрованный в состоянии покоя.


2
Кажется, что этот метод все еще показывает пароль в списке процессов?
— Марк

4

У меня была такая же потребность в bash (Ubuntu 16.04 LTS), и команды, приведенные в ответах, не работали в моем случае. Я должен был использовать:

curl -X POST -F 'username="$USER"' -F 'password="$PASS"' "http://api.somesite.com/test/blah?something=123"

Двойные кавычки в -Fаргументах нужны только если вы используете переменные, поэтому с командной строкой ... -F 'username=myuser' ...все будет в порядке.

Соответствующее примечание по безопасности: как отметил г-н Марк Рибау в комментариях, эта команда отображает пароль (переменная $ PASS, расширенная) в списке процессов!


1
Похоже, это все еще показывает значение $ PASS в списке процессов?
— Марк

Да, к сожалению, это так.
— Марко

1

Если вы работаете в системе, в которой есть приложение для набора ключей Gnome, решение, которое позволяет не раскрывать пароль напрямую, это использовать gkeyring.py для извлечения пароля из набора ключей:

server=server.example.com
file=path/to/my/file
user=my_user_name
pass=$(gkeyring.py -k login -tnetwork -p user=$user,server=$server -1)

curl -u $user:$pass ftps://$server/$file -O

1
ПРИМЕЧАНИЕ. Пароль будет отображаться в списке процессов. (И история, если это не является частью сценария.)
— Марк

1

Это НАМНОГО больше, чем запрашивал ОП, но так как это лучший результат для безопасной передачи паролей curl, я добавляю эти решения сюда для тех, кто прибывает сюда в поисках этого.


ПРИМЕЧАНИЕ: команда -sarg for readне является POSIX и поэтому доступна не везде, поэтому она не будет использоваться ниже. Мы будем использовать stty -echoи stty echoвместо.

ПРИМЕЧАНИЕ. Все переменные bash, приведенные ниже, могут быть объявлены как локальные, если они есть в функции, а не в unset.

ПРИМЕЧАНИЕ: perlдовольно широко доступен во всех системах, которые я пробовал, потому что это зависимость для многих вещей, тогда как rubyи pythonнет, поэтому perlздесь используется . Если вы можете гарантировать ruby/ pythonгде вы делаете это, вы можете заменить perlкоманду их эквивалентом.

ПРИМЕЧАНИЕ. Протестировано в bash3.2.57 на macOS 10.14.4. Небольшой перевод может потребоваться для других оболочек / установок.


Надежно запросите у пользователя (многоразовый) пароль для перехода к curl. Особенно полезно, если вам нужно вызывать curl несколько раз.

Для современных оболочек, где echoесть встроенный (проверьте через which echo):

url='https://example.com'
printf "Username: "
read username
printf "Password: "
stty -echo  # disables echoing user input, POSIX equivalent for 'read -s'
read pass
printf "\n" # we need to move the line ahead
stty echo   # re-enable echoing user input
echo ${pass} | sed -e "s/^/-u ${username}:/" | curl --url "${url}" -K-
unset username
unset pass

Для старых оболочек, где echoчто-то вроде /bin/echo(где все, что эхо, можно увидеть в списке процессов):
ЭТА ВЕРСИЯ НЕ МОЖЕТ ПОВТОРЯТЬ ПАРОЛЬ , см. Ниже.

url='https://example.com'
printf "Username: "
read username
printf "Password: "
stty -echo  # disables echoing user input, POSIX equivalent for 'read -s'
perl -e '
    my $val=<STDIN>;
    chomp $val;
    print STDERR "\n";  # we need to move the line ahead, but not send a newline down the pipe
    print $val;
' | sed -e "s/^/-u ${username}:/" | curl --url "${url}" -K-
stty echo   # re-enable echoing user input
unset username



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

Когда эхо является встроенным (это особенно надумано, так как эхо является встроенным, но предусмотрено для полноты):

url='https://example.com'
filepath="$(mktemp)"  # random path, only readable by current user
printf "Username: "
read username
printf "Password: "
stty -echo  # disables echoing user input, POSIX equivalent for 'read -s'
read pass
echo "${pass}" > "${filepath}"
unset pass
printf "\n" # we need to move the line ahead
stty echo   # re-enable echoing user input

cat "${filepath}" | sed -e "s/^/-u ${username}:/" | curl --url "${url}" -K-

rm "${filepath}"  # don't forget to delete the file when done!!
unset username

Когда эхо-что-то вроде /bin/echo:

url='https://example.com'
filepath="$(mktemp)"  # random path, only readable by current user
printf "Username: "
read username
printf "Password: "
stty -echo  # disables echoing user input, POSIX equivalent for 'read -s'
$(perl -e '
    my $val=<STDIN>;
    chomp $val;
    open(my $fh, ">", $ARGV[0]) or die "Could not open file \"$ARGV[0]\" $\!";
    print $fh $val;
    close $fh;
' "$filepath")
printf "\n" # we need to move the line ahead
stty echo   # re-enable echoing user input

cat "${filepath}" | sed -e "s/^/-u ${username}:/" | curl --url "${url}" -K-

rm "${filepath}"  # don't forget to delete the file when done!!
unset username
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.