この記事の目的
CORSとCSRFは頻繁に混同されます
理由は
- どちらもブラウザで起きる
- どちらもクロスオリジンが絡む
- 設定を間違えると突然動かない
からです
本記事はガイドというより
混乱ポイントを最短で整理して
設計と実装の判断ができる状態にする ことが目的です
先に結論
- CORSはブラウザの読み取り制限 であり サーバー防御ではない
- CSRFは Cookie自動送信 を悪用した攻撃
- SameSiteは Cookieの送信条件 を調整する
- トークン方式 JWTなど でもCSRFがゼロとは限らない 設計次第
用語の最小定義
- オリジン scheme host port の組
- クロスオリジン オリジンが異なる通信
例
- https://app.example.com と https://api.example.com はクロスオリジン
- https://example.com と http://example.com もクロスオリジン
CORSは何を守っているのか
CORSはブラウザが実装している安全装置です
悪意あるページが
ユーザーのブラウザを使って別オリジンの情報を読み取る のを防ぎます
重要
CORSは サーバー側の認可や認証 を代替しません
curlやサーバー間通信には効きません
なぜ自分のAPIがブラウザから読めないのか
ブラウザは基本的に
他オリジンのレスポンスをJSから読ませない
というルールを持ちます
だから
- APIは返している
- でもフロントが読めない
が起きます
プリフライトが起きる条件
次のいずれかでOPTIONSが先に飛びます
- Content-Typeがapplication/json
- Authorizationヘッダを付ける
- PUT PATCH DELETEなど単純でないメソッド
プリフライトは
ブラウザが 許可されているか を事前確認する仕組みです
CSRFは何を狙うのか
CSRFは
ユーザーの意思と無関係に 攻撃者が状態変更リクエストを送らせる 攻撃です
成立条件の中心は
- Cookieが自動で送られる
ことです
ユーザーがログイン済みで
攻撃者サイトを開くと
その攻撃者サイトから
銀行の送金APIへPOSTが飛び
Cookieが付いてしまう
という形です
CORSはこの攻撃を防ぎません
なぜなら
CSRFは 読み取り ではなく 書き込み 状態変更 が目的だからです
SameSiteは何を変えるのか
SameSiteはCookieの属性で
クロスサイトのときCookieを送るかどうか を制御します
- Lax 多くのケースで安全寄り GETのトップレベル遷移など限定
- Strict ほぼ送らない
- None 送るが Secure必須
重要
SameSiteだけでCSRFが完全に消えるわけではありません
要件によってNoneが必要な場合もあり
その場合は別の対策が必要です
よくある構成別の結論
構成A 同一オリジンでWebアプリ
- CORSは不要
- CSRFはCookieセッションなら要対策
対策
- CSRFトークン
- SameSite=LaxやStrict
構成B SPAとAPIが別サブドメイン
- CORSが必要
- Cookieを使うならCSRFも必要
おすすめ
- BFFを挟んで同一オリジン化できるなら強い
- できないなら CORS + CSRF + Cookie属性 をセットで設計
構成C AuthorizationヘッダのBearerトークン
- CORSは依然必要
- CSRFは原理的に起きにくい
ただし注意
- トークンがCookieに入っているならCSRF再燃
- XSSでトークンを盗まれるリスクが増える
つまり
CSRFが減る代わりにXSS対策の重要度が上がる というトレードです
実務チェックリスト
CORS
- Access-Control-Allow-Originをワイルドカードにしていない
- Authorizationを使うなら allow-headersに含める
- Cookie送信なら allow-credentials true と originの完全指定
- OPTIONSのレスポンスが速い
CSRF
- Cookieセッションを使うならCSRFトークンかSameSite設計がある
- 状態変更はPOST PUT PATCH DELETEに限定している
- Referer Originチェックを補助として検討している
Cookie
- Secureを付ける
- HttpOnlyを付ける JSから読ませない
- SameSiteの選択理由が説明できる
まとめ
混乱を終わらせる一番のコツは
- CORSは読み取り制限
- CSRFはCookie自動送信の悪用
- SameSiteはCookie送信条件
と役割を分けて考えることです
この整理ができると
なぜ動かないか 何を守れていないか が判断できるようになります