Kullanıcı adı ve şifre ile cURL mu kullanıyorsunuz?


470

Bir kullanıcı adı / şifre gerektiren bir URL'ye erişmek istiyorum. Curl ile erişmeyi denemek istiyorum. Şu anda şöyle bir şey yapıyorum:

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

Bir hata alıyorum. Yukarıdaki komutla birlikte bir kullanıcı adı ve şifre belirtmem gerekiyor.

Bunu nasıl yapabilirim?

Yanıtlar:


696

-uBir kullanıcı adı eklemek için bayrağı kullanın; curl bir şifre isteyecektir:

curl -u username http://example.com

Parolayı komuta da ekleyebilirsiniz, ancak parolanız bash geçmişinde görünür olacaktır:

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

109
Bunu konsoldan yaparsanız, parola geçmişte kalır ... yanlış. Sadece -u kullanıcısı belirtmelisiniz ve CURL eko olmayan modda sizden şifre isteyecektir.
Cristian Vrabie

25
@CristianVrabie Teknik olarak doğru, ancak komut istemlerine izin vermeyen otomatik bir komut dosyasından çalıştırıyorsanız yanlıştır. Bu soruna bir çözüm merak ediyorum.
Ligemer

26
@OmarOthman bir komut dosyasından curl çalıştırıyorsanız, kimlik bilgileri (açıkçası) geçmişinize gelmez, ancak ps (1) 'de görünür olurlar. düzeltme:print -- '-u username:password' > somewhere && curl -K somewhere http://...
sadece birileri

7
@Jay Ortam değişkenleri komut yürütülmeden önce değerlendirilecektir. Şifre ps çıkışında görünmeye devam edecektir.
Robert Važan

8
Konuyu işaretlemek değil ama cevabımın ( stackoverflow.com/a/27894407/758174 yani kullanmak --netrc-file) daha güvenli olduğuna inanıyorum . Parolayı geçmiş, ps, betiğiniz, vb curl. Dışında tutar . Tüm komut dosyalarında ve tüm kimlik doğrulamalı kullanımlarında kullandığım tek form budur .
Pierre D

255

Bunu yapmak daha güvenlidir:

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

... komut satırında düz bir kullanıcı / parola dizesi iletilmesi kötü bir fikirdir.

Parola dosyasının biçimi (başına man curl):

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

Not:

  1. Makine adı gerekir değil kapsar https://veya benzer! Sadece ana bilgisayar adı.
  2. ' machine', ' login' Ve ' password' kelimeleri yalnızca anahtar kelimelerdir; gerçek bilgi bu anahtar kelimelerden sonraki şeylerdir.

10
Evet, bu işlem parolayı işlem listesinden ve komut geçmişinden uzak tutar. Bunu yapmak için çok tercih edilen bir yol ve sadece biraz daha fazla iş :)
AC Capehart

8
Bu kesinlikle kabul edilen cevap olmalı; komut satırındaki şifreler korkunç bir uygulamadır. (Ve bu çok bilinen bir gerçektir.)
YERLEŞTİRİLEBİLİR

6
Bayrağı -K <file>veya --config <file>eğri bayraklarını dosya veya standart girdi yoluyla almak için de kullanabilirsiniz . (Uyarı: -kveya ile karıştırılmamalıdır --insecure!)
Rufflewind

2
Bu kıvırma yöntemi, kimlik bilgilerini geçmiş ve işlem durumunun dışında tutar, ancak kullanıcı adı ve şifreyi parola dosyamda açık metin olarak bırakır; başka bir saldırı vektörü oluşturur - geçmiş dosyasında bilgi sahibi olmaktan daha kötü: bash, örneğin izinleri otomatik olarak kısıtlar geçmiş dosyasının. Benzer bir sorun, kullanıcı adını / şifreyi ayarlamak için örneğin bir betikle ortam değişkenleri kullanıldığında ortaya çıkar. Komut dosyası güvenli değilse, kimlik bilgileri de değildir.
Steven the kolayca eğlenerek

5
Katılmıyorum @SteventheEasilyAmused, bir cleartext kullanmak daha iyidir .netrcbu yüzden sadece, uygun şekilde sıkı izinlerine sahip dosyayı sizin kullanıcı izin diğer mekanizmalar (örneğin komut satırı args) daha okuyabilirsiniz diğer kullanıcıların bilgileri okuyun.
Ken Williams

77

Ya da aynı şey ama farklı sözdizimi

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

1
Bu sözdizimini kullanıyorum, çünkü daha birçok durumda kullanılabilir. CURL ve wGet kullanmayan bir Windows cmd gibi start "" "http://username:password@api.somesite.com/test/blah?something=123". Her yerden başlatılabilir. Aynı şey ftp girişleri için de geçerlidir; D
m3nda

9
Komik karakterler kullanmak için URL'yi kullanıcı adı ve şifreyi kodlamanız gerekiyor
diachedelic

2
Çoğu insanın koklaması kolay olduğu için bu örnekte olduğu gibi URL'de şifre (hatta kullanıcı adı) göndermemeyi bildiğini biliyorum. Bu sözü edilen; Tavsiye etmiyorum ama sadece ne yaptığınızı bildiğinizde kullanın.
LosManos

1
Bu Suuuuuper arkaik ve gerektiği değil kullanılmalıdır. FTP günlerinden itibaren: o
Qix - MONICA

2
Ne yazık ki, bu işlem listesinde parolayı görünür durumda bırakır.
Mark Ribau

63

Ayrıca kullanıcı adını yazarak da gönderebilirsiniz:

curl -u USERNAME http://server.example

Curl daha sonra sizden şifreyi soracaktır ve şifre ekranda görünmeyecektir (veya komutu kopyalamanız / yapıştırmanız gerekiyorsa).


28

Şifreyi bir komut dosyasında güvenli bir şekilde geçirmek için (yani ps auxf veya günlüklerle görünmesini önlemek için) bunu -K- bayrağı (stdin'den config'i okuyun) ve bir yorumlu metin ile yapabilirsiniz:

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

2
--config(-K) seçeneğine yapılan başvuru için teşekkürler ... "--user user: password" dosyasını bir dosyaya koymak daha iyi bir çözüm olabilir ve -K the filebu nedenle her komut dosyasında parolanın yalnızca bir kopyası vardır . Tek bir dosyayı güvenli hale getirmek çok daha kolay.
Chris Cogdon

1
Sadece şifre dosyasında olduğunu Benzer seçenek: cat "${password_filepath}" | sed -e "s/^/-u ${username}:/" | curl --url "${url}" -K-. -K-Eski macOS bash, YMMV için URL'den önce koymak zorunda kaldım .
Mark Ribau

13

Genellikle CURL komutu

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

Herhangi bir parolanız yoksa veya parola istemek için komut istemini atlamak istiyorsanız, parola bölümünü boş bırakın.

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


1
NOT: Parola kabuk geçmişinde ve işlem listesinde görünür.
Mark Ribau

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

1
NOT: Parola kabuk geçmişinde ve işlem listesinde görünür.
Mark Ribau

8

Parolanın en az bilgisayarınızda görünmemesi için .bash_history:

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

6
Bu durumda, şifre yine de işlem listesinde görünecektir, örneğin ps auxw |grep curldoğru zamanda yapan biri tarafından görülebilir . Benzer şekilde, şifre üzerinden çalıştırılırsa kaydedilecektirsudo
Adam Katz

1
Bu yöntemle, parola .bash geçmişinden daha güvensiz olabilecek bir dosyada (.password dosyası) bulunur. Bunun iyi tarafı, sadece şifre olmasıdır - URL ve kullanıcı adı .password dosyasında sızdırılmaz.
Steven the kolayca eğlendirdi


6

Diğer cevaplar netrc'yi okuduğum şeye göre kullanıcı adı ve şifre belirtmeyi önerdi. İşte bazı sözdizimi ayrıntıları:

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

