web-dev-qa-db-ja.com

ASP.NETでSecureStringを使用する利点はありますか?

私が正しく理解していれば、これはプレーンテキストをメモリに保存しないためです。これにより、アプリは、メモリ、ガベージヒープ、またはディスクにページングされたメモリに対する難解な攻撃から保護されます。 SecureStringにはアンマネージバイトが供給され、一度に1つのアンマネージバイトが消費されます。その後、文字列はメモリから消去されます。 (私が離れたら私を訂正してください!)

ASP.NETでは、シークレットはWebフォームに収集され、HTTPSでポストバックされます。ただし、Requestオブジェクトは、フォームからのすべてのリクエスト値を名前と値のペアに変換し、それらをコレクションに配置します。 Request ["TxtPassword"]-したがって、文字列を取得する前であっても、文字列はすでに安全にメモリに書き込まれていません。さらに悪いことに、コントロールを使用していた場合、安全でない表現では、TextBoxのプロパティに管理された文字列が多くなります。

このSecureStringで何かを行うには、アンマネージ文字列を受け取るAPIが必要です。そのため、ストアドプロシージャパラメータなどにセキュア文字列を使用できないようです。

私はこれを間違ってやっていますか、それともSecureStringを使用して、セキュリティで保護されていない文字列のコピーをマネージメモリにリークしないのはばか者の用事ですか?

OAuthまたはWindows認証に切り替えることはオプションではありません。

45
MatthewMartin

あなたが正しく推測したように、そして他の人がすでに述べたように、ASP.NETフォームから来るセキュリティに敏感なデータを保存するために SecureString を使用することはほとんど意味がありません。そのデータはプレーンテキストでメモリにすでに存在しているからです。

ただし、SecureStringの使用が推奨されるシナリオは他にもあります。これは、機密データがプログラム自体によって作成され、プログラムの操作が完了した後はメモリに残してはならないためです。たとえば、SharePointサイトをプログラムで作成したり、認証資格情報をあるシステムから別のシステムに転送したりします。

古き良き時代には、機密データの存続期間をできるだけ短くすることが容易でした。スタックに割り当てて、プログラムがそれを使用して完了するとすぐにクリアすることができます。

char secret[512];
generate_secret(secret, sizeof(secret));
do_something_with(secret);
memset(secret, 0, sizeof(secret));
// Secret data is now gone.

ただし、主に次の理由により、マネージ文字列ではこのようなアプローチは不可能です。

  • それらはスタックに割り当てられていません、
  • それらは不変であるため、クリアすることはできません。
  • それらは使い捨てではないので、GCがデータを解放する時間についての保証はありません。メモリの状態によっては、解放されない場合もあります。

SecureStringは、変更可能で使い捨てにすることでその問題を解決しようとします。これにより、次のように書くことができます。

using (SecureString secret = new SecureString()) {
    GenerateSecret(secret);
    secret.MakeReadOnly();
    DoSomethingWith(secret);
}
// Secret data is now gone.
29

SecureStringは、システム間の直接呼び出しにネットワーク資格情報を割り当てるのに最適です。資格情報がWeb経由で受信された場合、どこかにプレーンテキストであることがWebの分野で与えられていますが、標準の資格情報呼び出し(ftp、ディレクトリサービスなど)を介してその資格情報を送り返す必要がある場合、SecureStringを使用すると合格方法として傷つけません。文字列がプレーンテキストでサーバーシステムにすでに存在していることは正しいですが、少なくともシステム間のフットプリントを減らすことができます。このパスワードをローカルでのみ使用している場合は、SecureStringはおそらくそれほど必要ではないことに同意します。

ただし、優れたセキュリティ習慣は、実際には時間の無駄ではありません。

7
Joel Etherton

あなたはそれの基本を持っていると思います。 SecureStringは、クライアント側にいるという観点から設計されています。したがって、WPF/Winformsアプリ(およびSilverlightがそこにあるかどうかを思い出せない)の場合、サーバー側アプリの場合は、文字列を最初に処理しないため、それほど価値はありません。

6
Rangoric

安全なコードレビューを実行するときにSecureStringの使用不足にフラグを立てるのは、データがアプリケーションによって暗号化されて再利用される可能性がある場合のみです。

たとえば、Webサイトのバックエンドが、資格情報を必要とするサードパーティまたは別の内部リソースと通信する必要がある場合です。これらはハッシュできないため、リクエストを作成する必要がある場合はSecureStringを使用します(これもTLS経由である必要があります)。

もう1つの方法は、可能であれば Windows Data Protection API を使用することです。

SecureStringの目的は、コンテンツを可能な限り短時間メモリに保持することであることに注意してください。

2
Casey