子プロセスにパスワードを渡す方法は?


18

(私のプログラムから開始された子プロセスに)コマンドラインでパスワードを渡すことは、安全ではないことが知られています(psコマンドで他のユーザーでも見ることができるため)。代わりに環境変数として渡すことはできますか?

それを渡すために他に何を使用できますか?(環境変数を除く)最も簡単な解決策はパイプを使用するようですが、この最も簡単な解決策は簡単ではありません。

Perlでプログラムします。


2
なぜ簡単ではないのですか?個別の/名前付きパイプである必要はありません。通常のstdin / outで十分です...どの言語でもあまり問題になりません。興味のあるプロセスでしか読めないことを確認できれば、それをプレーンな設定ファイルに入れることができます(見た目よりもずっと難しいです)。
frostschutz

1
子でexecを呼び出さない場合でも、何もすることなくパスワードのコピーが残っています。
ジェームズヤングマン

回答:


26

プロセスの引数はすべてのユーザーに表示されますが、環境は同じユーザーにのみ表示されます(少なくともLinuxでは、最新のすべてのUNIXバリアントで考えられます)。したがって、環境変数を介してパスワードを渡すことは安全です。誰かがあなたの環境変数を読むことができれば、彼らはあなたとしてプロセスを実行できるので、すでにゲームオーバーです。

環境の内容は間接的に漏洩するリスクがあります。たとえば、ps何かを調査するために実行し、公共の場所で機密環境変数を含む結果を誤ってコピー&ペーストした場合です。もう1つのリスクは、環境変数を必要としないプログラム(パスワードを必要とするプロセスの子を含む)に渡し、そのプログラムが環境変数を公開することです。二次漏洩のこれらのリスクがどれほど悪いかは、パスワードを使用したプロセスの実行内容(実行時間、サブプロセスの実行方法)によって異なります。

パイプなど、盗聴されるように設計されていないチャネルにパスワードを渡すことで、パスワードが誤って漏洩しないようにするのが簡単です。これは送信側で非常に簡単です。たとえば、シェル変数にパスワードがある場合、次のようにできます。

echo "$password" | theprogram

theprogram標準入力にパスワードが必要な場合。これはecho組み込みであるため安全です。引数はps出力で公開されるため、外部コマンドでは安全ではありません。同じ効果を達成する別の方法は、hereドキュメントを使用することです。

theprogram <<EOF
$password
EOF

パスワードを必要とする一部のプログラムは、特定のファイル記述子からパスワードを読み取るように指示できます。他の何かのために標準入力が必要な場合は、標準入力以外のファイル記述子を使用できます。たとえば、とgpg

get-encrypted-data | gpg --passphrase-fd 3 --decrypt … 3<<EOP >decrypted-data
$password
EOP

