(私のプログラムから開始された子プロセスに)コマンドラインでパスワードを渡すことは、安全ではないことが知られています(psコマンドで他のユーザーでも見ることができるため)。代わりに環境変数として渡すことはできますか?
それを渡すために他に何を使用できますか?(環境変数を除く)最も簡単な解決策はパイプを使用するようですが、この最も簡単な解決策は簡単ではありません。
Perlでプログラムします。
(私のプログラムから開始された子プロセスに)コマンドラインでパスワードを渡すことは、安全ではないことが知られています(psコマンドで他のユーザーでも見ることができるため)。代わりに環境変数として渡すことはできますか?
それを渡すために他に何を使用できますか?(環境変数を除く)最も簡単な解決策はパイプを使用するようですが、この最も簡単な解決策は簡単ではありません。
Perlでプログラムします。
回答:
プロセスの引数はすべてのユーザーに表示されますが、環境は同じユーザーにのみ表示されます(少なくとも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")
/usr/ucb/ps
は、setuid rootであったため、他のプロセスの環境変数を読み取って表示できました。これはSolaris 10で削除されたため、2005年以降のSolarisリリースには上記の「他のすべてのUnixバリアント」の回答が適用されます。
引数または環境変数を介してパスワードを直接渡す代わりに
#!/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などのパスワード処理プログラムで一般的に行われます。
ノート:
ファイル記述子番号を渡すことは、ファイル名を渡すのと同じように理論的にはファイルと同じですが、ファイル記述子番号ではなくファイル名を<()
与えるため、ファイル名はより実用的です(そしてcoproc
s は、これらのファイル記述子をこのコンテキストで使用できないようにするFD_CLOEXECとマークされたファイル記述子を与えます)。
に
/proc/sys/kernel/yama/ptrace_scope
設定されているLinuxシステムを使用している場合は0
、同じユーザーの下で実行されている他のプロセスから自分自身を保護する方法はありません(ptraceを使用してプロセスにアタッチし、メモリを読み取ることができます)
異なる(root以外の)ユーザーの下で実行されているプロセスからパスワードを遠ざけるだけでよい場合、引数、環境変数、パイプ、およびアクセス許可で保護されたファイルはすべて機能します。
いいえ、環境変数も簡単に読み取れ、子プロセスにリークします。パイプを使用して渡します。
ps
と/proc
、それを見ることができます。
ptrace()
、ターゲットだけでそのメモリを読むことができます。
他に適切なものがない場合は、Linux Key Retentionサービス(カーネルキーリング)を検討してください。
security / keys.txtから開始します。デフォルトのキーリングの1つは、親プロセスと子プロセスの間で複製できます。
これは最も簡単な解決策ではありませんが、そこにあり、維持され使用されているようです(昨年のAndroidのバグにも関係していました)。
私はその「政治的」ステータスについては知りませんが、同様のニーズがあり、Guileバインディングの作業を開始しました。既存のPerlサポートに遭遇したことはありません。