AI Session Notes - 2026-02-23
CORS(Cross-Origin Resource Sharing)の仕組み
学んだこと
- CORS はブラウザだけが持つセキュリティ機能であり、サーバー間通信には適用されない
- オリジン(Origin)は「プロトコル + ドメイン + ポート」の3つの組み合わせで、どれか1つでも異なれば別オリジン扱いになる
- サブドメイン違い(
app.example.comvsapi.example.com)も別オリジンになる - ブラウザはリクエスト時に
Originヘッダーを自動付与し、JavaScript からの書き換えは不可能(Forbidden Header)
詳細
なぜブラウザにだけ CORS が必要か
ブラウザはドメインごとの Cookie を自動送信する仕組みを持つ。CORS がなければ、悪意あるサイトの JS がユーザーのログイン済み Cookie を使って別サイトの API を勝手に叩けてしまう。サーバー間通信ではこの「Cookie 自動送信」が起きないため、CORS は不要。
リクエストのブロックタイミングは2パターン
- シンプルなリクエスト(GET など): リクエストは送信される。レスポンスも返ってくるが、ブラウザが JS への引き渡しをブロックする
- 複雑なリクエスト(POST + JSON など): ブラウザが事前に OPTIONS リクエスト(プリフライト)を送信し、許可されなければ本番リクエスト自体を送らない
Origin ヘッダー偽装について
curl やサーバーからは Origin を自由に設定できるが、それは自分自身の操作であり、他人の Cookie を利用できるわけではないので問題にならない。CORS が守りたいのは「ブラウザを使っている人の Cookie が第三者に悪用されること」。
同一組織内での CORS 許可
同じ会社の複数サービス間(例: app.example.com と api.example.com)では、API サーバー側が Access-Control-Allow-Origin ヘッダーで許可リストを管理し、信頼するオリジンからのアクセスを許可するのが一般的なパターン。
Cookie・トークン・セッションの関係
学んだこと
- Cookie はブラウザのデータ保存 + サーバーへの自動送信手段
- トークン はユーザーが認証済みであることを示す文字列。保存場所は Cookie でも localStorage でもよい
- セッション はサーバーがユーザーごとに保持する状態(ログイン情報など)
- この3つは入れ子の関係になることが多い: Cookie(運搬手段)の中にトークンがあり、トークンからセッション情報を得る
詳細
セッションの実現方法は2パターン
- サーバー側に保存: トークンはただの ID で、サーバーの DB やメモリに実データがある。トークンをキーにして引く
- トークン自体に情報を埋め込む: トークンに暗号化されたデータが入っており、サーバー側には保存しない(iron-session 等)
セッションの有効期限
セッション自体が切れるのではなく、トークンの保存先(Cookie)に設定された有効期限で制御される。Cookie が期限切れ → ブラウザが削除 → サーバーにトークンが届かない → 未ログイン扱い。
Cookie と localStorage の比較
学んだこと
- Cookie はリクエスト時にサーバーへ自動送信されるが、localStorage は自動送信されない(JS で明示的に送る必要がある)
- Cookie は約 4KB、localStorage は約 5〜10MB の容量制限
- localStorage には有効期限がなく、明示的に削除しない限り残り続ける
詳細
セキュリティ上のトレードオフ
- httpOnly Cookie → JS から読めないため XSS で盗めないが、自動送信されるため CSRF のリスクがある
- localStorage → 自動送信されないため CSRF は起きないが、JS から自由に読めるため XSS で盗まれる
現代のベストプラクティスは httpOnly Cookie + SameSite 属性の組み合わせで、XSS と CSRF の両方に対策する。
XSS(Cross-Site Scripting)
学んだこと
- XSS は悪意ある JavaScript がサイト上で実行されてしまう攻撃
- localStorage に保存した認証情報は XSS で容易に窃取される
- httpOnly Cookie は JS からアクセスできないため、XSS による窃取を防げる
CSRF(Cross-Site Request Forgery)と SameSite Cookie
学んだこと
- CSRF は別サイトからユーザーの Cookie を利用してリクエストを送る攻撃
- httpOnly は「JS から読めない」だけで「送信されない」わけではないため、Cookie の自動送信を利用した CSRF は防げない
SameSite属性で CSRF を防御できる
詳細
SameSite の3段階
| 値 | 動作 |
|---|---|
Strict |
別サイトからのリクエストには一切 Cookie を付けない。安全だが、外部リンクからの遷移時にもログアウト状態になる不便さがある |
Lax |
別サイトからの GET(リンククリック)は許可、POST は拒否。安全性と利便性のバランスが良く、広く使われている |
None |
制限なし。別サイトからでも全て Cookie を付ける(Secure 属性が必須) |
「Lax」は英語で「緩い、ゆるやか」の意味。Strict ほど厳格ではないが実用的な保護を提供する。
Next.js Server Actions をプロキシとして使うアーキテクチャ
学んだこと
- 外部 API が CORS を許可していない場合、ブラウザから直接呼べないため、サーバーサイドを経由する必要がある
- Next.js の Server Actions はこの「プロキシ」の役割を果たせる
- この構成にすると静的ホスティング(Cloudflare Pages 等)にはデプロイできず、Node.js が動くサーバー環境が必要になる
- ファイルシステム書き込みやシングルトンパターンを使っている場合、Edge Runtime(Cloudflare Workers 等)との互換性もない
メタ情報
- ツール: Claude Code
- 関連技術: CORS, HTTP, ブラウザセキュリティ, Cookie, セッション, XSS, CSRF, SameSite, Next.js, Server Actions