2012年12月12日

セッション管理ポリシーとフィクセーション

徳丸浩氏と大垣靖男氏の間でセッションフィクセーションに関するやり取りが有ったが、恐らくこれはセッション管理ポリシーの食い違いと思えたのでまとめてみる。
http://tumblr.tokumaru.org/post/37676352092/session-adoption-and-session-fixation
http://blog.ohgaki.net/session-adoption-and-session-fixation-and-session-hijack

自分の理解では、
徳丸氏は「権限昇格時のセッションIDの再生成でセッションフィクセーションによるハイジャックは排除できる」
大垣氏は「アダプション対策はハイジャック対策に必須」
と主張されているように見える。恐らくこれはセッションID発行に関する管理ポリシーの違いに起因する。

共通の前提として、攻撃者はサブドメインへのクッキーなど、サーバー内の実装や脆弱性に依存しない方法でフィクセーションを起こせるものとして、フィクセーションが不正な権限昇格に繋がるかを考える。
バックエンドサーバー・DBへの不正アクセスやXSSやCSRFなど、フィクセーション以外のサービス側の問題は考慮しない。また、誤った乱数実装や善良なユーザーからのセッションIDの漏洩によるハイジャックも別件として考慮しない。セッションID管理はCookieベースとする。


徳丸氏の前提としたポリシーは恐らく、
・全く権限のない匿名のユーザにもセッションIDを発行する
・権限昇格時にセッションIDを再生成する
攻撃者は容易にセッションIDを生成出来るので(Torなどで匿名アクセスしてCookieを貰えばいい)フィクセーションは起こせるが、昇格した権限は新しいIDに紐つくため、被害ユーザーはCookie重複によるログイン不能などDoSに晒されるものの、攻撃者が権限昇格することはない。なお、Cookieのキーもランダム化するなどでDoSの軽減は可能である。
再生成しないと、フィクセーションで権限昇格可能な深刻な脆弱性になる。

大垣氏の前提としたポリシーは恐らく、
・権限取得時に有効なセッションIDを発行する(=信頼できない攻撃者はセッションIDを取得できない)
・権限の変更や昇格の際は再生成し、破棄時にはセッションIDも無効化する(=セッションIDの有無と権限の有無が一致する)
と推測した。
サービスにログインできない攻撃者はフィクセーションを起こそうとしても、アダプション対策を回避できる有効なセッションIDを知らないので、フィクセーションは成功しない。逆に言えば、アダプション可能だった場合セッション管理フレームワークの深刻な脆弱性になる。

なお、どちらのポリシーでもログイン済みユーザーはフィクセーションは起こせるので、ログイン可能なユーザーに攻撃者がいた場合に備えて、ユーザーに”サーバーが認識しているユーザー名”を確認してもらう必要がなる。

このように前提が異なると仮定すると、両者の言っていることはどちらもそれぞれの前提の元で正しいように思われる。

前者のポリシーでは、セッションIDの有無は重要ではないので、アダプション対策の意義は攻撃検出などに限られる。一方、後者のポリシーではログイン状態の判定を、セッションIDの有無に依存しているため、セッションIDが捏造されたものか判定するアダプション対策は重要になる。

後者のポリシーでも権限昇格の際はセッションIDを再生成するか、権限を一時的なものとして(suではなくsudoのように)その都度PINを入力する方式にする必要がある。例えば、ログインユーザーが特権ユーザーに昇格する場合など、もし同一のセッションIDのまま権限昇格が可能なら、弱い権限を持つ攻撃者は弱い権限のセッションIDを取得して、強い権限をもつユーザーにフィクセーションを仕掛けることで権限昇格可能なハイジャックに相当する。


結局、regenerationは権限昇格時に必須だが、ログイン状態と有効なセッションIDの有無を対応付ける実装をする場合にはアダプション対策"も"必須、ということと思われる。

個人的にCookieとログイン状態の暗黙の対応関係に依存するのはプログラミング的には筋が悪いと感じられる。しかし、セッション管理と広告などを目的としたユーザー追跡が完全に分離されるので、ユーザー視点ではプライバシー上後者の方が好ましい。もっとも、その場合別の追跡クッキーが発行されるのでそちらはブロックする必要があるだろうが。

自分の理解した範囲の結論としては、どちらのポリシーにせよ、IDの再生成をすれば権限昇格タイプのセッションハイジャックは回避できる。フィクセーションは可能なら潰すべきだが、サブドメインベースの共用ホスティングを使うユーザーもいるので、プログラマーのレベルでは完全に潰すことは難しく、ログイン出来る攻撃者からのフィクセーションが成功しても致命的な問題が起こらないように、ユーザーにユーザー名を常時表示するなど、十分注意して実装しなければならない。アダプション対策は後者のポリシーで、セッションIDの有無に依存する実装の場合にのみ注意すればよい。

勝手な推測でセッション管理ポリシーを推定したが、これ以外のポリシーでは、アダプション対策でにフィクセーションによるハイジャックを回避できるシナリオが想定できなかった。
posted by ko-zu at 06:30| Comment(2) | TrackBack(0) | セキュリティ | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
『信頼できない攻撃者はセッションIDを取得できない』<この状況を作るのは、不可能ではないものの容易ではありません。と言うか、面倒です。

一般的な認証の実装では、まずsession_startして、セッション変数の中に有効なログインIDが保存されていることを確認します。大垣さんのご著書でもその方針で実装されています。
『信頼できない攻撃者はセッションIDを取得できない』ようにするためには、session_startするまえに、PHPSESSIDという名前のCookieが来ているかどうかを確認し、来ている時のみsession_startする必要があります。

すると、これ自身が「開発者によるセッションフィクセイション対策」(ただしこれだけでは完全ではない)をしていることになり、大垣さんの言われる「セッションアダプション対策すればセッションフィクセイションは防げる」ということにはなりません。
Posted by 徳丸浩 at 2012年12月13日 11:10
おっしゃるとおり、この想定はかなり面倒ですが、大垣氏の主張が「アダプション対策はハイジャック対策に必須」と限定すると、その面倒な実装"をも"想定して書かれている様に思われました。

大垣氏のエントリの内容では、「セッションアダプション対策すればセッションフィクセイションは(完全に)防げる」とまでは言っていないように思えました。フィクセーション対策は別途、昇格時に再生成が必要とエントリや周辺でも書かれていましたので。
ですので、「(ライブラリ側が)セッションアダプション対策すれば(セッションIDの有無でログイン判定するような拙い実装をするプログラマがいても)セッションフィクセイションは(ある程度)防げる」ということなのではないかと思いました。

大垣氏がアダプションの修正にこだわられる理由は、セッションCookieの有無(とそれが有効かどうか)でログイン判定するようなプログラムを書くのは勧められれない、というのは当然でも、PHP側が受け取ったCookieの有効無効を正しく判定しないのは、(PHP利用者はPHP側で判定してくれているだろうと思っているので、)ユーザの想定と実装が違うという意味でよくないため、ということと思います。
Posted by ko-zu at 2012年12月13日 11:53
コメントを書く
お名前: [必須入力]

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。

この記事へのトラックバック
×

この広告は90日以上新しい記事の投稿がないブログに表示されております。