Diğer cevaplar gibi, bu soruyla ilgili güvenliğe dikkat etme ihtiyacını vurgulamak istiyorum.

Her ne kadar uzman olmasam da, şu bağlantıları anladım:

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

Özetlemek:

Kullanılması protokollerin şifreli sürümlerini (HTTPS, HTTP vs) (FTP vs FTPS) önlemek Ağ Kaçak yardımcı olabilir.

Netrc kullanmak Komut Satırı Sızıntısını önlemeye yardımcı olabilir.

Bir adım daha ileri gitmek için, netrc dosyalarını gpg kullanarak şifreleyebilirsiniz.

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

Bununla kimlik bilgileriniz düz metin olarak "beklemede" (depolanmaz) olmaz.


5

Sade ve en güvenli yolu koymak kimlik bilgilerinizi depolamak / almak için ortam değişkenlerini kullanmak olacaktır. Böylece aşağıdaki gibi bir kıvırma komutu:

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

Ardından dinlendirici api arayıp http geçerdi WWW_AuthenticationBase64 değerlerini kodlanmış ile başlık API_USERve API_HASH. -LkSadece http 30x yönlendirmeleri takip etmek ve işleme güvensiz TLS kullanmayı curl söyler (yani SSL hataları görmezden). İkili --sadece komut satırı bayraklarını işlemeyi durdurmak için sözdizimi şekeri bash. Ayrıca, -b cookies.txtve -c cookies.txtbayrakları çerezleri yerel olarak depolamak -bve -cçerezleri saklamakla çerezleri işler.

Kılavuzda daha fazla kimlik doğrulama yöntemi örneği bulunmaktadır .


1
"-Lk" kullanmanın sizi ortadaki adam (MITM) saldırılarına açabileceğini unutmayın, bu nedenle bu seçenekle dikkatli olun.
GuyPaddock

4
Bu işe yaramaz ... bash bu değişkenleri sizin için genişlettiği için genişletme işlem listesinde görünür.
Chris Cogdon


4

Kimlik bilgilerini kıvrılmaya geçirmenin en güvenli yolu, bunları eklemeniz istenir. Bu, kullanıcı adını daha önce önerildiği gibi ( -u USERNAME) iletirken olur .

Ancak kullanıcı adını bu şekilde geçemezseniz ne olur? Örneğin, kullanıcı adının URL'nin bir parçası olması gerekebilir ve yalnızca şifre json yükünün bir parçası olabilir.

tl; dr: Bu durumda kıvrımı bu şekilde güvenle kullanabilirsiniz:

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

read komut satırından hem kullanıcı adı hem de parola ister ve gönderilen değerleri sonraki komutlarda referans olabilecek iki değişkente saklar ve son olarak ayarlanamaz.

Diğer çözümlerin neden ideal olmadığından bahsedeceğim.

Ortam değişkenleri neden güvensiz

  1. Ortam bir işlem tarafından dolaylı olarak kullanılabildiğinden, ortam değişkeninin içeriğinin erişim ve pozlama modu izlenemez (ps -eww)
  2. Genellikle uygulamalar tüm ortamı yakalar ve hata ayıklama veya izleme amacıyla günlüğe kaydeder (bazen bir uygulama çöktükten sonra diskteki günlük dosyalarında düz metin olarak)
  3. Çevre değişkenleri alt süreçlere aktarılır (bu nedenle en az ayrıcalık ilkesini ihlal eder)
  4. Onları korumak bir sorundur: yeni mühendisler orada olduklarını bilmezler ve zorlanmadığı ya da belgelenmedikleri için etraflarındaki gereksinimlerin farkında değildirler (örneğin, alt süreçlere geçirmemek).

Doğrudan komut satırında bir komuta yazmak neden güvensizdir Çünkü sırrınız, o ps -auxanda çalışan her işlem için gönderilen komutları listelediği için çalışan başka bir kullanıcı tarafından görünür hale gelir . Ayrıca secrte'ınız daha sonra bash tarihinde sona erer (kabuk sona erdiğinde).

