セッションID付きURLが Bot にインデックスされる等で、セッションID漏えい問題に対応したい

what

携帯サイトで、セッションID付きURLを利用して、セッションIDを引き回すと、セッションIDが漏えいするケースが多いため、セッションハイジャックにつながりやすいので、なるべくセッションIDを漏えいしにくい作りにしたい。
ちょっとググればたくさんこの話題は出てくるが、自分なりにまとめる。


結論

セッション付きURLを利用している限り、セッションIDの漏えいの可能性を0にすることは難しい。ただしセッションIDの漏えいとセッションハイジャックの可能性を下げることは可能なので、可能性を下げる努力をする。

一番良いのは、「ログインごとに新しいセッションIDを発行する」だと思う。
ただし、携帯サイトとPCサイトで同じセッションを利用している場合、PC側で「次回から入力を省略する」ということができなくなる。諸刃の剣ですなぁ・・・。


セッションIDが漏えいするケース

セッションID付きURLをGoogle-Botなどがインデックスして、検索結果に出てセッションIDが漏えいするケース

http://example.com/mobile?_session_id=aaed736ac56a13d24d8r40a50ea8cde4 (*1) というURLがGoogle-BotなどのBotにインデックスされると、 *1 のURLがGoogleなどの検索結果に出るので、複数人が同じセッションIDを持つ可能性があり、セッションハイジャックが成立してしまう可能性がある。


リファラで他のサイトにセッションIDが漏えいするケース

http://example.com/mobile?_session_id=aaed736ac56a13d24d8r40a50ea8cde4 というURLにいて、http://hogehoge.com/ というリンクがあり、アクセスした場合、リファラを出力していると、http://hogehoge.com/ のWebサーバログにセッションIDが残り、それを悪意のある人が見つけたら、セッションIDを悪用する可能性があり、セッションハイジャックしてしまう可能性がある。


セッションID付きURLをユーザーが他のユーザーへ送信してしまい、セッションIDが漏えいするケース

http://example.com/mobile?_session_id=aaed736ac56a13d24d8r40a50ea8cde4 というURLを友人にメールや赤外線などで送信してしまい、友人がアクセスすると、セッションIDが漏えいしてしまう。


セッションID付きURLをソーシャルブックマークやブログ、掲示板などに登録して、セッションIDが漏えいするケース

http://example.com/mobile?_session_id=aaed736ac56a13d24d8r40a50ea8cde4ソーシャルブックマークしたり、ブログや掲示板に登録したりすると、第三者にセッションIDが漏れ悪用される可能性がある。また、そこからBotがURLをインデックスして、検索結果に出てセッションIDが漏えいするケースにつながる。



4パターンほど書いたが、もっとあると思う。


セッションIDの漏えいの可能性を下げる対策

セッションID付きURLを利用している限り、セッションIDが漏えいする可能性を0にするには大変難しい。
しかし、出来るだけの対応はしたいので、セッションIDの漏えい、セッションハイジャックの確率を下げる方法をまとめてみる。


Botがサイトを訪問した際に、セッションID付きURLを発行しない

そのサイトに訪問してくる代表的なBotを探し出し、Botのアクセス時にセッションID付きURLを発行しなければ、Botが訪問時にセッションIDをインデックスすることはなくなる。



検索エンジンにセッションID付きURLの削除申請をする

Googleなどの検索結果にセッションID付きURLが出ている場合、そのURLを削除申請して、検索結果から消してしまう。GoogleGoogleウェブマスターツールから削除申請ができる。


セッションIDを悪用され、セッションハイジャックの可能性を下げる対策

漏えいする可能性は0にはできないので、悪用(セッションハイジャック)されることを考えて、セッションハイジャックの可能性を下げる。


携帯サイトであれば、ユーザーエージェントを確認して認証する

例えば、http://example.com/mobile?_session_id=aaed736ac56a13d24d8r40a50ea8cde4 (*2) というURLにはAさんのユーザ情報が保存されていて、Bさんが *2 を悪用して、携帯でサイトにアクセスしたときBさんはAさんに成りすませてしまう。

そこで、携帯が発行するユーザエージェントを使う。例えば、Aさんのユーザエージェントは「DoCoMo/2.0 N900i(c100;TB;W24H12)」で、Bさんのユーザエージェントは「KDDI-SA31 UP.Browser/6.2.0.7.3.129 (GUI) MMP/2.0」だとする。

そのセッションIDを利用する際は、ユーザエージェントが「DoCoMo/2.0 N900i(c100;TB;W24H12)」であるかどうかを確認すれば、Bさんの携帯ではアクセスできない。ただし、ユーザエージェントの偽装や、同じ携帯利用していた場合は効果はないが、友人にURLを送信してしまった、検索でたまたま出てきたなど、故意でないセッションハイジャックの可能性はぐっと下がると思う。


