Використовуєте cURL з ім'ям користувача та паролем?


466

Я хочу отримати доступ до URL-адреси, яка вимагає імені користувача / пароля. Я хотів би спробувати отримати доступ до нього з завитком. Зараз я роблю щось на кшталт:

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

Я отримую помилку. Я думаю, мені потрібно вказати ім’я користувача та пароль разом із вищевказаною командою.

Як я можу це зробити?

Відповіді:


693

Використовуйте -uпрапор, щоб вказати ім’я користувача, а curl запропонує пароль:

curl -u username http://example.com

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

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

109
Зауважте, що якщо це зробити з консолі, пароль залишиться в історії, яка ... неправильна. Ви повинні вказати просто -u користувача, і CURL попросить вас пароль у режимі без ехо.
Крістіан Врабі

25
@CristianVrabie Технічно правильно, але неправильно, якщо ви запускаєте його з автоматизованого сценарію, який не дозволяє підказувати. Було б цікаво вирішити цю проблему.
Лігемер

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

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

8
Не заважати суті, але я вважаю, що моя відповідь ( stackoverflow.com/a/27894407/758174, тобто використання --netrc-file) є більш безпечною. Він не захищає пароль від історії, ps, вашого сценарію тощо. Це єдина форма, яку я використовую у всіх своїх сценаріях і для всіх автентифікованих звичаїв curl.
П’єр Д

253

Безпечніше робити:

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

... як проходження простого рядка користувача / пароля в командному рядку - це погана ідея.

Формат файлу паролів (відповідно 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>отримувати прапори curl через файл або стандартний ввід. (Попередження: не плутати з -kабо --insecure!)
Rufflewind

2
Цей метод згортання не дає даних про історію та статус процесу, але залишає ім'я користувача та пароль у чіткому тексті у файлі my-password, створюючи інший вектор атаки - гірше, ніж наявність інформації у файлі історії: bash, наприклад, автоматично обмежує дозволи файлу історії. Аналогічна проблема виникає, якщо використовувати змінні середовища з, наприклад, скриптом для встановлення імені користувача / пароля. Якщо скрипт не захищений, також не є облікові дані.
Стівен Легко розважався

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

76

Або те саме, але різний синтаксис

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". Його можна запустити з будь-якого місця. Це стосується також ftp входу; D
m3nda

8
Вам потрібно
зашифрувати

2
Я знаю, що більшість людей знає, що не надсилає паролі (або навіть імена користувачів) у URL-адресі, як у цьому прикладі, оскільки це легко нюхати. З урахуванням сказаного; Я не відмовляюсь від цього, але використовуйте лише тоді, коли ви знаєте, що ви робите.
LosManos

1
Це надмірна архаїчність і не слід використовувати. Це з днів FTP: o
Qix - MONICA ПОМИЛИЛИ

2
На жаль, це залишає пароль видимим у списку процесів.
Марк Рібау

63

Ви також можете просто надіслати ім'я користувача, написавши:

curl -u USERNAME http://server.example

Curl запитає вас про пароль, і пароль не буде видно на екрані (або якщо вам потрібно скопіювати / вставити команду).


27

Щоб надійно передати пароль у скрипті (тобто запобігти появі з 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, 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-файл), який може бути більш небезпечним, ніж історія .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 та передасть WWW_Authenticationзаголовку http із кодованими значеннями Base64 API_USERта API_HASH. -LkПросто каже завиток слідувати HTTP 30x переадресовує і використовувати небезпечні TLS обробки (тобто ігнорувати Ssl помилок). Тоді як подвійний --- це лише синтаксичний цукор bash, щоб зупинити обробку прапорами командного рядка. Крім того, -b cookies.txtі -c cookies.txtпрапори обробляють файли cookie, -bнадсилаючи файли cookie та -cзберігаючи файли cookie локально.

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


1
Майте на увазі, що використання "-Lk" може відкрити вас до атак "людина в середині" (MITM), тому будьте обережні з цим варіантом.
GuyPaddock

4
Це не працює ... оскільки bash розширює ці змінні для вас, розширення відображається в списку процесів.
Кріс Когдон


4

Найбезпечніший спосіб передачі облікових даних для згортання - запропонувати вставити їх. Це відбувається при передачі імені користувача, як було запропоновано раніше ( -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оскільки перераховує команди, подані для кожного поточного запущеного процесу. Також тому, що ваш secrte потім опиняється в історії башів (як тільки оболонка закінчується).

Чому небезпечно включати його у локальний файл Суворе обмеження доступу до файлу 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 для readкоманди не є POSIX, тому він доступний не скрізь, тому він не буде використовуватися нижче. Ми будемо використовувати stty -echoі stty echoзамість цього.

ПРИМІТКА. Усі змінні bash, наведені нижче, замість цього можуть бути оголошені як локальні, якщо вони функціонують, а не не встановлюються.

ПРИМІТКА: perlдосить загальнодоступний у всіх системах, які я намагався, оскільки він залежність від багатьох речей, тоді як rubyі pythonні, тому perlтут використовується . Якщо ви можете гарантувати ruby/ pythonде ви це робите, ви можете замінити perlкоманду на їх еквівалент.

ПРИМІТКА: Випробувано в bash3.2.57 на macOS 10.14.4. Для інших оболонок / установок може знадобитися невеликий переклад.


Безпечно запропонуйте користувачеві пароль (для багаторазового використання), щоб перейти до згортання. Особливо корисно, якщо вам потрібно зателефонувати завивати кілька разів.

Для сучасних снарядів, де 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



Якщо вам потрібно тимчасово зберігати пароль у файлі, повторно використовувати його для декількох команд, перш ніж очистити його (скажімо, ви використовуєте функції для повторного використання коду і не хочете повторювати код і не можете передайте значення навколо через 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'
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.