セキュリティセンターTOP > セキュアプログラミング講座 > Webアプリケーション編 > セッション対策 > セッション乗っ取り:#2 セッションID強度を高める

第4章 セッション対策
セッション乗っ取り:#2 セッションID強度を高める

セッションID という値の必要条件

セッションIDは、Webページの遷移を維持し、必要な手続きを経て情報を閲覧あるいは、登録・変更・削除を行うための重要な値である。そのため、容易に推測されない(破られない)強度の高い値にすることが重要である。

セッションID強度
図4-5: セッションID 強度

(1) 公共に知られていそうなIDは使用しない

例えば、会員番号やユーザID等、公共に知られていそうな値では容易に推測が可能であるので、使用すべきではない。セッションIDは、人間が覚えておく必要は無いので、見た目が無意味な値であっても、まったく問題はない。

(2) ランダムなIDを使用する

00001、00002...等の規則性や連続性のある値は、推測が容易であるのでランダムなIDを使用する。例えば、ユーザIDや時刻等の情報と擬似乱数とを混ぜ合わせた文字列に対してハッシュ関数を使用することで、ランダムなIDが生成されるようになる。
ただし、擬似乱数生成関数やハッシュ関数を自前で作成することは避けるべきである。

(3) 桁数と文字種を多くする

桁数が短く、文字種の少ない場合、ブルートフォースアタックで破られてしまうおそれがある。これを防ぐためには、使用する文字種、桁数をなるべく多くし、総当りするパターンを増やすことである。例えば、英数小文字大文字で20桁の値を考えた場合、組み合わせとしては「(26+26+10)^20」通りとなる。

(4) ユニークなセッションIDを発行する

セッションIDは、どのような場合でも、常にユニークな値を発行するようにする。

  • Webアプリケーションを利用する他ユーザに対して発行する場合
    同じセッションIDを発行してしまうと「なりすまし」のおそれがある。
  • 同一ユーザに対して発行する場合
    セッションの度に同じIDを発行することがないようにする。これは一度セッションIDが盗まれてしまうと、Webアプリケーション内での「なりすまし」が永続的に可能となってしまうからである。

処理系がもつセッションID生成ロジックの利用

自前のセッションID生成ロジックを作成する場合は、上記を考慮に入れて作成するべきであるが、ASP、Java Servlet、ASP、PHP等のWebアプリケーションエンジンは、比較的推定が困難になるランダムな値によるセッションIDを発行するので、それを利用する方法もある。

上記「(2) ランダムなIDを使用する」に記述したように擬似乱数関数やハッシュ関数を使用することは自前のランダム関数を使用するよりも安全である。しかし、擬似乱数関数やハッシュ関数に依存しきってしまっても問題がある。それは、それらの関数のアルゴリズムが解明されてしまうとセッションIDが推測可能となってしまうからである。確実に実施すべきことは、セッションIDの桁数と文字種を多くし、推測を困難にすることである。

Webアプリケーションエンジン(Java Servlet、ASP、PHP)が実装しているセッションID の使用方法を以下に記述する。

(1) Java Servlet

Java Servletでは、HttpServletRequestのgetSessionメソッドを実行する。
getSessionメソッドでは、セッションIDが設定されていない場合にはセッションIDを発行し、既に設定済みの場合にはそのIDを使用する。

HttpSession session = request.getSession(true);

発行されたセッションIDはCookie(JSESSIONID)に保存され、次回以降、このクッキーを使用する。

(2) ASP

ASPでは、ページへの最初のアクセスの時にASPエンジンが、セッションIDを発行する。発行されたセッションIDはCookie(ASPSESSIONID)に保存され、次回以降、このクッキーを使用する。

(3) PHP

PHPでは、session_startを実行する。session_startでは、セッションIDが設定されていない場合にはセッションIDを発行し、既に設定済みの場合にはそのIDを使用する。

session_start();

発行されたセッションIDはCookie(PHPSESSID)に保存され、次回以降、このCookie を使用する。