Webサイトの安全を守る仕組み
CSRFとは?ログイン中に勝手に操作される仕組みと防ぎ方をやさしく図解
通販サイトにログインしたまま別のページを開いただけで、住所や設定が勝手に変えられてしまう。そんな「本人は押していないのに、本人の操作に見える」問題を、順番に見ていきましょう。
1. 知らないうちに住所が変わる?
たとえば、通販サイトにログインして買い物かごを見たあと、友達から届いたリンクを開いたとします。そこには「おすすめ商品はこちら」と書かれていました。
ところが、リンク先のページには見えない送信処理が仕込まれていました。通販サイトの「お届け先住所を変更する」機能に対して、あなたのブラウザからリクエストが送られます。
もちろん、現実の攻撃がいつでも成功するわけではありません。Cookieの設定やWebサイトの保護策によって防げます。仕組みを知ることで、何が守りになるのかが分かります。
3. 攻撃の流れを3人の登場人物で見る
- あなたが通販サイトにログインしている。
- 別のページを開くと、ブラウザが通販サイト宛のリクエストを送ろうとする。
- 送信条件が許せば、ブラウザは通販サイト用Cookieも添える。
- 通販サイトが「Cookieがあるから本人の意思に違いない」と扱うと、変更処理が進んでしまう。
4. 守り方①:秘密の合言葉を確認する
最も基本的な対策のひとつがCSRFトークンです。住所変更画面を開いた利用者に対し、サーバが予測困難な値を用意し、変更時にその値が正しいか照合します。
攻撃者の別サイトは、通常は同一オリジンポリシーによって通販サイトの正規ページからトークンを読み取れません。したがって、有効なトークンを付けられず不正リクエストを拒否されます。
トークンはサーバ側でセッションと結び付けて照合する方式などを利用します。推測可能な値にしたり、Cookieにしか入れていなかったり、存在するだけで検証しなかったりすると意味がありません。XSSが存在すると、トークンが読み取られる場合があることにも注意が必要です。
5. 守り方②:Cookieと送信元を確かめる
SameSite Cookie
Cookieに SameSite=Lax や SameSite=Strict を設定することで、クロスサイトのリクエストでCookieが送られる場面を制限できます。Secure 属性も併用するのが一般的です。
ただしSameSiteだけを万能視しないこと。Laxでもトップレベルの安全とみなされるナビゲーションでは送信され得ます。GETで重要な状態を変更しないことも重要です。またSameSiteは「サイト」単位であり「オリジン」単位とは一致しません。
Origin / Referer の検証
サーバはリクエスト元を示す Origin や Referer ヘッダーを確認できます。想定した送信元でない場合、更新処理を拒否する補助対策です。
ただしRefererはプライバシー設定・ポリシー・ブラウザ挙動で欠落することがあります。欠落したら何でも許す設計にせず、Originの確認やFetch Metadataなどを組み合わせて扱う必要があります。
重要な操作では再確認
振込先変更や決済確定など、被害の大きい操作ではパスワード再入力や再認証、取引内容の再確認も防御になります。ただし毎回の再認証は利用者負担が増すため、リスクに応じて採用します。
6. 体験:対策を切り替えてみよう
通販サイトで「お届け先を変更する」場面をシミュレーションします。攻撃者のページからの要求がサーバに届いたとき、どの対策なら拒否できるかを切り替えて確認しましょう。
通販サイトの住所変更を守れる?
すべて架空のデータです。スイッチを変えて「判定する」を押してください。
送信しようとしている操作
newAddress = 架空の配送先
この画面は実際の通信を行いません。LaxのGETは「クロスサイトからのトップレベルナビゲーション」を想定しています。サブリソース取得やPOSTでは挙動が異なります。
このラボは概念を理解するためのローカルな模擬判定です。実際にリクエストを外部サイトへ送ることはありません。
7. CSRFとXSSは何が違う?
名前は似ていますが、悪用するポイントが違います。
| 比較 | CSRF | XSS |
|---|---|---|
| 困ること | 本人が望まない操作を実行される | Webページ上で不正なスクリプトを実行される |
| よくある原因 | Cookieの認証だけで更新処理を許す | 表示データを適切に処理せずHTMLなどに埋め込む |
| 代表的な対策 | CSRFトークン、SameSite、送信元検証 | 出力文脈に合ったエスケープ、危険なHTML操作の回避、CSPなど |
< を < に置き換える処理は、HTMLとしての解釈を防ぐための出力時エスケープに関係します。ブラウザが勝手に送る「住所変更リクエスト」を止める仕組みではありません。なお、入力時に一律置換すればXSS対策が完成するわけでもなく、出力する場所に適した処理が必要です。8. 実際のWeb開発で気をつけること
会員情報の変更、配送先の登録、支払い操作、メールアドレス変更のように、サーバの状態が変わる機能は特に注意します。
- ログインセッションをCookieで管理している場合、更新処理にCSRF防御を設ける。
- GETは情報の取得に使い、状態変更を行わない。POST等を使うだけでCSRFが防げるわけではない。
- フレームワーク提供のCSRF対策を適切に有効化し、APIの認証方式も確認する。
- トークンは照合し、機密性を保ち、URLやアクセスログへの流出を避ける。
- SameSite・Origin/Referer・Fetch Metadataなどは多層防御として検討する。
- XSSの防御も別途行う。XSSが成立するとCSRF防御が破られる場合がある。
特にSPAやAPIでは、Cookie認証なのか、JavaScriptが管理する認証ヘッダーなのかによってCSRFの攻撃条件が変わります。CORSを設定しただけでCSRFを防げると考えるのも危険です。
9. よくある疑問
Q. HTTPSならCSRFは防げますか?
防げません。HTTPSは通信を暗号化し、通信相手を検証する仕組みです。ログイン中のブラウザが意図しない操作を送る問題とは別です。
Q. 別サイトがCookieの中身を読めないなら安全では?
Cookieの値を読めなくても、ブラウザがCookieを自動送信する場合があります。これがCSRFの重要なポイントです。
Q. CSRFトークンは毎リクエスト必ず更新しますか?
必須ではありません。セッション単位で利用する設計もあります。発行方法と検証方法、使いやすさとのバランスが重要です。
Q. 認証なしのフォームでもCSRFを気にする必要は?
典型的なCSRFはブラウザに残る認証状態を利用します。ただし、認証なしでも望まない状態変更を起こせる機能は、別の観点から保護が必要です。
10. まとめ
CSRFとは、ログイン中のブラウザに、利用者が意図しない操作を送らせる攻撃です。サイトにCookieが送られてきたことだけでは、利用者が本当に操作を望んでいるかまでは分かりません。
そのため、CSRFトークンで操作を確認し、SameSite Cookieや送信元検証でリクエストを制限します。HTMLの特殊文字を置換する対策は主にXSSの文脈で使うもので、CSRF対策とは役割が違います。
「ログインしている人」と「いま操作を望んでいる人」を区別する。この考え方を持つと、対策の意味が整理できます。