ユーザー名とパスワードでcURLを使用していますか?


468

ユーザー名/パスワードが必要なURLにアクセスしたい。curlでアクセスしてみます。今私は次のようなことをしています:

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

エラーが発生します。上記のコマンドでユーザー名とパスワードを指定する必要があると思います。

どうやってやるの?

回答:


695

-uフラグを使用してユーザー名を含めると、curlはパスワードを要求します。

curl -u username http://example.com

コマンドにパスワードを含めることもできますが、その場合、パスワードはbash履歴に表示されます。

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

109
コンソールからこれを行うと、パスワードが履歴に残ることに注意してください...間違っています。-u userだけを指定すると、CURLは非エコーモードでパスワードを要求します。
クリスティアン・ヴラビー2013

25
@CristianVrabie技術的には正しいが、プロンプトを許可しない自動スクリプトから実行している場合は正しくない。その問題の解決策に興味があるでしょう。
Ligemer

26
@OmarOthmanスクリプトからcurlを実行している場合、認証情報は(明らかに)履歴に残りませんが、ps(1)に表示されます。修正:print -- '-u username:password' > somewhere && curl -K somewhere http://...
2014年

7
@Jay環境変数は、コマンドの実行前に評価されます。パスワードは引き続きps出力に表示されます。
RobertVažan16年

8
重要なことではありませんが、私の答え(stackoverflow.com/a/27894407/758174すなわちを使用--netrc-file)の方が安全だと思います。履歴、ps、スクリプトなどからパスワードを保護します。これは、すべてのスクリプトで、およびのすべての認証済み使用法で使用する唯一の形式ですcurl
Pierre D

255

それは安全です:

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ケープハート

8
これは間違いなく受け入れられる答えになるはずです。コマンドラインでのパスワードは恐ろしい習慣です。(そしてこれは広く知られている事実です。)
ELLIOTTCABLE

6
フラグを使用する-K <file>--config <file>、ファイルまたは標準入力を介してカールフラグを受け取ることもできます。(警告:と混同すべきでない-k--insecure!)
Rufflewind

2
このcurlメソッドは、資格情報を履歴とプロセスステータスから除外しますが、ユーザー名とパスワードをクリアテキストでmy-password-fileに残し、別の攻撃ベクトルを作成します-履歴ファイルに情報があるよりも悪い:たとえば、bashは、アクセス許可を自動的に制限します履歴ファイルの。ユーザー名/パスワードを設定するスクリプトなどで環境変数を使用する場合も、同様の問題が発生します。スクリプトが安全でない場合、資格情報も安全ではありません。
Steven the Easily

5
私は反対する@SteventheEasilyAmused、それがクリアテキストを使用して多くの方が良いです.netrcので、唯一、適切に厳格なアクセス権を持つファイルを、あなたのみましょう他のメカニズム(例えば、コマンドライン引数)よりも、ユーザーはそれを読むことができ、他のユーザーが情報をお読みください。
ケンウィリアムズ

77

または同じことだが構文が異なる

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

1
より多くの状況で使用できるので、私はその構文を使用します。cURLもwGetもないWindows cmdのように、を使用しstart "" "http://username:password@api.somesite.com/test/blah?something=123"ます。どこからでも起動できます。それはまた、FTPログインに適用され; D
m3nda

9
変な文字を使用するには、ユーザー名とパスワードをURLエンコードする必要があります
ダイアデリック

2
この例のように盗聴しやすいため、ほとんどの人はURLでパスワード(またはユーザー名)を送信しないことを知っています。とは言うものの; 私はそれをお勧めしませんが、あなたが何をしているのか知っているときだけ使用してください。
LosManos

1
これはsuuuuuperの古風なものであり、使用しないでください。これはFTPの日からです:o
Qix-モニカは、

2
残念ながら、これによりプロセスリストにパスワードが表示されたままになります。
Mark Ribau

63

次のように書くだけでユーザー名を送信することもできます。

curl -u USERNAME http://server.example

Curlはパスワードを要求し、パスワードは画面に表示されません(またはコマンドをコピー/貼り付けする必要がある場合)。


28

スクリプトでパスワードを安全に渡す(つまり、ps auxfまたはログでパスワードが表示されないようにする)には、-K-フラグ(標準入力から設定を読み取る)とヒアドキュメントを使用します。

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

2
--configオプションへの参照をありがとう(-K)...おそらくより良い解決策は、「-user user:password」をファイルに入れて、単純-K the fileにすべてのスクリプトにコピーではなくパスワードのコピーを1つだけ持つことです。 。単一のファイルを保護する方がはるかに簡単です。
Chris Cogdon、2017年

1
同様のオプションcat "${password_filepath}" | sed -e "s/^/-u ${username}:/" | curl --url "${url}" -K-。パスワードのみがファイルにあります。-K-古いmacOS bash、YMMVのURLの前に置く必要がありました。
Mark Ribau

12

通常、CURLコマンドは次のように参照します

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

パスワードがない場合、またはコマンドプロンプトをスキップしてパスワードを要求する場合は、パスワードセクションを空白のままにします。

すなわち curl https://example.com\?param\=ParamValue -u USERNAME:


