セッション固定化は、攻撃者があらかじめ用意したセッションIDを被害者に使わせ、ログイン後の状態を乗っ取る攻撃です。 対策の中心はログイン成功時のセッションID再発行ですが、攻撃者が認証前のIDを固定できる経路とCookieの適用範囲もあわせて点検する必要があります。
セッション固定化とは
セッション固定化(セッションフィクセーション):攻撃者が既知のセッションIDを被害者のブラウザに固定させ、被害者がそのIDのままログインした後、同じIDを使って本人になりすます攻撃です。 ログイン成功時にセッションIDを再発行せず、攻撃者が事前に知るIDを被害者へ固定できる実装が、主な成立条件になります。
セッションハイジャックがログイン後のIDを盗むのに対し、固定化はログイン前のIDを先に握らせておく点が違います。 攻撃者は自分が知っているIDのまま被害者を認証させ、その認証済みセッションに相乗りします。 成立すれば本人と同じ権限で操作できるため、被害はセッションハイジャックと変わりません。
セッション固定化が起きるパターン
典型的な弱点は次のとおりです。
- ログイン成功後もセッションIDを発行し直さず、認証前のIDをそのまま使い続ける
- セッションIDをURLのクエリパラメータで受け入れる実装で、攻撃者が任意のIDを含むリンクを踏ませられる
- サーバが未知のセッションIDを受け取ったとき、新規に発行せずそのIDを採用してしまう
- サブドメインをまたいでCookieを共有し、別のサブドメインからセッションIDを固定される
- 権限が上がる操作(一般ユーザーから管理者への切り替えなど)の前後でIDを更新していない
共通するのは「認証の前後でセッションIDが変わらず、攻撃者が事前に知ったIDが認証後も有効になる」という点です。
対策法
原則は「ログイン成功時に必ずセッションIDを再発行する」ことです。
- 認証に成功した時点で古いセッションを破棄し、新しいセッションIDを発行する。これが本命の対策になる
- セッションIDはCookieでのみ受け渡し、URLのパラメータからは受け入れない
- サーバが生成したID以外のセッションIDを採用しない(未知のIDは新規発行に切り替える)
- 権限が上がる操作(ログイン、重要な設定変更)の前後でもセッションを更新する
- CookieにHttpOnlyとSecureを付け、固定に使うIDが露出する経路自体を減らす(補助策)
多くのフレームワークはログイン時のID再発行を標準で用意しているため、その機能を使えているかの確認が最優先です。 既存実装ではログイン処理でセッションを作り直しているかを点検するのが、費用対効果の高い進め方になります。
Rails での事例
Rails でhas_secure_passwordを使ったログイン処理を自前で書くとき、認証成功後に session[:user_id] を代入するだけでは、セッションIDが認証前のまま引き継がれます。
攻撃者が事前に固定したIDが、そのまま認証済みセッションになってしまいます。
# 危険:セッションIDを作り直していない
def create
user = User.find_by(email: params[:email])
if user&.authenticate(params[:password])
session[:user_id] = user.id
redirect_to dashboard_path
end
end
対策は、認証成功時に reset_session で古いセッションを破棄してから、新しいセッションに値を入れることです。
def create
user = User.find_by(email: params[:email])
if user&.authenticate(params[:password])
reset_session # ここで新しいセッションIDが発行される
session[:user_id] = user.id
redirect_to dashboard_path
end
end
reset_session より前に値を入れると破棄されてしまうため、順序(リセットしてから代入)が重要です。
Devise を使っている場合は、ログイン時のセッション再発行を標準で行うため、この処理を自前で書く必要はありません。
自前認証から Devise のような実績あるライブラリへ寄せること自体が、この種の取りこぼしを避ける対策になります。
まとめ
セッション固定化対策の要点を整理します。
- 根本原因は「認証の前後でセッションIDが変わらないこと」。攻撃者が事前に握らせたIDが、そのまま認証済みセッションになる
- 本命の対策はログイン成功時のセッションID再発行。Railsなら
reset_sessionを呼んでからsession[:user_id]を代入する(順序が逆だと値ごと破棄される) - セッションIDはCookieでのみ受け渡し、URLのパラメータからは受け入れない。サーバが生成していないIDは採用せず、新規発行に切り替える
- ログインだけでなく、権限が上がる操作(管理者への切り替え、重要な設定変更)の前後でもセッションを更新する
- Deviseのような実績あるライブラリはログイン時の再発行を標準で行う。自前認証から寄せること自体が、この種の取りこぼしを避ける対策になる
セッション固定化対策の中心は、ログインや権限昇格時のセッションID再発行です。 ただし、ログイン処理の1箇所だけでは成立可否を判定できません。 古いIDが無効になるか、URLからIDを受け入れないか、未知のIDを採用しないか、CookieのDomain属性によって別サブドメインから固定できないかも点検してください。
関連して読める記事
セッションハイジャックと固定化は、ログイン後のIDを盗むか、ログイン前のIDを握らせておくかの違いがあり、成立後はいずれも本人の権限で操作されます。 XSSはセッションを悪用される経路の一つであり、HttpOnlyがない場合はJavaScriptからCookieを読み取られる可能性があります。 HttpOnlyがあっても、XSSによって被害者のセッションを使った操作を実行されるため、Cookie属性だけでXSSの被害を防げるわけではありません。 セッションではなくトークンで認証状態を持つJWTでも、「盗まれたIDやトークンをどう無効化するか」という同じ問いが残ります。 ログイン処理そのものを狙う攻撃としては、流出したID/パスワードの一覧を試すクレデンシャルスタッフィングもあり、同じログイン経路を守る対象として扱えます。

セッションハイジャックとは?起きるパターンと対策法
セッションハイジャックの仕組みと起きるパターン、Cookie の HttpOnly / Secure / SameSite 属性と TLS の全面適用を軸にした対策を整理します。Rails のセッションストア設定で属性を明示していない危険例と、secure・httponly・same_site を指定した安全な設定、force_ssl による HTTPS 強制と reset_session によるセッション破棄までを具体的なコードで示します。
2026年7月25日
XSS(クロスサイトスクリプティング)とは?起きるパターンと対策法
XSS(クロスサイトスクリプティング)の仕組みと3つの型、混入しやすいパターン、そして出力時のエスケープを軸にした対策を整理します。React(TypeScript)の dangerouslySetInnerHTML と Rails(ERB)の raw / html_safe を題材に、危険なコードと安全な書き方を具体的なコード例で示します。
2026年7月22日
JWT認証の脆弱性とは?署名検証の不備で起きるパターンと対策法
JWT(JSON Web Token)の署名検証の不備で認証が丸ごと回避される仕組みと起きるパターン、署名アルゴリズムの固定と失効設計を軸にした対策を整理します。Ruby の jwt gem で署名を検証しない decode の危険例と、algorithm を明示した安全な検証、localStorage 保管をやめて HttpOnly Cookie かメモリ保持へ寄せる判断基準を具体的なコードで示します。
2026年7月25日
クレデンシャルスタッフィングとは?起きるパターンと対策法
クレデンシャルスタッフィング(リスト型攻撃)の仕組みと起きるパターン、多要素認証とレート制限を軸にした対策を整理します。ブルートフォースとの違い、rack-attack で IP 単位とアカウント単位の両方にしきい値を設ける実装、Devise の lockable や流出パスワード拒否の組み合わせ方を具体的なコードで示します。
2026年7月25日