Friday, April 11, 2014

Heartbleed脆弱性と、その背後にあるWebアプリケーションアーキテクチャの一般的欠陥について

■Heartbleedのリスクと善後策

Heartbleedは、攻撃者が一定の条件を満たすOpenSSLが動作しているサーバの、任意位置のメモリを外部から読み出すことができてしまうという脆弱性です。具体的には、以下のようなリスクが想定されています。

  • 秘密鍵の漏洩による、偽サイトの出現(あるいは中間者攻撃)
  • 秘密鍵の漏洩により、(過去のものを含む)パケットキャプチャの解読
  • サーバの同一プロセスが行った処理に関連する(他のユーザーのパスワードやセッションキーを含む)データの漏洩

漏洩した秘密鍵を用いた攻撃には、ユーザーを偽サイトへ誘導できたり、パケットの経由点を管理しているなどの、経路上の要件が必要になります。他のユーザーのデータの漏洩については、経路上の要件は不要な一方、攻撃の実施に近いタイミングでサーバにアクセスしたユーザーのデータしか漏れない、という違いがあります。

どこまで対策を施すべきかは、攻撃を受けた可能性をどの程度と評価するか、個々の組織の判断によるところがあると思うのでコメントしませんが、以下のような対策が必要になる可能性があります。

  • 偽サイトの出現や中間者攻撃、これからのパケット解読を防ぐには、新しい秘密鍵/公開鍵ペアを使うサーバ証明書への更新と、現行のサーバ証明書のrevocation
  • 秘密鍵の漏洩によって過去のパケット解読が容易になることのないよう、Forward Secrecyを満たすようなサーバ設定
  • 他のユーザーのものを含むデータの漏洩については、セッション情報のリセットとパスワードの再設定のお願い

■Heartbleedの背景

Heartbleedのような問題は、そもそもなぜ発生するのでしょう。それは言うまでもなく、安全性の根拠をプログラムが正しく記述されることに求めているからです(つまり、プログラムにバグがあると脆弱性として発現する可能性があるから)。最小権限の原則が守られていない、と言い換えてもよいと思います。

Heartbleedにおいて他のユーザーのデータが漏洩するのは、一つのプロセスが複数のユーザーの通信を処理しているからです。ユーザーごとに(あるいは接続毎に)別個のプロセスを割り当てていれば、他のユーザーの通信内容が漏洩することは起こりえません。

秘密鍵の漏洩にしても、秘密鍵を必要とする処理(TLSのハンドシェイク中の一部処理に限られます)と、TLS Heartbeatの処理(ハンドシェイク中以外に限られます)を別個の権限の元で動作させていれば、発生しなかったと言えます(17:19修正)。

多くのOSのプロセス分離やファイルアクセス権の制御に見られるように、最小権限の原則に基づいたセキュリティは有効に機能することが知られています。

にもかかわらず、ウェブ関連のソフトウェアにおいては同原則を用いずに、安全性の根拠をプログラムにバグがない点に求めるという悪しき慣習が続いています。特に、機能別の権限分離はまだしも、アクセスユーザー別の権限分離については系統だった実施例が非常に少ないという印象をもっています。

たとえば、SQL Injectionに代表されるSQL関連の情報漏洩も、アクセス制御にRDBMSのアクセス制御機構を用いず、アプリケーションプログラム内のSQL(とそのエスケープ)が正しく記述されている点に、安全性の根拠を求めているが故に発生しているわけです注1

ウェブの黎明期においては、(小数のユーザが使用することが一般的だった)RDBMSの認証システムの要件と多数が使用するウェブの要件は異なるのでRDBMSの認証システムはウェブ向けには使用できない、というのは説得力のある言い訳でした。ですが、今やRDBMSの用途の多くがウェブアプリケーションのデータストアになっているはずです。にもかかわらず、RDBMS(あるいはその他のデータストア)のアクセス制御機構をウェブアプリケーションからのアクセス制御に使う、というのは一般的な手法になっていません。

同様の問題はウェブアプリケーションサーバにもあり、複数のユーザーのリクエストを単一のプロセスで処理する結果、情報漏洩が発生するケースが見受けられます注2

リバースプロキシ、アプリケーションサーバ、データストア、そういったウェブアプリケーションの各要素について、最小権限の原則に基づいた、アプリケーションにバグがあっても脆弱にならないようなアーキテクチャの構成技法と技術開発が求められているのではないでしょうか。


注1: 強制アクセス制御がうまく機能しないようなアクセスパターンも、もちろん存在します
注2: 卑近な例としては、ログインユーザーとして別のユーザの名前が表示されるとか

3 comments: