採点されません。匿名です。 間違えることは学習の一部です。読むだけでもかまいません。

Session セキュリティ — Regenerate ID

テクノロジ系 / session-cookie (session / cookie / login / CSRF)

Session セキュリティ — Regenerate ID

Lesson 13 / Chapter 6

Session Fixation 攻撃って何

「攻撃者が 既に知っている Session ID をユーザーに使わせて、ログイン後の Session を乗っ取る」

1. 攻撃者がサイトにアクセス → サーバーから Session ID="ABC123" を取得
2. 攻撃者が罠リンクで ABC123 をユーザーに使わせる
   例: https://target.example/?PHPSESSID=ABC123
3. ユーザーが ABC123 のまま target.example にログイン
4. サーバー: 「ABC123 さん、ログイン完了」
5. 攻撃者: ABC123 を自分のブラウザに設定 → ログイン状態を共有して乗っ取り

ログイン前後で Session ID が同じ ことが弱点。

防御策: session_regenerate_id(true)

<?php
session_start();

$oldId = session_id();   // ログイン前の ID
session_regenerate_id(true);   // 新 ID を発行 + 古い Session を破棄
$newId = session_id();   // ログイン後の ID

// $oldId !== $newId が保証される
$_SESSION['user'] = ['name' => '太郎'];
引数意味
true古い Session を破棄 (必須に近い)
false (デフォルト)古い Session は残ったまま (危険)

必ず true を渡す。これを忘れると、固定化された ID も生き続けてしまう。

いつ呼ぶか

タイミング理由
ログイン直後ログイン前の ID で固定化されてもログイン後 ID で無効化される
権限昇格時 (一般 → 管理者)同じ理由。重要操作の前に再生成
ログアウト時session_destroy() するので不要だが、念のため再生成しても良い

何らかの権限が変わる瞬間に ID を作り直す」のが原則。

採点用: ID 変更を確認

<?php
// (採点用スタブ ... session の擬似化)

$oldId = session_id();       // 採点用は固定 ID "TESTSESSIONID"
session_regenerate_id(true);
$newId = session_id();

if ($oldId !== $newId) {
    echo "changed: yes\n";
} else {
    echo "changed: no\n";
}

CLI でも session_regenerate_id() は新しい ID を生成してくれる。比較で「変わったか」を検証する。

他の防御策 (概念だけ)

対策効果
session.cookie_httponly=1JS から PHPSESSID Cookie を読めなくする (XSS 経由の盗難を防ぐ)
session.cookie_secure=1HTTPS 通信でしか PHPSESSID を送らない
session.cookie_samesite=Lax他サイトからのリクエストに PHPSESSID を載せない (CSRF と二重防御)
session.use_strict_mode=1サーバーが発行していない ID を拒否

php.ini または ini_set() で設定。全部 ON にしておけば固定化攻撃にも強くなる

このチャプターでできるようになること

✅ Session Fixation が「事前に知った ID をユーザーに使わせて乗っ取る攻撃」と言える

session_regenerate_id(true) を呼ぶ意味と引数の役割を説明できる

✅ ログイン時に必ず ID を再生成するコードを書ける

✅ 他の防御策 (httponly / secure / samesite / strict_mode) を 1 行で挙げられる

→ ドリルへ

考えてみよう

既定では正解・不正解の判定はしません。自分のペースで「答えを見る」を。採点してほしい場合だけ「採点してほしい」を押してください。