セッションIDの有効期限を短くする

http://example.com/mobile?_session_id=aaed736ac56a13d24d8r40a50ea8cde4 というURLが漏えいしても、aaed736ac56a13d24d8r40a50ea8cde4 というセッションIDが有効でなければ、他のセッションIDを発行する。そのため、セッションハイジャックされる可能性はぐっと下がる。

セッションファイル(もしくはDBにあるセッション情報)自体を削除する場合、すべてのセッションを削除すると、操作中のユーザが急にログアウト状態になってしまうため、すべてではなく、数日間以上使われていないセッションを削除するなどしたほうが良いと思う。


「セッションにIP情報を保存する」、「ログインごとに新しいセッションを発行する」

RailsによるアジャイルWebアプリケーション開発 第2版 P567より


「セッション固定攻撃の回避」


 誰かのセッションidがわかれば、そのidを使ってHTTPリクエストを作成することができます。Railsは、そのようなリクエストを受け取ると、そのリクエストが本物のユーザのものだと判断します。リクエストをしたユーザは、本物のユーザが実行できる操作をすべて許可されることになります。
 Railsはセキュアなハッシュ関数を使ってセッションidを生成するので、ユーザのセッションidが他のユーザによって推測されるための対策は十分になされているといえます。この方法で生成されるidは、実質的には乱数だとみなせる非常に大きな数です。ところが、ほとんどのセッションidを奪うのと同じ結果を得る方法が存在するのです。
 セッション固定攻撃では、攻撃者は、まずアプリケーションから有効なセッションidを何かしら取得します。そして第三者がそのセッションidを使ってアプリケーションにログインするように仕向けます。第三者がそのセッションを使ってアプリケーションにログインすれば、そのセッションidにアクセスできる攻撃者にとってもログインしたのと同様の状態になります。
 セッション固定攻撃の阻止には2つのテックにックが役に立ちます。まず、セションを作成したリクエストのIPアドレスをセッションデータ内に保持しておくことが有効な場合があります。こうすれば、IPアドレスが変化した時点でそのセッションを無効にすることにより攻撃を回避できます。ただし、この方法を使うと、ラップトップで移動先のさまざまなネットワークから接続する必要があるユーザや、自宅からPPPoE接続を使っていて割り当てられるIPアドレスの有効期限が切れるたびにアドレスが変化するユーザは、不都合を強いられることになります。
 もう1つの対策は、ユーザがログインするたびに新しいセッションを作成するようにするというものです。こうすれば、正当なユーザはアプリケーションを問題なく使い続けることができますが、攻撃者の手元には対応するセッションが存在しない無効なセッションidが残るだけです。

  • 「セッションにIP情報を保存する」

こちらについては、接続中にIPが変わるユーザや、移動が多いユーザには不都合が強いられてしまうので、そのようなユーザが見込まれるサイトには不向きですが、セキュアです。


  • 「ログインごとに新しいセッションを発行する」

こちらは、セッション情報を保持できないので、毎回ログインすることになります。「次回から入力を省略する」ということができなくなりますが、かなりセキュアになります。


PCサイトと携帯サイトがある場合、アプリケーションを分けて、セッション自体を分ける

http://example.com/mobile?_session_id=aaed736ac56a13d24d8r40a50ea8cde4 (*3) が携帯のアプリケーションのセッションであるとします。PCのGoogle検索で、*3 が発見されて、アクセスされると *3 のセッションIDは有効なので使えてしまします。しかし、PCと携帯のアプリケーション自体がちがければ、*3 でアクセスしても、そのセッションIDは無効ということになります。
 ただし、携帯から携帯、PCからPCのセッションIDは従来と変わらないです。携帯のセッションIDがGoogle-botに拾われ、PCで *3 をクリックして同じセッションがセットされるということはなくなります。



おまけ - キャリアごとのCookie対応について

au

http://www.au.kddi.com/ezfactory/tec/spec/cookie.html
基本的に全機種Cookie対応。
しかし、SSL(端末に保管) と 非SSL(EZサーバに保管) をまたぐと、クッキーを引き継げないため、工夫が必要である。
さらに、端末に保管できるのは「WAP2.0ブラウザ搭載端末のみ」である。WAP2.0ブラウザ搭載端末以外は、セッションID付きURLなどで対応する必要がある。


SoftBank

http://creation.mb.softbank.jp/web/web_doc.html の HTTP編から抜粋。
3GC 型端末では、Cookie を用いてstatefull なセッションを実現できる。
ただし、SSL と非SSL 間でCookie の引き継ぎができない。