セキュリティに関するブリーフィング

脅威のモデル化についての会話の続き

Michael Howard

MSDN Magazine 2009 年 5 月号で、セキュリティ初心者の若者 Paige と、説明するのにややうんざりしているセキュリティ担当者 Michael による「脅威のモデル化についての会話」という記事を執筆しました。今月は、その会話の続きを紹介します。

シーン 1

小さな給湯室、コーヒーポットの隣。

Paige: この前は、私の脅威モデルをよく見てもらったけれど、今度会ったら、セキュリティが確保された暗号化設計に関する問題点について説明してくれると言ってたわよね。今、説明してもらってもいいかしら。

Michael: とりあえず、コーヒーを入れてもいいかな?

返答を待たずに、Michael はコーヒーをなみなみと入れる。

Paige: ええ、どうぞ。

Michael: 君のアプリケーションについてもう一度教えてもらえるかい?

Paige: ユーザーが、サーバーにデータを格納できる製品よ。ユーザー用に確保したサーバーにデータを送り込む小さなクライアント コードがいくつかあるの。このコードが、Web サーバー経由でユーザーのファイルをバック エンドにアップロードするの。このファイルをすぐに参照できるように、SQL Server に格納されているファイルのメタデータと一緒にファイル システムに保存するのよ。最終的には、何十億ファイルも保存できるのよ。主な環境は、ドメインに参加するコンピューターとインターネットから接続してくるコンピューターの 2 つよ。

Michael: そうだったね、思い出したよ。コードをたくさん使っている、動作の速いアプリケーションだったね。よし、じゃあ、君の脅威モデルをもう一度見て、問題の箇所がどこにあるか考えよう。DFD、データ フロー ダイアグラムはあるかい?

2 人は Paige のデスクに向かう。Paige はスマート カードを使ってログオンし、SDL 脅威のモデル化ツールを読み込む。

Paige: これよ。

Michael はダイアグラムに目を通す。

Michael: これはレベル 1 のダイアグラムだね。コンテキスト ダイアグラムよりも 1 レベル詳細になっているのかな。

Paige: そうよ。レベル 2 のダイアグラムもあるけれど、まだそんなに詳しく見る必要はないと思うの。

Michael: そのとおりだよ、これで十分だ。この先、もっと細かく知る必要が出てきたら、レベル 2 のダイアグラムも見ることにしよう。

Paige: ちなみに、私たちはこのダイアグラムはもう DFD って呼んでいないの。

Michael: へえ、そうなんだ。じゃあ、何て呼んでいるんだい?

Paige: アプリケーション ダイアグラムよ。

Michael: 好きなように呼べばいいと思うよ。わかりやすい言い方にしたわけだね。じゃあ、ダイアグラムに戻ろう。ユーザーは、ファイルをサーバーにアップロードすることや、サーバーからダウンロードすることをクライアント アプリケーションに要求する。そしてサーバーは、そのデータを、SQL Server に保持されているファイルに関するいくつかのメタデータと共に、バック エンドのファイル システムに保存するんだね。

Paige: それも用途の 1 つよ。でも、おそらくそれが主なシナリオね。もちろん、管理者はアプリケーションをセットアップしたり、構成したり、監視したりする必要があるわ。管理ツールの役割はそれね。

Michael: じゃあ、その主なシナリオというのを見てみよう。

シーン 2

Michael は、アプリケーション ダイアグラムをじっと見つめている。

Michael: まず、この主要シナリオのそれぞれの要素を見てから、STRIDE の脅威について詳しく説明することにしよう。

Paige: STRIDE? 何のことだったかしら。

Michael: Spoofing (スプーフィング)、Tampering (改ざん)、Repudiation (否認)、Information Disclosure (情報漏えい)、Denial of Service (サービス拒否)、Elevation of Privilege (特権の昇格) のことだよ。

Michael は、何かを紙切れにすばやく書き始める。

Michael: この表を見て。

Paige: これって全部、脅威のモデル化ツールにあるわね。

Michael: そうだよ。ツールをどのように使えるかこの表で見せたかったんだ。ちなみに、脅威モデルが完全かつ正確であれば、SDL に準拠するために脅威のモデル化ツールを使用する必要はないからね。基本的に、それぞれの要素が特定の脅威の影響を受けやすいことが、この表でわかってもらえるかな。

