topic: session-cookie (session / cookie / login / CSRF) / ch06
ch06 — Session セキュリティ (regenerate_id / 固定化)
学習目標
- Session Fixation (固定化攻撃) が何を狙うかを 1 行で言える
- ログイン時に
session_regenerate_id(true)を呼んで Session ID を作り直す 意味を説明できる - 新旧 Session ID が 異なる ことをコードで確認できる
所要時間
スライド 5 分 + ドリル 2 問 = 25 分
ドリル
| no | 内容 |
|---|---|
| 01 | ログイン時に session_regenerate_id(true) を呼び、新旧 ID が違うことを "changed: yes" の形で出力 |
| 02 | 固定化攻撃のシナリオを擬似化 — 既知の ID で開始 → ログイン → ID が変わったか検証 |
本物のセッション動作で確認したい場合
cd topics/13-session-cookie/ch06-session-security/drill/01-regenerate-id/
php -S localhost:8000 answer.php
ブラウザの開発者ツール (Application → Cookies → PHPSESSID) を見ながらリロードし、ログイン処理を呼んだ瞬間に Session ID が変わることを確認。
演習問題の詳細
この章の演習問題の内容を読めます。実際に手元で解くには教材リポジトリを clone してください。
ドリル 01 — `session_regenerate_id(true)` で ID を作り直す
問題
ログイン時の Session ID 再生成を再現してください。
session_start()直後の Session ID (採点用スタブでTESTSESSIONID) を変数に保存session_regenerate_id(true)を呼ぶ- 再取得した Session ID と比較し、異なれば
"changed: yes"、同じなら"changed: no"を 1 行出力
期待される出力:
changed: yes
採点
php scripts/grade.php topics/13-session-cookie/ch06-session-security/drill/01-regenerate-id/
ヒント
$oldId = session_id();
@session_regenerate_id(true);
$newId = session_id();
echo ($oldId !== $newId ? "changed: yes" : "changed: no") . "\n";本物のセッション動作で確認したい場合
cd topics/13-session-cookie/ch06-session-security/drill/01-regenerate-id/
php -S localhost:8000 answer.php
ブラウザの開発者ツールで PHPSESSID を見ながらリロード、再生成のタイミングで Cookie 値が変わることを確認。
ドリル 02 — Session Fixation シナリオ — ログイン時に ID 再生成で防ぐ
問題
固定化攻撃のシナリオを 1 スクリプトで擬似化します。
シナリオ:
- 攻撃者から渡された ID
ATTACKERFIXEDIDで Session を開始 (採点用スタブでsession_id()をこの値にセット) - ユーザーがログイン処理を実行
- ログイン直後に
session_regenerate_id(true)を呼ぶ - ログイン後の 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";ポイント
- ログイン直後に必ず
session_regenerate_id(true)を呼ぶ のが固定化攻撃の最小防御 trueを渡し忘れると古い Session が残るので注意 (引数の名前はdelete_old_session)- ログアウト時の
session_destroy()と組み合わせて運用するのが定石
演習問題(2問)
サイト内で問題文・雛形・解答例を確認できます。実際に手元で解くには教材リポジトリを clone してください。