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

469

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

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

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

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

user246114
источник

Ответы:

696

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

curl -u username http://example.com

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

curl -u username:password http://example.com
Finbarr
источник
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 попросит вас ввести пароль, и пароль не будет отображаться на экране (или, если вам нужно скопировать / вставить команду).

Kristian
источник
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
user128364
источник
1
ПРИМЕЧАНИЕ. Пароль будет отображаться в истории оболочки и списке процессов.
Марк
8

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

curl -u user:$(cat .password-file) http://example-domain.tld
sjas
источник
6
В этом случае пароль все равно останется в списке процессов, например, он виден кому-то, кто делает ps auxw |grep curlв нужное время. Точно так же пароль будет зарегистрирован, если запущен черезsudo
Адам Кац
1
С помощью этого метода пароль будет представлен в файле (.password-file), который может быть более небезопасным, чем история .bash. Хорошей частью этого является то, что это только пароль - URL и имя пользователя не просочились в .password-файл.
Стивен легко
7

довольно легко, сделайте следующее:

curl -X GET/POST/PUT <URL> -u username:password
Preyas
источник
В этом вопросе нет требований безопасности
Виктор Поло Де Гивес Монтеро
1
ПРИМЕЧАНИЕ. Пароль будет отображаться в истории оболочки и списке процессов
Марк
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 к файлу может снизить риск в этом сценарии. Тем не менее, это все еще файл в вашей файловой системе, незашифрованный в состоянии покоя.

iammyr
источник
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, расширенная) в списке процессов!

Marco
источник
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
Марк Рибау
источник