🎓 レベル:標準 | 重要度:A(必須) 📎 前提:セッションとトークン(JWT)
要点(BLUF)
- 認証・セッションの理屈(第3章)を、実装の細部で台無しにしないためのトピック。事故の多くは小さな設定漏れ。
- Cookie は
HttpOnly・Secure・SameSiteの3属性で固める。これが XSS・盗聴・CSRF への一次防御。 - **XSS(スクリプト混入)と CSRF(意図しない操作の誘発)**は別物。XSS は出力エンコード、CSRF はトークン+SameSite で防ぐ。
概念:理屈と実装のギャップ
第3章で「ソルト付き低速 KDF」「JWT の署名検証」を学びました。しかし実装で Cookie 属性を付け忘れる、自動エスケープを切る、といった小さな漏れが、せっかくの設計を無効化します。アプリセキュリティの事故は派手な攻撃よりも、こうした実装の取りこぼしから起こります。ここでは代表的な勘所を押さえます。
仕組み:Cookie の安全属性
セッション ID やトークンを Cookie に置くなら、最低限この3属性を設定します。
| 属性 | 効果 | 防ぐもの |
|---|---|---|
HttpOnly | JavaScript から読めなくする | XSS による Cookie 窃取 |
Secure | HTTPS のときだけ送信 | 平文回線での盗聴 |
SameSite | 別サイトからの送信を制限 | CSRF(Lax/Strict) |
加えて、Domain/Path を絞り、有効期限を適切にし、ログアウトで確実に無効化します。トークンを localStorage に置くと JS から読めて XSS に弱いので、HttpOnly Cookie が安全寄りです(セッションとトークン(JWT))。
仕組み:XSS と CSRF は別の問題
混同されがちですが、原因も対策も異なります。
- XSS(クロスサイトスクリプティング):攻撃者の用意したスクリプトが被害者のブラウザで実行される。原因は出力時のエンコード不足。対策の本丸は文脈別の出力エンコード(入力検証とインジェクション対策)+ **CSP(Content-Security-Policy)**で実行を制限。
HttpOnlyで Cookie 窃取の被害を緩和。 - CSRF(クロスサイトリクエストフォージェリ):ログイン中の利用者に、本人の意図しないリクエストを別サイト経由で送らせる。対策はCSRF トークン(サーバ発行の使い捨て値をフォームに埋め検証)+ Cookie の
SameSite。
flowchart TD
subgraph XSS["XSS:スクリプトが混入して実行"]
X1["原因:出力エンコード不足"] --> X2["対策:出力エンコード+CSP+HttpOnly"]
end
subgraph CSRF["CSRF:意図しない操作を誘発"]
C1["原因:リクエストの真正性を確認せず"] --> C2["対策:CSRFトークン+SameSite"]
end
仕組み:セッションのライフサイクル
- ログイン時にセッション ID を再生成:固定化(攻撃者が用意した ID を使わせる)を防ぐ。
- 十分な乱数の ID:推測不能な長さ。
secretsなどの安全な乱数で。 - アイドル/絶対タイムアウト:放置や長時間の有効化を避ける。
- ログアウトでサーバ側も破棄:クライアントの Cookie 削除だけでなくサーバの状態も無効化。
防御側の使い方/設定
- Cookie 3属性を既定で付ける:フレームワークのセッション設定で
HttpOnly・Secure・SameSiteを有効化。 - 状態変更操作に CSRF 対策:トークン検証+
SameSite。GET で状態を変えない設計に。 - 出力は常にエンコード+CSP:XSS の本丸は出力エンコード。CSP で実行可能なスクリプト源を制限。
- 認証情報の保存は第3章に従う:パスワードは低速 KDF(認証の基礎(パスワード保存とMFA))、トークンは署名検証(セッションとトークン(JWT))。
- エラー・列挙対策:ログイン失敗メッセージを一般化し、アカウント列挙の手がかりを与えない。
なぜ安全か:理屈を実装の既定で守る
これらが効くのは、正しい設計を「既定値」として実装に固定するからです。HttpOnly は XSS が起きても Cookie 窃取を防ぎ、Secure は回線盗聴を防ぎ、SameSite と CSRF トークンは「本人のブラウザだが本人の意図ではない」リクエストを弾きます。どれも一行の設定ですが、抜けると設計全体の保証が崩れます。実装の既定で守ることが、人的ミスに強い防御です。
仕組みの直観
セッションの実装は入館証の運用です。理屈(本人確認の仕組み)が立派でも、入館証を落としても誰でも拾って使える(属性漏れ)、別人が「これを使え」と渡した札で入れてしまう(固定化)、よそのビルの依頼状で勝手に手続きが進む(CSRF)――こうした運用の穴で台無しになります。属性を固め、入館のたびに新しい札を発行し、手続きには本人発行の合言葉(CSRF トークン)を要求する、という運用の徹底が安全を作ります。
⚠️ よくある誤解・設定ミス
- Cookie 属性の付け忘れ:
HttpOnly/Secure/SameSite無しは XSS・盗聴・CSRF に直結。 - XSS と CSRF の対策を取り違える:XSS に CSRF トークンは効かない。原因別に対策する。
- トークンを
localStorage保存:XSS で読まれうる。HttpOnlyCookie が安全寄り。 - ログイン後に ID を再生成しない:セッション固定化に弱い。
- GET で状態変更:CSRF の足場になりやすい。状態変更は POST 等+トークン。
対応 lab
ブラウザ挙動が前提のため実行 lab は置きません。トークン側の検証は security-study/labs/jwt_verify_demo.py、保存側は password_hashing_demo.py が対応します。
関連
- セッション/トークンの理屈 → セッションとトークン(JWT)
- 出力エンコード(XSS の本丸) → 入力検証とインジェクション対策
- 設計・レビューで支える → セキュアコーディングとレビュー