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が書き換わるので関数呼び出し側はセッションフィクセーション対策を簡単に施すことができます。ただし当然ですが既に何かを