Paige: ええ、わかったわ。だけど、何か忘れているんじゃない? いろんなアプリケーション要素の間にあるデータ フローがまったく見当たらないわ。

Michael: わかってるよ、だけどあえて省略したんだ。まだデータ フローに注目するつもりはないからね。データ フローについては、この間詳しく話したしね。

Paige: そうだったかしら?

Michael: うん。脅威モデルを見て。

Paige は SDL 脅威のモデル化ツールに目を通す。

Paige: 思い出したわ。SSL/TLS を使って、クライアント プロセスとサーバー プロセスの間のデータ フローの改ざんと情報漏えいの脅威を解決するっていう話ね。

Michael: そのとおりだよ。じゃあ、ここで質問だ。ユーザーからサーバーに送られてきて、サーバーのファイル システムに保存されるデータの機密は守られているかな?

Paige: この前も聞かれたわね。たぶん、そのはずよ。

Michael: 残念でした。

Paige: どういうこと? データは SSL/TLS を使って暗号化されているんだから、問題ないでしょう?

Michael: いや、違うんだ。SSL/TLS は、2.0 クライアントのプロセスと、3.0 サーバーのプロセスの 2 つのプロセスの間でデータがやり取りされるとき、そのデータの情報漏えいの脅威を緩和するんだ。でも、データがセキュリティ保護されたこのトンネルを抜けると、クリアな状態に戻るから、ファイル システムにはクリアな状態のデータが書き込まれることになるんだよ。

Paige: そうなのね。だけど、それのどこにリスクがあるの?

Michael: 考えてみて。

Paige: わからないわ。

Michael はため息をつく。

Michael: 君のアプリケーションのクライアントが、株式公開企業の従業員だとしよう。もうちょっと具体的にしようか。その従業員は株式公開企業の CFO で、この四半期の会計データを記録したスプレッドシートを保存するのに、君のアプリケーションを使用しているとしよう。保存されるデータは、企業が利益を発表する四半期の終わりまでは公開されない。さて、ハッカーが君のシステムに侵入して、そのデータを取得し、その企業の株を売買するのに利用するとしたら、これはインサイダー取引になるおそれがあるね。

Paige: あら、それはたいへんだわ。

Michael: 本当にたいへんなんだよ。きわめて深刻な事態だ。CFO も、この機密データを適切に管理していないということで、SOX 法に違反するおそれがあるね。

Paige: 「おそれがある」、ばっかりね。

Michael: そうだね。弁護士みたいかな。本題に戻ろう。これは君が考慮に入れている事態かな?

Paige: うーん、そうでもないわ。使用規約には、極度に機密性の高いデータにはこのサービスを使わないほうがよいって書かれてあると思うんだけど、とりあえず、続けるわ。「ええ、このシナリオについても考慮しているわ」って答えたことにしましょう。それで?

Michael: まず、企業を危機にさらしたのはこのシナリオのせいではないことを確実にするために、弁護士に相談することをお勧めするよ。弁護士に、「頑張ってみましょう」と言われたことにしよう。でも、君がバック エンドのデータを保護していることを確信している必要があるね。

Paige: つまり、サーバーのファイル システムのデータ ストア 5.0 にデータを保持することが情報漏えいにつながるから、その脅威を緩和する必要があるというわけね。これで合ってる?

Michael: そのとおりだよ。じゃあ、これをどうやって解決すればいいかな?

Paige: ACL を使うのはどうかしら。

Michael: どうしてアクセス制御リストなんだい?

Paige: データにアクセスできるユーザーを制限できるわ。

Michael: じゃあ、サーバー アプリケーションはどうやってデータを読み書きするんだい?

Paige: プロセスが一意 ID で実行されているとしましょう。それを FooID とするわね。有効なユーザーがファイルにアクセスできるのと同じように、FooID にもアクセスを許可する ACL をファイルに適用するわ。

Michael: それじゃあ駄目だよ。安全じゃない。

Paige: どうして?

