セッションフィクセーション問題

ITpro の記事で Session Fixation 問題について書かれていたので PHP での対策例を書いておきます。
 
PHP ではこの問題を解決するために、session_regenerate_id() という関数が提供されています。

<?php
 
session_start();
 
$old = session_id();
session_regenerate_id();
$new = session_id();
 
echo “$old -> $new<br>”;
// 結果:
// d4aa3b6cfaedca70dc09262dfbf8c39e -> 53c031b85fe89e00d3b151eddfd91733

具体的な利用方法はこんな感じです。

<?php
 
session_start();
 
$algo = “sha256”;
 
// パスワードは生で保存せずハッシュで持つ(5.1.2 以前は hash() 関数を使えないため mhash() または md5() で代用する)
$password_hash = “d74ff0ee8da3b9806b18c877dbf29bbde50b5bd8e4dad7a3a725000feb82e8f1”; // hash($algo, “pass”);
$bAuthorized = !empty($_SESSION[‘authorized’]);
 
if(!$bAuthorized){
        if(empty($_GET[‘p’]) || hash($algo, $_GET[‘p’]) !== $password_hash){
                // ログインページ表示
?>
                未認証(session_id = <?=session_id()?>)<br>
                <form action=”” method=”GET”>
                        <input type=”password” name=”p”>
                        <input type=”submit” value=”ログイン”>
                </form>
 
<?php
                exit;
        }
        $bAuthorized = $_SESSION[‘authorized’] = true;
        // セッションフィクセーション対策(Session Fixation)
        session_regenerate_id(); // ログインが成功した段階でセッションID を更新垢
 
}
 
?>
認証済み(session_id = <?=session_id()?>)

このサンプルを実行すると、パスワードに “pass” という文字列を入れて認証すると session_id が書き換わるのを確認できます。
 
この関数を使うと、透過的にセッションIDが書き換わるので関数呼び出し側はセッションフィクセーション対策を簡単に施すことができます。ただし当然ですが既に何かを