topic: session-cookie (session / cookie / login / CSRF) / ch06 — Session セキュリティ (regenerate_id / 固定化) / 演習 02

📝 ドリル 02 — Session Fixation シナリオ — ログイン時に ID 再生成で防ぐ

問題

固定化攻撃のシナリオを 1 スクリプトで擬似化します。

シナリオ:

  1. 攻撃者から渡された ID ATTACKERFIXEDID で Session を開始 (採点用スタブで session_id() をこの値にセット)
  2. ユーザーがログイン処理を実行
  3. ログイン直後に session_regenerate_id(true) を呼ぶ
  4. ログイン後の Session ID が攻撃者の渡した固定 ID と 異なる ことを確認

出力仕様:

  • 「ログイン前の ID」と「ログイン後の ID」が同じか異なるかを判定
  • 異なれば "safe: regenerated"、同じなら "vulnerable: fixation" を 1 行出力

期待される出力:

safe: regenerated

(session_regenerate_id(true) を呼ばないと vulnerable: fixation になる)

採点

php scripts/grade.php topics/13-session-cookie/ch06-session-security/drill/02-session-fixation/

ヒント

// スタブで session_id('ATTACKERFIXEDID') がセットされている前提
$oldId = session_id();                    // ATTACKERFIXEDID
$_SESSION['user'] = ['name' => '太郎'];   // ログイン
@session_regenerate_id(true);             // ★ ここがポイント
$newId = session_id();

echo ($oldId !== $newId ? "safe: regenerated" : "vulnerable: fixation") . "\n";
▶ 3v4l で実行

ポイント

  • ログイン直後に必ず session_regenerate_id(true) を呼ぶ のが固定化攻撃の最小防御
  • true を渡し忘れると古い Session が残るので注意 (引数の名前は delete_old_session)
  • ログアウト時の session_destroy() と組み合わせて運用するのが定石

テストケース

期待される出力

safe: regenerated

📄 starter.php(雛形)

このコードから書き始めてください。

<?php

// 採点用スタブ: CLI で session_start() を安定動作させるための前処理
// 攻撃者から渡された固定 ID で Session を開始 (Fixation シナリオ)
error_reporting(E_ERROR);
ini_set('session.use_cookies', '0');
ini_set('session.use_only_cookies', '0');
$tmpDir = sys_get_temp_dir() . '/dojo_l13_' . getmypid();
@mkdir($tmpDir, 0700, true);
session_save_path($tmpDir);
session_id('ATTACKERFIXEDID');
@session_start();

// TODO: 現在の session_id() を $oldId に保存する
// TODO: $_SESSION['user'] にログイン情報を入れる (例: ['name' => '太郎'])
// TODO: @session_regenerate_id(true) を呼んで ID を作り直す
// TODO: 新しい session_id() を $newId に保存する
// TODO: $oldId !== $newId なら "safe: regenerated"、
//       そうでなければ "vulnerable: fixation" を出力
✅ 解答例を見る(自分で解いてから)
<?php

// 採点用スタブ: CLI で session_start() を安定動作させるための前処理
// 攻撃者から渡された固定 ID で Session を開始 (Fixation シナリオ)
error_reporting(E_ERROR);
ini_set('session.use_cookies', '0');
ini_set('session.use_only_cookies', '0');
$tmpDir = sys_get_temp_dir() . '/dojo_l13_' . getmypid();
@mkdir($tmpDir, 0700, true);
session_save_path($tmpDir);
session_id('ATTACKERFIXEDID');
@session_start();

$oldId = session_id();

// ログイン処理
$_SESSION['user'] = ['name' => '太郎'];

// ★ ログイン直後に必ず ID を再生成して固定化攻撃を無効化する
@session_regenerate_id(true);
$newId = session_id();

echo ($oldId !== $newId ? "safe: regenerated" : "vulnerable: fixation") . "\n";