web-dev-qa-db-ja.com

あるアプリから別のアプリにパスワードを安全に送信する方法は?

最初にこの質問/回答を参照してください: 別のプロセスからプロセスを呼び出す場合、標準入力パスワードの送信はENV変数の送信よりも安全ですか?

私はJava開発者であり、C#プロセスを内部から呼び出す必要があるアプリを構築しています。私の状況では、JavaアプリがこのC#を呼び出していますプログラム https://github.com/nddipiazza/SharepointOnlineCookieFetcher

これは、環境変数を介して、またはstdinを使用してパスワードを送信することが安全ではないことを確立しました。

このアプリにパスワードを提供するためのベストプラクティスは何ですか?

1

私の理解では、これはあなたの脅威モデルです。2つのプログラムがあり、一方は他方を実行します。最初のプログラムは、いくつかの秘密を2番目のプログラムに渡す必要があります。敵対者は、この秘密を記録、傍受、または変更できてはなりません。両方のプロセスは互いに信頼し、同じシステム上で実行されます。

答えは、実行可能ファイルが攻撃者によって書き込み可能かどうかによって異なります。特権システムパスに保持されている場合、または親実行可能ファイルと少なくとも同じレベルの整合性がある場合は、改ざんされていないことが信頼できると確信できます。両方のプロセスが信頼されている場合、2つのプロセス間でデータを送信する最も簡単な方法は、stdinなどのパイプです。親プロセスが作成でき、子によって共有されるメモリの領域である共有メモリを使用することもできます。これにより、パイプ経由よりも効率的な通信が可能になります。許可されていない当事者は、以下のことができない限り、通信の内容を傍受または変更することはできません。

  • 親または子の実行可能ファイルを直接変更します。
  • プログラムをだまして、間違った実行可能ファイルを実行させます。 PATHを悪用する。
  • プログラムと同じユーザーとして実行し、それらを危険にさらすことを可能にします。
  • 親または子のいずれかの環境(例:LD_PRELOAD)を変更します。

環境変数を使用しないことをお勧めします。この環境は秘密にされているわけではなく、多くの場合、他のユーザーはシステム上のさまざまなプロセスの環境を見ることができます。たとえばLinuxでは、/proc/<pid>/environファイルを読み取ることで、プロセスの環境を取得できます。

3
forest

フォレストの答えは世界的に正しいですが、インスタンス間の保護レベルを向上させることができる重要な方法については言及していません。

Windowsでは、CryptProtectMemory(およびCryptProtectData)を使用して、現在のユーザーにリンクされているキーでデータを暗号化できます(CryptProtectMemoryの場合、マシンを再起動するたびにキーが変更されます)。

これにより、システムに保護レイヤーを追加できます。CryptProtectMemory(CRYPTPROTECTMEMORY_SAME_LOGONフラグを指定)を使用して、自分と同じマシンと同じユーザーで実行しているプロセスで復号化キーへのアクセスを制限できます。

それはあなたと同じコンテキストで実行されているコードからあなたを保護しませんが、最終的にはそれからあなたを保護するものは何もありません。

編集:CryptProtectDataではなくCryptProtectMemoryを使用する必要があることを強調します。 CryptProtectDataは、ストレージにストリーミングされるデータを対象としています(したがって、別のWindowsセッションからまとめて取得して復号化する必要があります)。

1
Stephane