プログラムにファイル記述子から読み取るように指示できないが、ファイルから読み取るように指示できる場合は、 `/ dev / fd / 3などのファイル名を使用してファイル記述子から読み取るように指示できます。

theprogram --password-from-file=/dev/fd/3 3<<EOF
$password
EOF

ksh、bash、またはzshでは、プロセス置換によりこれをより簡潔に行うことができます。

theprogram --password-from-file=<(echo "$password")

Solaris 9以前で/usr/ucb/psは、setuid rootであったため、他のプロセスの環境変数を読み取って表示できました。これはSolaris 10で削除されたため、2005年以降のSolarisリリースには上記の「他のすべてのUnixバリアント」の回答が適用されます。
アランク

@alanc実際、最近では、Solaris <10は最新のものとは考えていません。Solaris 9はWindows XPとほとんど同じです!
ジル「SO-悪であるのをやめる」

ジル:私は今のSolaris 11は、私は完全に理解し、同意して、5年以上出て、残念ながらまだSolaris 8または9を実行し、いくつかの人々を知っていることを、現代のSolaris 10を考慮し、ハードの時間を持ってそこの日
alanc

10

引数または環境変数を介してパスワードを直接渡す代わりに

#!/bin/bash
#filename: passwd_receiver
echo "The password is: $1"

同じ引数または環境変数を使用してファイル名を渡します

#!/bin/bash
#filename: passwd_receiver
echo "The password is: $(< "$1")"

次に、アクセス許可で保護された通常のファイル(同じユーザーで実行されている他のプロセスからは保護されませんが)を渡すか、それ/dev/stdinパイプします(同じユーザーで実行されている他のプロセスから保護されます):

 echo PASSWORD | ./passwd_receiver /dev/stdin 

/dev/stdinここで使用する場合、パイプであることが不可欠です。端末の場合、同じユーザーの下で実行されている他のプロセスから読み取り可能です。

既に/dev/stdin別のものに使用する必要がある場合、それをサポートするシェルを使用している場合、プロセス置換を使用できます。これは、基本的にパイプの使用と同等です。

./passwd_receiver <(echo PASSWORD)

名前付きパイプ(FIFO)は同じように見えるかもしれませんが、インターセプト可能です。

これらのソリューションも完全に安全というわけではありませんが、多くのスワップを行うメモリに制約のあるシステムを使用していなければ、十分に近いかもしれません。

理想的には、これらのファイル(パイプもファイルです)を、スワップ不可としてmlock (2)でマークされたメモリに読み込みます。これは、gnupgなどのパスワード処理プログラムで一般的に行われます。

ノート:

  1. ファイル記述子番号を渡すことは、ファイル名を渡すのと同じように理論​​的にはファイルと同じですが、ファイル記述子番号ではなくファイル名を<()与えるため、ファイル名はより実用的です(そしてcoprocs は、これらのファイル記述子をこのコンテキストで使用できないようにするFD_CLOEXECとマークされたファイル記述子を与えます)。


  2. /proc/sys/kernel/yama/ptrace_scope設定されているLinuxシステムを使用している場合は0、同じユーザーの下で実行されている他のプロセスから自分自身を保護する方法はありません(ptraceを使用してプロセスにアタッチし、メモリを読み取ることができます)

  3. 異なる(root以外の)ユーザーの下で実行されているプロセスからパスワードを遠ざけるだけでよい場合、引数、環境変数、パイプ、およびアクセス許可で保護されたファイルはすべて機能します。


7

いいえ、環境変数も簡単に読み取れ、子プロセスにリークします。パイプを使用して渡します。


2
「環境変数...子プロセスへのリーク」これが、環境変数を使用する全体のポイントです。継承されていなければ役に立たないでしょう。「環境変数も簡単に読み取れます」、そうではありません。
パトリック

2
変数を読み取り、設定解除します。それは難しいことではありません。また、パイプについても同じ引数を使用できます。パイプが読み取られない場合、パイプは子プロセスに渡され、子プロセスはそれを読み取ってパスワードを取得できます。
パトリック

1
未設定の環境変数の文書化手段を@Patrick必ずしも場所から値をスクラブしていないps/proc、それを見ることができます。
zwol

1
一部のシステムでは、任意のプロセスの環境変数を読み取ることができますか?Linuxは他の人が所有するプロセスに対してそれを許可していないと思います。あなたが同じユーザーであるならptrace()、ターゲットだけでそのメモリを読むことができます。
ilkkachu

5
この答えは間違っています。他のユーザーは環境変数を読み取ることができません。
ジル 'SO-悪であるのをやめる'

1

他に適切なものがない場合は、Linux Key Retentionサービス(カーネルキーリング)を検討してください。

security / keys.txtから開始します。デフォルトのキーリングの1つは、親プロセスと子プロセスの間で複製できます。

これは最も簡単な解決策ではありませんが、そこにあり、維持され使用されているようです(昨年のAndroidのバグにも関係していました)。

私はその「政治的」ステータスについては知りませんが、同様のニーズがあり、Guileバインディングの作業を開始しました。既存のPerlサポートに遭遇したことはありません。

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