セッション固定は、攻撃者が用意したセッションIDのまま、被害者にログインさせる攻撃です。仕組みと、確実な防ぎ方を解説します(攻撃手順は載せません)。
なぜ成立するか(仕組み)
原因は「ログイン前後でセッションIDが変わらない」設計にあります。変わらなければ、ログイン前に攻撃者が知っていたIDが、ログイン後も“認証済み”として通用してしまいます。
CSRF や XSS と組み合わされることもありますが、セッション固定そのものの本質は「ログイン時にIDを作り直していない」という一点です。
IPA(情報処理推進機構)の「安全なウェブサイトの作り方」は、この問題を「セッション管理の不備」の一つとして扱い、ログイン機能を持つウェブサイト全般に注意が必要としています。根本的な解決として挙げているのは、ログイン成功後に新しくセッションを開始することです。
セッション乗っ取り・CSRFとの違い
名前が似ていて混同されやすい3つを並べます。どれも「ログイン状態を悪用される」点は同じですが、攻撃者が何を手に入れるかと、効く対策が違います。
| 項目 | セッション固定 | セッション乗っ取り | CSRF |
|---|---|---|---|
| 攻撃者が持つもの | 自分で用意したID(最初から知っている) | 盗んだ他人のID | IDは持たない |
| 被害者に起きること | 用意されたIDのままログインさせられる | 発行済みのIDを盗まれる | 意図しない操作を送らされる |
| 主な防御 | ログイン時のID再生成 | HttpOnly・Secure、XSS対策、短い有効期限 | CSRFトークン、SameSite |
セッション固定だけは「ログインの時点でIDを作り直す」という1つの対策で根本的に防げる点が特徴です。
防御:ログイン時にIDを作り直す
ログイン成功時にセッションIDを再生成(最重要)
URL経由のセッションID指定を受け付けない
Cookie属性を設定する
HttpOnly(JSから読めない)・Secure(HTTPSのみ)・SameSite(別サイト起点の送信を抑制)を付ける。関連する乗っ取り経路をまとめて弱める。適切な失効を設ける
OWASP の Session Management Cheat Sheet は、権限の変化のたびにIDを作り直すことに加え、サーバーが自分で発行したIDだけを受け付ける「strict」な方式を勧めています。外から持ち込まれた未知のIDをそのまま採用する方式(permissive)だと、攻撃者が用意したIDが通る余地が残るためです。
主なフレームワークの既定動作
多くのフレームワークは、標準のログイン機能を使えば自動でIDを作り直します。危ないのは、ログイン処理を自分で書いたときや、既定の保護を外したときです。
| 環境 | 既定の動作 | 自分で書くときに確認すること |
|---|---|---|
| PHP(素のセッション) | 自動では作り直さない。session.use_strict_mode の既定は 0 | ログイン成功時に session_regenerate_id(true) を呼ぶ。use_strict_mode を 1 にする |
| Laravel | スターターキットや Fortify を使えば認証時に自動で再生成 | ログインを自作したら $request->session()->regenerate() を呼ぶ |
| Spring Security | 既定で有効(Servlet 3.1 以降は changeSessionId) | sessionFixation().none() で無効にしていないか確認する |
PHPでは、URLでセッションIDを渡す設定(session.use_trans_sid を有効にする、session.use_only_cookies を無効にする)は PHP 8.4 で非推奨になりました。古い設定ファイルを引き継いでいる場合は見直します。
自分のサイトで確認する方法
自分が管理するサイトで、次の4点を確かめます。どれも開発者ツールだけでできます。
- 開発者ツールの「アプリケーション」(Firefoxは「ストレージ」)でセッションCookieの値を控え、ログイン後にもう一度見る。値が変わっていなければ、ログイン時にIDを作り直していない
- ログイン画面やログイン後のURLに
PHPSESSID=や;jsessionid=のようなセッションIDが付いていないか見る - 同じ画面でセッションCookieに
HttpOnly・Secure・SameSiteが付いているかを見る - ログアウト後に、控えておいた古いCookieの値を戻してアクセスし、ログイン状態に戻らないことを確かめる
Cookieの属性は、所有を確認したサイトを点検する サイト総合セキュリティ診断 でも確認できます。1の確認は、ログイン処理を変えたときに自動テストに入れておくと、うっかり外したときにすぐ気づけます。
当サイトの視点:フレームワークの『再生成』を外さない
セッション固定は、自前の凝った対策ではなく「ログイン時にIDを再生成する」という1つの対策でほぼ防げます。重要なのは、フレームワークが用意しているこの仕組みをうっかり外さない・呼び忘れないことです。独自のセッション管理を自作するより、実績のある実装の既定動作を使うのが安全です。当サイトは「認証や鍵まわりは自作しない・既定の安全側を外さない」を原則にしています。IDOR と同様、認証・認可まわりは仕組みとして毎回確実に実行されるようにすることが大切です。
出典(一次情報)
- IPA「安全なウェブサイトの作り方」1.4 セッション管理の不備 — ipa.go.jp(ログイン成功後に新しくセッションを開始する、URLにIDを入れない)
- OWASP Session Management Cheat Sheet — cheatsheetseries.owasp.org(権限変化時の再生成、strict な方式、Cookie属性)
- MITRE CWE-384: Session Fixation — cwe.mitre.org
- PHP マニュアル「セッションの実行時設定」 — php.net(
use_strict_modeなどの既定値、8.4 での非推奨) - Laravel ドキュメント「HTTP Session」 — laravel.com / Spring Security「Authentication Persistence and Session Management」 — docs.spring.io