1
注:パスワードはシェルの履歴とプロセスリストに表示されます。
Mark Ribau

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

1
注:パスワードはシェルの履歴とプロセスリストに表示されます。
Mark Ribau

8

パスワードをポップアップさせないようにするには.bash_history

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

6
この場合、パスワードはプロセスリストに残ります。たとえばps auxw |grep curl、適切なタイミングで誰かがパスワードを見ることができます。同様に、パスワードを実行するとログに記録されますsudo
Adam Katz '19

1
この方法では、パスワードはファイル(.password-file)に存在し、.bash履歴よりも安全でない可能性があります。これの良い点は、それがパスワードだけであるということです-URLとユーザー名は.password-fileでリークされません。
Steven簡単に面白がっている


6

他の回答は、私が読んだ内容に基づいて、ユーザー名とパスワードを指定することをnetrcに提案しています。構文の詳細は次のとおりです。

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

他の回答と同様に、この質問に関してセキュリティに注意を払う必要があることを強調したいと思います。

私は専門家ではありませんが、これらのリンクは洞察に満ちています:

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

要約する:

使用するプロトコルの暗号化されたバージョンを(HTTPS HTTP VS)(FTP対FTPSは)避けネットワーク漏れを助けることができます。

netrcの使用をすると、コマンドラインリークを回避できます。

さらに一歩進むには、gpgを使用してnetrcファイルを暗号化することもできるようです

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を呼び出して、http渡すWWW_AuthenticationBase64では、の値をコード化してヘッダをAPI_USERしてAPI_HASH-Lkただ、HTTPリダイレクト30Xに従うことをして(すなわち、SSLエラーを無視)の取り扱い安全でないTLSを使用するようにカールを伝えます。double --は、コマンドラインフラグの処理を停止するためのbash構文シュガーです。さらに、-b cookies.txtおよび-c cookies.txtフラグはでクッキーを扱う-bクッキーを送信し、-cローカルに保存する処理します。

マニュアルには、認証方法のがさらにあります。


1
「-Lk」を使用すると中間者攻撃(MITM)が発生する可能性があるため、そのオプションには注意してください。
GuyPaddock 2017

4
これは機能しません... bashはこれらの変数を展開するので、展開はプロセスリストに表示されます。
クリスコグドン2017年


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 コマンドラインからユーザー名とパスワードの両方を要求し、送信された値を2つの変数に格納します。これらの変数は、後続のコマンドで参照でき、最後に設定を解除できます。

他のソリューションが理想的でない理由について詳しく説明します。

環境変数が安全でない理由

  1. 環境変数の内容のアクセスと公開モードは追跡できません(ps -eww)。その環境はプロセスで暗黙的に使用できるためです。
  2. 多くの場合、アプリは環境全体を取得し、デバッグまたは監視の目的で環境をログに記録します(特に、アプリがクラッシュした後、ディスク上のプレーンテキストのログファイルに記録される場合があります)。
  3. 環境変数は子プロセスに渡されます(したがって、最小特権の原則に違反します)
  4. それらを維持することは問題です:新しいエンジニアは彼らがそこにいることを知りませんし、強制も文書化もされていないので、それらの周りの要件を認識していません。

コマンドラインでコマンドに直接入力するのは安全ではないのはなぜですか 。シークレットは、ps -aux現在実行中のプロセスごとに送信されたコマンドを一覧表示するため、実行中の他のユーザーに表示されてしまいます。また、あなたのセクレトは(シェルが終了すると)bash履歴に残ることになります。

ローカルファイルに含めることが安全ではない理由ファイル に対する厳格なPOSIXアクセス制限により、このシナリオのリスクを軽減できます。ただし、それはまだファイルシステム上のファイルであり、保存時には暗号化されません。


2
このメソッドはまだプロセスリストにパスワードを表示するようです?
Mark Ribau

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' ...も問題ありません。

関連するセキュリティ通知:Mark Ribau氏がコメントで指摘しているように、このコマンドはプロセスリストにパスワード(展開された$ PASS変数)を表示します!


1
これはまだプロセスリストの$ PASSの値を示しているように見えますか?
Mark Ribau

はい、残念ながらそうです。
Marco、

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
注:パスワードはプロセスリストに表示されます。(これがスクリプトの一部でない場合は、履歴です。)
Mark Ribau

1

これはOPが要求するよりもはるかに大きいですが、これはパスワードを安全にに渡すための最高の結果であるためcurl、ここに到着してそれを検索している他の人のために、これらのソリューションをここに追加します。


注:コマンドの-s引数readはPOSIXではないため、どこでも使用できるわけではないため、以下では使用しません。使用stty -echoしますstty echo代わりにます。

注:以下のすべてのbash変数は、設定を解除するのではなく、関数内でローカルとして宣言できます。

注意: perl私は、それは多くのものの依存であることに起因するしようとしたのに対しきたすべてのシステムで利用でき、かなり一般的であるrubypythonされないので、使用してperlここに。保証できる場合ruby/ pythonこれを行う場所は、perlコマンドを同等のもので。

注:bashmacOS 10.14.4の3.2.57でテストされています。他のシェル/インストールでは、いくつかの小さな変換が必要になる場合があります。


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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.