Yerel bir dosyaya dahil etmek neden güvensizdir Dosyadaki katı POSIX erişim kısıtlaması bu senaryodaki riski azaltabilir. Ancak, hala dosya sisteminizdeki, beklemede şifrelenmemiş bir dosyadır.


2
Bu yöntem hala işlem listesinde parolayı gösterir gibi görünüyor?
Mark Ribau

4

Ben bash aynı ihtiyacı vardı (Ubuntu 16.04 LTS) ve cevaplarda verilen komutlar benim durumumda çalışamadı. Kullanmak zorunda kaldım:

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

Bağımsız -Fdeğişkenlerdeki çift ​​tırnak işaretleri yalnızca değişken kullanıyorsanız gereklidir, bu nedenle komut satırından ... -F 'username=myuser' ...iyi olur.

İlgili Güvenlik Bildirimi: Bay Mark Ribau'nun yorumlarda belirttiği gibi, bu komut işlem listesinde parolayı ($ PASS değişkeni, genişletilmiş) gösterir!


1
Bu hala süreç listesinde $ PASS değerini gösteriyor gibi görünüyor?
Mark Ribau

Evet, maalesef öyle.
Marco

1

Gnome anahtarlık uygulamasına sahip bir sistemdeyseniz, doğrudan şifreyi açığa çıkarmaktan kaçınan bir çözüm , anahtarlıktan şifreyi çıkarmak için gkeyring.py kullanmaktır :

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
NOT: Parola işlem listesinde görünür. (Ve eğer senaryonun bir parçası değilse tarih.)
Mark Ribau

1

Bu OP'nin istediğinden ÇOK daha fazla, ancak bu şifreleri güvenli bir şekilde geçirmek için en iyi sonuç olduğu için curl, bu çözümleri buraya arayanlar için buraya ekliyorum.


NOT: komut -siçin arg readPOSIX değildir ve bu nedenle her yerde kullanılamaz, bu nedenle aşağıda kullanılmayacaktır. Biz kullanacağız stty -echove stty echobunun yerine.

NOT: Aşağıdaki tüm bash değişkenleri bunun yerine bir işlev içindeyse ayar yerine yerel olarak bildirilebilir.

NOT: perloysa nedeniyle birçok şeyler için bir bağımlılık olmasının denedim tüm sistemlerde oldukça genel kullanıma rubyve pythonböylece kullanarak, değil perlburada. Bunu garanti ediyorsanız ruby/ pythonnerede yaptığınız varsa, perlkomutu eşdeğerleriyle değiştirebilirsiniz.

NOT: bashmacOS 10.14.4'te 3.2.57'de test edilmiştir . Diğer mermiler / kurulumlar için bazı küçük çeviriler gerekebilir.


Bir kullanıcıdan güvenli bir şekilde (yeniden kullanılabilir) bir parolanın kıvrılmasına geçmesini isteyin. Kıvrımı birden çok kez çağırmanız gerektiğinde özellikle kullanışlıdır.

echoDahili mermiler için modern mermiler için (üzerinden kontrol edin 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

Daha eski mermiler için, nerede echoolduğu gibi /bin/echo(işlem listesinde yankı ne olursa olsun):
BU SÜRÜM ŞİFREYİ TEKRAR KULLANAMAZ , bunun yerine aşağıya bakın.

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



Parolayı geçici olarak bir dosyaya depolamanız gerekiyorsa, temizlemeden önce birden çok komut için yeniden kullanmak için (kodu yeniden kullanmak için işlevleri kullandığınız ve kodu tekrarlamak istemediğiniz için değeri yankı yoluyla iletin). (Evet, bu formda farklı kütüphanelerdeki işlevler olmamak için biraz kıvrımlı; Onları göstermek için gereken minimum koda indirgeme çalıştım.)

Yankı yerleşik olduğunda (bu özellikle anlaşılır, çünkü yankı yerleşiktir, ancak bütünlük için sağlanmıştır):

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

Eko şöyle bir şey olduğunda /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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.