Michael: 僕が攻撃者だったら、FooID でコードを実行してサーバーのプロセスに侵入して、それからそのサーバーで悪意のあるコードを実行できてしまうよ。ほら、僕のコードを FooID で実行して、データを盗めたよ。

Paige は落胆した様子を見せる。

Paige: うーん。

Michael: 暗号を使えばいいんだよ。

Paige: そうね! サーバーは暗号化された BLOB を読み書きするだけだから、攻撃者がサーバーに侵入しても、暗号を解読できない限りデータを取得できないわ。

活気づく Paige。

Michael: おもしろいのはここからだよ。この前は、暗号化に関するいくつかの問題点について、特にキーとの関連にからめて触れたね。

Paige: どういう意味?

Michael: わかった、じゃあ、データはどうやって暗号化するつもりだっけ?

Paige: ユーザーがクライアント側アプリケーションでパスワードを入力するでしょう。すると、クライアント側アプリケーションが、そのパスワードを使ってデータを暗号化して、暗号化した BLOB をネットワーク経由でサーバーに送信するの。サーバーでは、SQL Server にメタデータを書き込んでから、サーバーのファイル システムに暗号化された BLOB を書き込むわ。

Michael: メタデータには何が入っているの?

Paige: 所有者の ID、ファイル サイズ、ファイル名、データがファイル システムに書き込まれた時刻、最後にデータを読み取った時刻といったところかしら。こうした情報がファイル システムにも保持されているはわかっているけど、SQL Server データベースみたいに、この種のデータを格納するよう設計されたものを参照したほうがずっと速いと思うわ。

Michael: そうだね。メタデータに、ファイルに保持されたデータが含まれていなくて良かったよ。

Paige: どうして?

Michael: 2 つほど理由があるんだ。まず、メタデータにファイルのデータが含まれているということは、サーバー アプリケーションからクリアな状態のデータにアクセスできるということだよ。含まれていなければ、サーバーのプロセスはデータを取得するために暗号を解読する必要があるでしょう。

Paige: それで?

大きくも、落ち着いた声で Michael は答える。

Michael: 君のサーバー アプリケーションは暗号を解読するキーを知る必要があるから、君は、本当に恐ろしい、あらゆる種類のキー管理ゲームに巻き込まれるんだ。できるなら、こんなやっかいな問題からは逃れたいよね。複数のキーがあれば手際よく切り抜けることができるけど、今は説明したくないんだ。どうしてもそれを知りたいなら、マイクロソフトが EFS、つまり暗号化ファイル システムを使用してファイルを暗号化する方法について研究することだね。

Paige: EFS を使えるの?

Michael: 多分ね。クライアントにもよるけれど。クライアント側ではどんなプラットフォームがサポートされているの?

Paige: 今年の終わりには Windows 向け、その 2 ヶ月後には Linux 向けの製品を出すわ。

Michael: Solaris は?

Paige: Solaris って?

Michael はクスクス笑い、Paige の返答を無視する。

Michael: EFS には Windows アカウントが必要だから、EFS は使えない。だから、別のテクノロジを使ってデータを暗号化する必要があるよ。EFS か、DPAPI、つまりデータ保護 API を使えたらよかったんだけど。どちらも、基になる暗号化テクノロジが同じだから、ユーザーのパスワードから派生したキーを使って、データをシームレスに暗号化したり解読したりできるからね。じゃあ、他の方法について考えようか。

Paige: 暗号化ライブラリは使える?

Michael: もちろん使えるよ。むしろ、この間僕が聞いたアイデアよりずっと優れていると思うよ。

Paige: どんなアイデアだったの?

Michael: 暗号化アルゴリズムを独自に作成してもかまわないかとたずねてきた人がいたんだ。

Paige: やめたほうがいいって言ったのね。

Michael: もちろんだよ。他に何て言えばいいんだい? SDL ポリシーに完全に違反しているだけじゃなく、独自に作成した暗号化を使う可能性すら検討しないほうがよいこともはっきりと付け加えておいたよ。

Paige: じゃあ、どうすればいいの?

