はじめに
Webアプリケーションのセキュリティを理解するうえで、Cookie・セッション・認証の関係は最重要テーマの一つです。
脆弱性診断では、これらの仕組みの不備を狙った攻撃(セッションハイジャック、セッションフィクセーション、CSRFなど)を日常的に検査します。本記事では、それぞれの違いと役割、そしてセキュリティ上の注意点を整理します。
結論
Cookieは「ブラウザに保存される小さなデータ」(保存もされるし、リクエスト時にサーバーへも送信される)、セッションは「サーバー側で管理される状態」、トークンは「クライアント側に保存される認証データ」。それぞれ異なる概念であり、混同しないことがセキュリティ理解の第一歩。
Cookie・セッション・トークンの違い
| 項目 | Cookie | セッション | トークン |
|---|---|---|---|
| 何か | サーバーとブラウザ間で小さなデータをやりとりする仕組み | サーバー側で管理されるユーザー状態 | クライアント側に保存される認証データ |
| 保存場所 | ブラウザに保存され、リクエスト時にサーバーへ自動送信される | サーバー(メモリ、DB、Redisなど) | ブラウザ(Cookie、localStorage等) |
| 改ざん | 利用者本人が参照・変更可能 | サーバー管理のため改ざん不可 | 署名により改ざん検知が可能 |
| 有効期限 | Expires / Max-Age で設定可能 | サーバー側のタイムアウト設定 | トークン内に有効期限を含む |
重要な関係性
Cookie ≠ セッション ≠ トークン
Cookie → 「データの運び屋」(サーバー⇔ブラウザ間でやりとりされる仕組み)
セッション → 「サーバーが管理する状態」
トークン → 「認証データ」(中身)
CookieにセッションIDを載せて運ぶ、という関係
Cookie の詳細
Cookieとは
Webサーバーがブラウザに対して**「この値を覚えておいて」** と指示する仕組みです。ブラウザは次回以降のリクエスト時に、保存したCookie値を自動的にサーバーへ送信します。
Cookieの制限
- 保持できる値の個数と文字列長に制限がある
- 利用者本人が参照・変更できるため、秘密情報の直接格納には向かない
Cookieのセキュリティ上重要な属性
Cookieには複数の属性がありますが、セキュリティの観点で特に重要なのは3つです。
| 属性 | 役割 | 設定しないとどうなるか |
|---|---|---|
| Domain | 指定したドメインと一致する場合のみCookieを送信する | 不用意に設定すると共有範囲が広がり、他サブドメインから悪用されるリスクがある |
| Secure | HTTPS通信の場合のみCookieを送信する | HTTP通信でも送信されるため、平文での盗聴リスクが生じる |
| HttpOnly | JavaScriptからCookieへのアクセスを禁止する | XSS攻撃で document.cookie により窃取される |
Domain属性の注意点
Domain属性は「指定しない」のが最も安全。
指定しなければ、Cookieは発行元のホストにのみ送信されます(ホスト限定)。不用意に .example.com のように広く指定すると、evil.example.com のようなサブドメインからもCookieにアクセスできてしまいます。
セッション管理の仕組み
Cookie によるセッション管理の流れ
1. ユーザーがログイン(ID/パスワード送信)
2. サーバーが認証OK → セッションIDを生成
3. Set-CookieヘッダでセッションIDをブラウザに送信
4. ブラウザがCookieにセッションIDを保存
5. 以降のリクエストでCookieヘッダにセッションIDを自動送信
6. サーバーがセッションIDからユーザーを特定
Cookieの値 ≒ セッションID
Webサーバーがブラウザに覚えさせるCookieの値は、多くの場合セッションIDです。このセッションIDが、サーバー側に保管されたセッション情報(ユーザー名、権限、カート内容など)と紐づいています。
HTTP認証の方式
HTTPプロトコル自体にも認証機能がサポートされています。
Basic認証
最もシンプルな認証方式です。
1. ブラウザからリクエスト送信
2. サーバーが 401 Unauthorized で応答
3. ブラウザが認証ダイアログを表示
4. ユーザーがユーザー名とパスワードを入力
5. Base64エンコードして再リクエスト
注意点: Basic認証はBase64エンコード(暗号化ではない)のため、HTTPS通信が前提です。HTTPで使うと資格情報が平文で漏洩します。
実装方法: Webサーバーの設定(.htaccess等)またはPHP設定にて実現可能です。
Digest認証
パスワードをハッシュ化して送信する方式で、Basic認証よりはセキュアですが、現在はあまり使われていません。
NTLM認証
Windows環境で使われるチャレンジ・レスポンス方式の認証です。Active Directory環境でのシングルサインオンに利用されます。
セッション管理に対する攻撃と対策
セッションフィクセーション(セッションIDの固定化攻撃)
攻撃者があらかじめ用意したセッションIDをユーザーに使わせ、ログイン後にそのセッションを乗っ取る攻撃です。
対策:
認証成功(ログイン)後にセッションIDを再生成する。
ログイン前後でセッションIDが変わるため、攻撃者が事前に入手したIDは無効になります。
セッションIDの盗聴
ネットワーク上でセッションIDが盗み取られる攻撃です。
対策:
TLS(HTTPS)による通信の暗号化が有効。 加えて、CookieにSecure属性を設定する。
CSRF(Cross-Site Request Forgery)
CSRFとは
ログイン中のユーザーのブラウザを悪用して、ユーザーの意図しないリクエストをサーバーに送信させる攻撃です。ブラウザがCookieを自動送信する仕組みを悪用します。
対策
| 対策 | 内容 |
|---|---|
| Refererの確認 | リクエストのRefererヘッダを検証し、正規のページから送信されたかを確認する |
| CSRFトークン | フォームにサーバー発行のトークンを埋め込み、リクエスト時に検証する。HTMLのRefererヘッダは攻撃者が任意に組み込めないため、Referer確認も有効 |
| SameSite Cookie属性 |
SameSite=Lax または Strict を設定し、外部サイトからのCookie送信を制限する |
まとめ
| ポイント | 内容 |
|---|---|
| Cookieはデータの運び屋 | ブラウザに保存され、リクエスト時にサーバーへ自動送信される仕組み |
| セッションはサーバー管理 | サーバー側で状態を管理するため、改ざんできない |
| トークンは認証データ | クライアント側に保存される認証情報 |
| Cookie重要属性 | Domain、Secure、HttpOnly の3つ |
| Domain属性 | 指定しない(ホスト限定)が最も安全 |
| セッションID固定化対策 | ログイン後にセッションIDを再生成する |
| 盗聴対策 | TLS(HTTPS)+ Cookie の Secure属性 |
| CSRF対策 | Referer確認、CSRFトークン、SameSite属性 |
参考資料
この記事は脆弱性診断エンジニアとしての学習メモを兼ねています。
誤りや補足があればコメントいただけると嬉しいです。