あまり知られていない携帯でセッションを使う場合の重要な問題

意図しないセッションジャックの可能性

最近「プロペ。」というサービスを公開しました
http://d.hatena.ne.jp/toytools/20080712
http://prope.in/

開発中に携帯サイトでセッションを使う際に、意識して対策しておかないとまずい点に気づきました。
ネットでもこういった方法について触れられていることが無いので、この問題に対する対策を行っている場合は意外と少ないのではないでしょうか




問題点は、専用の対策を行っていなければユーザーが意識せずにセッションジャックを行ってしまう可能性です

  1. ユーザー【A】がセッションID【1】がついたURLをブックマーク
  2. ユーザー【A】がしばらくサイトを使わないことでセッションID【1】がサーバー側で破棄される
  3. ユーザー【B】がログインした際に、セッションID【1】が付与される
    • サーバー側から見るとすでに破棄されたセッションIDなので新しいセッションIDとして認識される
  4. ユーザー【A】がブックマークからアクセスする

上記手順がふまれた場合に、ユーザー【A】はユーザー【B】としてログインされてしまうことになります


この状態が起こる条件は、(PHP、Javaなど言語を問わず)標準のセッションID生成機を使用しているすべてのサイトです。

PCのサイトではブックマーク内にセッションIDが含まれることはまずないので、こういった状態になるケースはありませんが、携帯サイトではアクセス数が多ければ普通に起こりえます



対策

対策は下記の方法により可能です
※他にも色々方法はあると思います
※セッション内にユーザーIDを保持してログイン管理を行っている場合を想定しています



セッションID・ログイン・ユーザーIDに関して以下の条件を設けます

  • ログインしていない場合のセッションIDは『[ランダムな数字の文字列]』
    • ※ 通常のセッションID生成機と同じ
    • ※ 他ユーザーとかぶらないように
  • ログインしている場合のセッションIDは『[USER_ID]--[ランダムな数字の文字列]』にする
    • ※ ログイン処理をした時点で発行しなおす


そして下記条件の場合に無効なログイン状態と判断します

  • セッション内に保持しているユーザーIDが存在しない(セッションの時間切れ等)
  • セッション内に保持しているユーザーIDと、セッションIDに含む[USER_ID]の部分の文字列が一致しない
  • セッションIDが『[ランダムな数字の文字列]』だが、セッション内に保持しているユーザーIDが存在する

上記の場合には無効なので、ログインしていない場合のセッションID『[ランダムな数字の文字列]』でセッションIDを発行しなおします


この方法により、ブックマークされるURLについているセッションIDは、他人のログイン情報に対して振られたセッションIDでないことが保障されます


最後に

セッションIDのユニーク性はかなり高いので、そうそうこういった事態がおきることは無いと思いますが、アクセス数がそれなりにあるサイトでは起こる可能性はゼロではありません
対策をしておいて損は無いと思います


またこの方法を用いることによって、セッションジャックの可能性自体かなり減らせるのでセキュリティをあげたいPCサイトにも有効な手法だと思います



追記:上記対策では未ログイン時のセッションのユニーク保障ができないので、
ログインしていない場合にもセッションを使うサイトではもうすこし、ごちゃごちゃやる必要がある(思いついたら書きます)


もしかして、これって常識だったりします...??