はじめに
研修期間も終わったため、
毎日セキュリティエンジニアとしての学ぶをアウトプットしていくことにしました。
セッションについて
Webアプリケーションのセキュリティを学ぶうえで、セッション管理は避けて通れないテーマです。
脆弱性診断の現場でも、セッション管理の不備は頻出する指摘事項の一つです。しかし、「セッションって何?」と聞かれると、意外と正確に説明できない方も多いのではないでしょうか。
本記事では、セキュリティ初学者の方を対象に、セッションの基礎(仕組み・用語) をできるだけ噛み砕いて解説します。
結論:セッションとは
セッション = ユーザーがWebサイトにアクセスしてからログアウト(または離脱)するまでの「一連のやりとり」を管理する仕組み
ECサイトでログインして、商品をカートに入れて、決済する ―― この一連の操作をひとまとまりとして扱うために、セッションという仕組みが存在します。
なぜセッションが必要なのか? ― HTTPの「ステートレス」問題
HTTPはステートレス(状態を持たない)
WebはHTTP(Hypertext Transfer Protocol)で通信しています。HTTPの大きな特徴として、ステートレス(Stateless) であることが挙げられます。
これは、1回のリクエスト/レスポンスが完結するたびに、サーバーはクライアントの情報をすべて忘れてしまうことを意味します。
たとえ話:記憶喪失の店員さん
あなた「カレーください」
店員 「はい、カレーですね!(提供)」
(5秒後)
あなた「さっき頼んだカレーに福神漬けもください」
店員 「…どちら様でしょうか?カレー?何のことですか?」
HTTPのステートレス性は、まさにこの状態です。リクエストのたびにサーバーは「あなたが誰か」を忘れてしまいます。
これでは困る場面
- ECサイト:カートに入れた商品を覚えてほしい
- ログイン:認証済みの状態を維持してほしい
- 銀行サイト:振込途中で「誰ですか?」と言われたら困る
この問題を解決するために生まれたのが セッション管理 です。
セッション管理の仕組み
全体の流れ
【ステップ1】ログイン
ブラウザ → サーバー : ユーザーID/パスワード送信
サーバー : 認証OK → セッションIDを生成
サーバー → ブラウザ : セッションIDをCookieで返す
【ステップ2】以降のリクエスト
ブラウザ → サーバー : リクエスト + Cookie(セッションID)
サーバー : セッションIDからユーザーを特定 → 適切なレスポンス返却
【ステップ3】ログアウト
サーバー : セッションを破棄 → セッションIDを無効化
ポイント
| 項目 | 説明 |
|---|---|
| セッションID | ユーザーを識別するための一意な文字列。サーバーが生成する |
| Cookie | セッションIDをブラウザに保存し、リクエスト時に自動送信する仕組み |
| セッションストア | セッションIDとユーザー情報の紐付けを保存する場所(メモリ、DB、Redisなど) |
用語を整理する
セッションID
サーバーがユーザーごとに発行する一意の識別子です。
たとえ話にすると「受付番号」のようなものです。病院の受付で番号を渡されて、以降はその番号で呼ばれる ―― セッションIDも同じ仕組みです。
重要:セッションIDそのものにはユーザー情報は含まれません。 あくまで「サーバー側に保存されたデータを参照するための鍵」です。
Cookie(クッキー)
ブラウザに保存される小さなデータで、名前=値 の形式を持ちます。
HTTPレスポンスの Set-Cookie ヘッダでサーバーからブラウザに送られ、以降のリクエストでは Cookie ヘッダに載せて自動的にサーバーへ送信されます。
# サーバー → ブラウザ(レスポンス)
Set-Cookie: SESSIONID=abc123xyz; Path=/; HttpOnly; Secure
# ブラウザ → サーバー(次回以降のリクエスト)
Cookie: SESSIONID=abc123xyz
Cookieの主要な属性
| 属性 | 役割 |
|---|---|
HttpOnly |
JavaScriptからCookieにアクセスできなくする(XSS対策) |
Secure |
HTTPS通信時のみCookieを送信する(盗聴対策) |
SameSite |
外部サイトからのリクエスト時のCookie送信を制御する(CSRF対策) |
Expires / Max-Age |
Cookieの有効期限を設定する |
Path |
Cookieが送信されるURLパスを制限する |
Domain |
Cookieが送信されるドメインを指定する |
セッションストア
セッションIDとユーザー情報の紐付けを保存する場所です。
- サーバーメモリ:手軽だが、サーバー再起動で消える
- ファイル:PHPのデフォルト方式
- データベース:永続的だがI/Oコストがある
- Redis / Memcached:高速で、大規模アプリケーションで採用されることが多い
セッション管理の方法3パターン
セッションIDの受け渡し方法は主に3つあります。
1. Cookie方式(推奨)
最も一般的で安全性が高い方式です。Set-Cookie ヘッダでセッションIDをブラウザに保存します。
✅ メリット:自動送信、HttpOnly/Secure属性で保護可能
⚠️ 注意点:XSS脆弱性があるとCookieが抜かれるリスクがある
2. URLパラメータ方式(非推奨)
URLにセッションIDを埋め込む方式です。
https://example.com/mypage?sessionid=abc123xyz
❌ リスク:URLが履歴やRefererヘッダで外部に漏洩する可能性がある
❌ リスク:URLを共有するとセッションIDも共有されてしまう
3. hiddenフィールド方式
HTMLフォームの hidden フィールドにセッションIDを埋め込む方式です。
<input type="hidden" name="sessionid" value="abc123xyz">
△ 用途:特定のフォーム遷移でのみ使われることがある
⚠️ 制約:aタグでのページ遷移には使えない
セッションのライフサイクル
┌──────────┐
│ 開始 │ ユーザーがアクセスまたはログイン
└────┬─────┘
↓
┌──────────┐
│ 維持 │ セッションIDの送受信でユーザーを識別
└────┬─────┘
↓
┌──────────┐
│ 終了 │ ログアウト / タイムアウト / ブラウザ閉じる
└──────────┘
セッションの終了条件
- 明示的なログアウト:サーバー側でセッションを破棄
- タイムアウト:一定時間操作がないと自動で無効化(一般的に15〜30分)
-
ブラウザ終了:
Expires未設定のCookieはブラウザ終了時に消える
セキュリティの観点から ― よくある脅威(概要)
セッション管理の不備は、重大なセキュリティインシデントに直結します。ここでは代表的な脅威の概要だけ触れます(詳細は別記事で解説予定)。
| 脅威 | 概要 |
|---|---|
| セッションハイジャック | 攻撃者がセッションIDを盗み、正規ユーザーになりすます |
| セッションフィクセーション | 攻撃者が用意したセッションIDをユーザーに使わせ、ログイン後に乗っ取る |
| XSSによるCookie窃取 | XSS脆弱性を悪用して document.cookie でセッションIDを窃取する |
| CSRF | 正規ユーザーの認証済みセッションを利用して、意図しない操作を実行させる |
最低限押さえるべき対策
- セッションIDは暗号論的に安全な乱数で生成する(フレームワーク標準機能を使う)
- ログイン成功時にセッションIDを再生成する(フィクセーション対策)
- Cookieには
HttpOnly、Secure、SameSite属性を設定する - セッションには適切なタイムアウトを設定する
- セッション管理は自作せず、フレームワークの機能を利用する
まとめ
| ポイント | 内容 |
|---|---|
| セッションとは | ユーザーの一連のやりとりを管理する仕組み |
| なぜ必要か | HTTPがステートレスだから |
| セッションID | ユーザーを識別するための一意な文字列 |
| Cookie | セッションIDの受け渡しに使われるブラウザ側の保存領域 |
| セッションストア | セッションIDとユーザー情報を紐づけるサーバー側の保存場所 |
| セキュリティ上の鉄則 | フレームワーク標準のセッション管理を使う/Cookie属性を適切に設定する |
参考資料
- IPA - 安全なウェブサイトの作り方(セッション管理の不備)
- IPA - Webアプリケーション編 第4章 セッション対策
- OWASP - Session Management Cheat Sheet
次に読むとよいテーマ
- セッションハイジャックの攻撃手法と対策
- Cookie属性(HttpOnly / Secure / SameSite)の詳細
- JWT(JSON Web Token)との違い
- セッション管理 vs トークンベース認証
この記事は脆弱性診断エンジニアとしての学習メモを兼ねています。
誤りや補足があればコメントいただけると嬉しいです。