Michael: クライアント コードが C# だから、.NET の System.Security.Cryptography 名前空間を使えるよ。この名前空間は Mono で使えるから、Linux からも呼び出せるしね。試したことはないけれど、実験してみるといいよ。ライセンスに関する問題がないことを確実にするために、弁護士と話し合う必要もあるね。

Paige: ライセンスに関する問題って?

Michael: サードパーティのコードだからね。ライセンスによってどんな問題が起こるかはだれにもわからないんだ。

Paige: わかったわ。それで、ユーザーのパスワードでデータを暗号化して、BLOB を送信して...

Michael: ちょっと待った。ユーザーのパスワードを暗号化キーに使うんじゃなくて、暗号化キーをパスワードから派生するんだよ。パスワードは非常に推測しやすいからね。

Paige: どうやってキーを "派生" するの?

Michael は微笑む。

Michael: キー派生関数を使うんだ。

Paige: 賢い Michael さん。もう少しわかりやすく説明してもらえるかしら?

Michael: もちろん。salt と共に、.NET の Rfc2898DeriveBytes のような関数にキーを渡すんだ。salt というのは、特定の攻撃を実行しにくくする一意の数値のことだよ。これは反復回数を表していて、数十万回にはならないけど、だいたい数十回になるね。関数はパスワードを受け取って、salt を使ってそのパスワードを何千回も書き換えるんだ。これは、よく「パスワードの拡張」とも呼ばれるね。ふつう 1 秒もかからないこの操作の終わりに、数バイト受け取るから、このバイト列をキーとして使うことができるよ。こうしてキーを派生することで、キーを推測しにくくなるだけじゃなくて、攻撃者は反復回数の分調べる必要があるから、パスワードを高速に推測する攻撃も仕掛けにくくなるんだ。つまり、攻撃者がだいたい 1 秒間に 1,000,000 個のパスワードをテストできるとして、反復回数が 100,000 回だったら、1 秒間に 10 個しかパスワードをテストできなくなるんだ。すごいだろう。

Paige: とてもすごいわ。だから、高度暗号化標準を使って、その派生したキーでデータを暗号化するのね。

Michael: そうだよ。もちろん、行われるのはデータの暗号化だけだよ。整合性のチェックは行われないけど、それはとても簡単だからね。キーを別に派生して、それを使ってメッセージ認証コードを作成したら、メタデータと一緒に保存すればいいんだ。暗号化と整合性のチェックに同じキーは使わないでね。また別のキーを派生して使うんだ。

もうひとりのセキュリティ担当者の Adam が何かをつぶやきながら歩いてくる。

Adam: セキュリティの専門家の君は、いつもまず暗号化関連の問題を深く追究したがるね。だけど、攻撃者はぜい弱なリンクを狙うんじゃないかな。

Michael: そうだよ、セキュリティの専門家は、すぐに深く追究する傾向がある。君の告発のとおり、僕は有罪だよ。だけど、どうしても解決したいんだ。

Paige: えーっと、そうね。他には何かある?

Michael: そうだな、ユーザーがパスワードを忘れるというやっかいな問題もあるんだ。USB メモリ スティックか何かに、ユーザーがパスワードをバックアップする機会を与えたいんだ。そして、僕たちはユーザーのパスワードを知らないことや、もしもパスワードを忘れてしまったら、データは取り戻せないことに気付いてもらいたいね。

Paige: これで終わりかしら?

Michael: ひとまずはね。脅威モデルの大きくて重要なセクションだからね。セキュリティが確保されるアプリケーションを構築する際に必要なトレードオフに対する考え方をいくつか理解してもらえたならうれしいよ。

Paige: ええ、理解できたわ。ありがとう。

Michael Howard は、マイクロソフトのシニア セキュリティ プログラム マネージャーとして、セキュリティを向上させるためのプロセスの変更とベスト プラクティスに取り組んでいます。また、『Writing Secure Code for Windows Vista』(Microsoft Press、2007 年)、『The Security Development Lifecycle』(Microsoft Press、2006 年)、『Writing Secure Code プログラマのためのセキュリティ対策テクニック』(Microsoft Press、2004 年)、『19 Deadly Sins of Software Security』(McGraw-Hill Osborne Media、2005 年) などの、セキュリティに関する 5 冊の書籍を共同執筆しています。