用語辞典10分で読める

セッション固定(Session Fixation)とは:攻撃者が用意したセッションIDでログインさせる攻撃

セッション固定は、攻撃者が用意したセッションIDを被害者に使わせ、ログイン後に同じIDでなりすます攻撃です。仕組みと、ログイン時のセッションID再生成やCookie属性による防御を解説します。

本文を読む
公開日
更新日
目次

セッション固定は、攻撃者が用意したセッションIDのまま、被害者にログインさせる攻撃です。仕組みと、確実な防ぎ方を解説します(攻撃手順は載せません)。

なぜ成立するか(仕組み)

原因は「ログイン前後でセッションIDが変わらない」設計にあります。変わらなければ、ログイン前に攻撃者が知っていたIDが、ログイン後も“認証済み”として通用してしまいます。

① 攻撃者が“あるセッションID”を被害者に使わせる(リンク等で)
↓ 被害者がそのIDのままログイン
② IDが再生成されない=同じIDが“認証済み”になる
↓ 攻撃者は最初からそのIDを知っている
③ 同じIDでアクセス=被害者になりすまし
ログインしてもIDが変わらないと、攻撃者が事前に知っていたIDがそのまま認証済みになってしまう。

CSRF や XSS と組み合わされることもありますが、セッション固定そのものの本質は「ログイン時にIDを作り直していない」という一点です。

IPA(情報処理推進機構)の「安全なウェブサイトの作り方」は、この問題を「セッション管理の不備」の一つとして扱い、ログイン機能を持つウェブサイト全般に注意が必要としています。根本的な解決として挙げているのは、ログイン成功後に新しくセッションを開始することです。

セッション乗っ取り・CSRFとの違い

名前が似ていて混同されやすい3つを並べます。どれも「ログイン状態を悪用される」点は同じですが、攻撃者が何を手に入れるかと、効く対策が違います。

項目セッション固定セッション乗っ取りCSRF
攻撃者が持つもの自分で用意したID(最初から知っている)盗んだ他人のIDIDは持たない
被害者に起きること用意されたIDのままログインさせられる発行済みのIDを盗まれる意図しない操作を送らされる
主な防御ログイン時のID再生成HttpOnly・Secure、XSS対策、短い有効期限CSRFトークン、SameSite

セッション固定だけは「ログインの時点でIDを作り直す」という1つの対策で根本的に防げる点が特徴です。

防御:ログイン時にIDを作り直す

1

ログイン成功時にセッションIDを再生成(最重要)

認証が成立した瞬間に、古いIDを破棄して新しいセッションIDを発行する(多くのフレームワークの session regenerate / renew)。事前に仕込まれたIDは即無効になる。権限が上がる操作(管理者昇格など)でも再生成する。
2

URL経由のセッションID指定を受け付けない

セッションIDはCookieで扱い、URLパラメータからのID指定は無視する。攻撃者が“固定したいID”を被害者に使わせる経路を塞ぐ。
3

Cookie属性を設定する

セッションCookieに HttpOnly(JSから読めない)・Secure(HTTPSのみ)・SameSite(別サイト起点の送信を抑制)を付ける。関連する乗っ取り経路をまとめて弱める。
4

適切な失効を設ける

一定時間・ログアウト・パスワード変更でセッションを失効させる。固定されたIDが長く有効なままにならないようにする。

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点を確かめます。どれも開発者ツールだけでできます。

  1. 開発者ツールの「アプリケーション」(Firefoxは「ストレージ」)でセッションCookieの値を控え、ログイン後にもう一度見る。値が変わっていなければ、ログイン時にIDを作り直していない
  2. ログイン画面やログイン後のURLに PHPSESSID= や ;jsessionid= のようなセッションIDが付いていないか見る
  3. 同じ画面でセッションCookieに HttpOnly・Secure・SameSite が付いているかを見る
  4. ログアウト後に、控えておいた古い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

次に読む

分類番号

CWE は脆弱性の原因となる弱点の種類を、MITRE ATT&CK は攻撃者の手口を分類した番号体系です。どちらも MITRE が管理し、脆弱性情報や検知ルールの分類に広く使われています。

CWE(弱点の種類)

CWE™: Copyright © 2006–2026, The MITRE Corporation. CWE is a trademark of The MITRE Corporation. The MITRE Corporation hereby grants you a non-exclusive, royalty-free license to use CWE for research, development, and commercial purposes. Any copy you make for such purposes is authorized on the condition that you reproduce MITRE’s copyright designation and this license in any such copy. CWE Terms of Use

よくある質問

Qセッション固定とセッション乗っ取りは何が違う?
A

セッション乗っ取り(hijacking)は、すでに発行された他人のセッションIDを“盗む”攻撃です。セッション固定(fixation)は逆で、攻撃者が“自分の知っているID”を先に被害者へ使わせ、被害者がそのIDでログインするのを待つ攻撃です。盗むのではなく、最初から知っているIDを認証済みにさせるのが特徴です。

Q一番の防御は?
A

『ログインの瞬間にセッションIDを再生成する』ことです。多くのフレームワークやセッションライブラリにこの機能(session regenerate / renew)があり、認証が成立した時点で古いIDを捨てて新しいIDを発行します。これだけで、攻撃者が事前に仕込んだIDは無効になります。権限が上がる操作(管理者昇格など)でも再生成します。

QURLにセッションIDを入れるのはなぜ危険?
A

URLにIDが乗ると、リンク共有・リファラ・ログ・ブラウザ履歴を通じて第三者に渡りやすく、攻撃者が“固定したいID”を被害者に使わせるきっかけになります。セッションIDはURLパラメータではなくCookieで扱い、URL経由のID指定は受け付けないのが安全です。

Q自分のサイトがセッション固定に弱いか、どう確かめる?
A

自分のサイトで、ブラウザの開発者ツールを開き、ログイン前と後のセッションCookieの値を比べます。ログインしても値が同じなら、ログイン時にIDを作り直していないので対策が必要です。あわせて、URLにセッションIDが付かないこと、Cookieに HttpOnly・Secure・SameSite が付いていることを確認します。

QPHPでセッション固定を防ぐ設定は?
A

ログイン成功時に session_regenerate_id(true) を呼んで新しいIDに切り替えます。php.ini では session.use_strict_mode を 1 にして、サーバーが発行していないIDを受け付けないようにします(既定は 0)。session.use_only_cookies は既定の 1 のまま、session.use_trans_sid は既定の 0 のままにして、URLでIDを渡さないようにします。

QJWTを使っていればセッション固定は起きない?
A

サーバー側のセッションIDを使わず、ログイン成功時に新しいトークンを発行する方式なら、事前に用意したIDを認証済みにさせるという形の攻撃は成り立ちにくくなります。ただし、ログイン前に発行したトークンをログイン後も使い続ける設計なら同じ問題が起こり得ます。どの方式でも、ログインの時点で新しい識別子を発行するのが原則です。