【初心者向け】CSRFとは?仕組み・XSSとの違い・対策方法をやさしく解説
Webシステムの開発やセキュリティに関わると、CSRFという言葉を目にすることがあります。
「CSRFはどのような攻撃なの?」
「ログインしているだけで被害に遭うの?」
「XSSとは何が違うの?」
このような疑問を持つIT業務初心者の方は少なくありません。
CSRFとは、ログイン中の利用者をだまして、本人が意図していない操作をWebサイトへ実行させる攻撃です。
例えば、利用者がログインしているネットバンキングや会員サイトに対して、勝手に送金、設定変更、商品購入などを実行させる可能性があります。
この記事では、CSRFの基本的な仕組み、被害の具体例、XSSとの違い、開発時に必要な対策方法を、IT業務に従事する初心者向けに分かりやすく解説します。
- CSRFとは?
- CSRFを一言で表すと?
- CSRFを身近な例で考えてみよう
- CSRFが成立する基本的な条件
- CSRF攻撃の流れ
- Cookieが悪用される理由
- CSRFの具体例
- 簡単なCSRF攻撃のイメージ
- GETとPOSTの違い
- CSRFとXSSの違い
- CSRFとセッションハイジャックの違い
- CSRFとクリックジャッキングの違い
- CSRF対策の基本
- CSRFトークンとは?
- CSRFトークンを使ったフォーム例
- CSRFトークンに必要な条件
- SameSite Cookieとは?
- SameSite=Strictとは?
- SameSite=Laxとは?
- SameSite=Noneとは?
- SameSite属性だけで十分?
- Originヘッダーの確認
- Refererヘッダーの確認
- 重要な操作では再認証を求める
- 更新処理をGETで実行しない
- フレームワークのCSRF対策機能を使う
- APIでもCSRF対策は必要?
- Cookie認証とトークン認証の違い
- JSONならCSRFは防げる?
- CORSはCSRF対策になる?
- CSRF対策でよくある間違い
- CSRF対策の実装手順
- CSRF対策のテスト方法
- CSRF攻撃を受けた場合の被害
- 管理画面では特に注意する
- CSRFとログアウトの関係
- IT業務で確認するポイント
- よくある質問
- IT業務初心者が覚えておきたいポイント
- 関連して覚えておきたい用語
- まとめ
CSRFとは?
CSRFは、Cross-Site Request Forgeryの略です。
日本語では、クロスサイト・リクエスト・フォージェリやリクエスト強要と呼ばれます。
簡単にいうと、利用者がログイン中のWebサイトへ、攻撃者が不正なリクエストを送らせる攻撃です。
利用者がWebサイトへログイン中 ↓ 攻撃者の用意したページを開く ↓ 本人のブラウザーから不正なリクエストが送られる ↓ Webサイトが本人の操作だと誤認する
攻撃者が利用者のパスワードを直接知らなくても、ログイン済みの状態を悪用できる点が特徴です。
CSRFを一言で表すと?
CSRFを一言で表すと、本人のログイン状態を勝手に使って操作させる攻撃です。
利用者本人が正規のWebサイトへログインしているため、ブラウザーにはログイン情報を示すCookieなどが保存されています。
攻撃者は、この状態を利用して、利用者のブラウザーから不正な操作を送信させます。
CSRFを身近な例で考えてみよう
CSRFは、本人の印鑑を悪用して、知らないうちに書類へ押印させるような攻撃です。
例えば、会社で本人確認済みの印鑑を持っている社員がいるとします。
攻撃者が別の書類を本人に気付かれないように差し出し、その印鑑を押させると、会社側は本人が承認した書類だと判断してしまいます。
CSRFでも、Webサイトはログイン済みのCookieを確認し、本人から届いた正しい操作だと誤認することがあります。
CSRFが成立する基本的な条件
CSRFは、主に次の条件がそろった場合に成立しやすくなります。
- 利用者が対象のWebサイトへログインしている
- ログイン状態がCookieなどで維持されている
- 重要な操作にCSRF対策がない
- 攻撃者が不正なリクエストを作成できる
- 利用者が攻撃用のページやリンクを開く
特に、Cookieがブラウザーから自動送信される仕組みが悪用されます。
CSRF攻撃の流れ
CSRF攻撃は、次のような流れで行われます。
- 利用者が正規のWebサイトへログインする
- ブラウザーへログイン用のCookieが保存される
- 利用者が攻撃者の用意したページを開く
- 攻撃用ページから正規サイトへリクエストが送信される
- ブラウザーがログインCookieを自動送信する
- 正規サイトが本人の操作だと誤認する
- 意図していない処理が実行される
正規サイトへログイン ↓ Cookieが保存される ↓ 攻撃用サイトを開く ↓ 正規サイトへ不正リクエスト ↓ Cookieも自動送信 ↓ 本人の操作として処理される
Cookieが悪用される理由
Cookieは、ログイン状態や利用者情報をブラウザーへ保存する仕組みです。
利用者がWebサイトへログインすると、サーバーからセッションIDなどがCookieとして送られることがあります。
その後、ブラウザーは同じWebサイトへアクセスするたびにCookieを自動送信します。
ブラウザー ↓ Cookieを自動送信 Webサーバー
CSRFでは、この自動送信の仕組みが悪用されます。
攻撃者はCookieそのものを盗まなくても、利用者のブラウザーからCookie付きのリクエストを送らせることができます。
CSRFの具体例
登録メールアドレスを勝手に変更する
利用者が会員サイトへログイン中に、攻撃用ページを開いたとします。
攻撃用ページから、次のようなメールアドレス変更リクエストが送られる可能性があります。
POST /account/email/change
email=attacker@example.com
対策がなければ、登録メールアドレスを攻撃者のものへ変更される可能性があります。
パスワードを変更する
現在のパスワードを再入力せずにパスワード変更できるWebサイトでは、攻撃者がパスワードを変更するリクエストを送らせる可能性があります。
商品を購入する
ECサイトへログイン中の利用者に対して、商品購入や注文確定の操作を実行させる可能性があります。
送金先を変更する
金融サービスでは、振込先の登録や送金処理を勝手に実行されると、大きな被害につながる可能性があります。
管理者設定を変更する
管理画面へログイン中の管理者を狙い、ユーザー作成、権限変更、設定変更などを実行させる攻撃も考えられます。
簡単なCSRF攻撃のイメージ
例えば、正規サイトに次のようなURLで設定変更できる機能があるとします。
https://example.com/account/change-email?email=attacker@example.com
攻撃者は、このURLを画像タグなどに埋め込む可能性があります。
<img src="https://example.com/account/change-email?email=attacker@example.com">
利用者が攻撃用ページを開くと、ブラウザーが画像を読み込もうとして正規サイトへアクセスします。
そのときログインCookieも送信されると、メールアドレス変更処理が実行される可能性があります。
そのため、重要な更新処理をGETリクエストで実行する設計は避ける必要があります。
GETとPOSTの違い
| 項目 | GET | POST |
|---|---|---|
| 主な用途 | データの取得 | 登録・変更など |
| パラメーター | URLに含まれることが多い | リクエスト本文に含まれることが多い |
| 重要な更新処理 | 使用しない | 使用するがCSRF対策が必要 |
ただし、POSTを使うだけでCSRFを防げるわけではありません。
攻撃者はフォームを使ってPOSTリクエストを送信させることもできるため、CSRFトークンなどの対策が必要です。
CSRFとXSSの違い
CSRFと混同されやすい攻撃に、XSSがあります。
| 項目 | CSRF | XSS |
|---|---|---|
| 正式名称 | Cross-Site Request Forgery | Cross-Site Scripting |
| 主な目的 | 本人に意図しない操作をさせる | Webページ上で不正なスクリプトを実行する |
| 悪用するもの | ログイン状態やCookieの自動送信 | 入力値の不適切な出力 |
| 主な被害 | 設定変更、購入、送金など | Cookie窃取、画面改ざん、偽フォーム表示など |
| 代表的な対策 | CSRFトークン、SameSite Cookie | 出力時エスケープ、CSPなど |
CSRFは利用者の権限を悪用して操作を実行させる攻撃です。
XSSは、Webページ内で攻撃者のJavaScriptなどを実行させる攻撃です。
CSRFとセッションハイジャックの違い
| 項目 | CSRF | セッションハイジャック |
|---|---|---|
| Cookieを盗むか | 通常は盗まない | セッション情報を盗む |
| 操作する端末 | 被害者のブラウザー | 攻撃者自身の端末 |
| 主な特徴 | 被害者にリクエストを送らせる | 被害者になりすまして操作する |
CSRFでは、攻撃者がログインCookieの内容を知らなくても攻撃できる場合があります。
CSRFとクリックジャッキングの違い
クリックジャッキングは、利用者に見えない画面や偽のボタンを重ね、意図しない場所をクリックさせる攻撃です。
| 項目 | CSRF | クリックジャッキング |
|---|---|---|
| 攻撃方法 | 不正なリクエストを送信させる | 意図しない場所をクリックさせる |
| 利用者の操作 | ページを開くだけでも成立する場合がある | クリック操作が必要 |
| 代表的な対策 | CSRFトークン | frame-ancestors、X-Frame-Options |
CSRF対策の基本
CSRF対策として、主に次の方法があります。
- CSRFトークンを使用する
- CookieへSameSite属性を設定する
- OriginヘッダーやRefererヘッダーを確認する
- 重要な操作で再認証を求める
- 更新処理をGETで実行しない
- フレームワークのCSRF対策機能を利用する
CSRFトークンとは?
CSRFトークンとは、正規の画面から送信されたリクエストであることを確認するための、推測困難な値です。
サーバーが利用者ごと、またはセッションごとにトークンを発行します。
正規の画面を表示 ↓ サーバーがCSRFトークンを発行 ↓ フォームにトークンを埋め込む ↓ 送信時にサーバーが検証
攻撃者は正しいトークンを取得できないため、不正なリクエストを作成しにくくなります。
CSRFトークンを使ったフォーム例
正規のフォームへ、CSRFトークンを隠し項目として埋め込みます。
<form method="post" action="/account/email/change">
<input type="hidden" name="csrf_token" value="ランダムなトークン">
<input type="email" name="email">
<button type="submit">変更する</button>
</form>
サーバー側では、送られてきたトークンが正しいかを確認します。
トークンが正しい ↓ 処理を実行 トークンがない・不正 ↓ 処理を拒否
CSRFトークンに必要な条件
- 第三者が推測しにくい
- 十分な長さがある
- 暗号学的に安全な乱数で作成する
- 利用者やセッションと関連付ける
- URLへ不用意に含めない
- ログへ出力しない
短い連番やユーザーIDだけをトークンとして使う方法は適切ではありません。
SameSite Cookieとは?
SameSiteは、別のWebサイトからリクエストされたときに、Cookieを送信するかどうかを制御する属性です。
CookieへSameSite属性を設定することで、CSRF攻撃を防ぎやすくなります。
| 設定値 | 概要 |
|---|---|
| Strict | 異なるサイトからのリクエストでは、原則としてCookieを送らない |
| Lax | 一部の通常の画面遷移では送信するが、不正なPOSTなどでは制限する |
| None | 異なるサイトからでも送信する。Secure属性が必要 |
SameSite=Strictとは?
SameSite=Strictは、最も厳しい設定です。
外部サイトから対象サイトへ移動した場合でも、Cookieが送信されないことがあります。
CSRF対策として強力ですが、外部リンクからログイン済み状態でページを開きたい場合などに、利便性へ影響する可能性があります。
SameSite=Laxとは?
SameSite=Laxは、安全性と利便性のバランスを取った設定です。
通常のリンクによるページ移動ではCookieが送られることがありますが、外部サイトからのPOSTリクエストなどでは制限されます。
多くのWebサイトで候補となる設定です。
SameSite=Noneとは?
SameSite=Noneを設定すると、異なるサイトからのリクエストでもCookieを送信できます。
外部サービスとの連携や、別ドメインをまたぐ認証などで必要になる場合があります。
SameSite=Noneを使用する場合は、通常、Secure属性も設定し、HTTPS通信でのみCookieを送信します。
外部サイトからCookieが送られるため、CSRFトークンなど別の対策が重要です。
SameSite属性だけで十分?
SameSite属性は有効な対策ですが、それだけに依存しないことが重要です。
ブラウザーやシステム要件、サブドメイン構成、外部サービス連携などによって動作が異なる場合があります。
重要な更新処理では、CSRFトークンと組み合わせる方法が一般的です。
Originヘッダーの確認
Originヘッダーには、リクエストを送信した元のサイト情報が含まれる場合があります。
Origin: https://example.com
サーバー側で、正規のサイトから送信されたリクエストかを確認できます。
想定外のドメインから送信されたリクエストは拒否します。
Refererヘッダーの確認
Refererヘッダーには、リクエスト元となったページのURLが含まれる場合があります。
Referer: https://example.com/account/settings
正規のドメインから送信されたリクエストかを確認できます。
ただし、利用者の設定や通信環境によってRefererが送信されない場合もあるため、これだけに依存しない設計が必要です。
重要な操作では再認証を求める
次のような重要な操作では、ログイン済みでもパスワードや多要素認証を再度求める方法があります。
- パスワード変更
- メールアドレス変更
- 送金
- 退会
- 管理者権限の付与
- 多要素認証の解除
CSRFによって不正なリクエストが送信されても、追加認証がなければ処理できません。
更新処理をGETで実行しない
GETリクエストは、原則としてデータの取得に使用します。
次のような更新処理をGETで実行する設計は避けます。
- ユーザー削除
- メールアドレス変更
- 商品購入
- 設定変更
- ログアウト以外の重要処理
ただし、POSTへ変更するだけでは不十分であり、CSRFトークンなども必要です。
フレームワークのCSRF対策機能を使う
多くのWebフレームワークには、CSRF対策機能が用意されています。
例えば、次のような処理を自動で行う場合があります。
- CSRFトークンの生成
- フォームへの埋め込み
- 送信されたトークンの検証
- 不正リクエストの拒否
- エラーレスポンスの返却
独自に対策を実装するよりも、標準機能を正しく利用する方法が安全です。
APIでもCSRF対策は必要?
APIでCSRF対策が必要かどうかは、認証方法によって異なります。
Cookieを使って認証するAPIでは、ブラウザーがCookieを自動送信するため、CSRF対策が必要です。
一方、JavaScriptなどがAuthorizationヘッダーへアクセストークンを明示的に設定する構成では、一般的なCSRFの影響を受けにくい場合があります。
Authorization: Bearer アクセストークン
ただし、アクセストークンの保存方法やXSS対策など、別のセキュリティ対策が必要です。
Cookie認証とトークン認証の違い
| 項目 | Cookie認証 | Authorizationヘッダーによる認証 |
|---|---|---|
| 送信方法 | ブラウザーが自動送信 | アプリが明示的に設定 |
| CSRFの影響 | 受けやすい | 一般的には受けにくい |
| 注意点 | CSRF対策が必要 | トークン漏えいやXSS対策が必要 |
トークン認証を使えばすべて安全になるわけではありません。
認証情報をどこへ保存し、どのように送信するかを含めて設計する必要があります。
JSONならCSRFは防げる?
JSON形式のAPIは、通常のHTMLフォームから直接送信しにくいため、従来型のCSRF攻撃を受けにくい場合があります。
ただし、Content-Typeの検証が不十分だったり、別形式のリクエストも受け付けていたりすると、攻撃される可能性があります。
Cookie認証を利用する場合は、JSON APIでもCSRF対策を検討します。
CORSはCSRF対策になる?
CORSは、異なるオリジンからブラウザーでリソースへアクセスすることを制御する仕組みです。
ただし、CORSを設定しただけでCSRFを完全に防げるわけではありません。
単純なリクエストは、レスポンスをJavaScriptから読み取れなくても、サーバーへ送信される場合があります。
CORSとCSRFは目的が異なるため、CSRFトークンやSameSite Cookieなどの対策が必要です。
CSRF対策でよくある間違い
POSTにすれば安全だと思う
攻撃者はHTMLフォームを使ってPOSTリクエストを送信させることができます。
秘密のURLなら安全だと思う
URLがログや履歴、Refererなどから漏れる可能性があります。
Referer確認だけで十分だと思う
Refererが送信されない環境もあるため、単独の対策としては不十分です。
CORSだけ設定すればよいと思う
CORSはレスポンスの読み取りを制御する仕組みで、リクエスト送信自体を完全に防ぐものではありません。
SameSiteだけに依存する
互換性や要件によってCookieが送信される場合もあるため、重要処理ではCSRFトークンと組み合わせます。
トークンを固定値にする
すべての利用者で同じ値を使うと、攻撃者に推測・取得される可能性があります。
CSRF対策の実装手順
一般的な実装の流れは次のとおりです。
- フレームワークのCSRF機能を確認する
- 更新処理をPOST・PUT・PATCH・DELETEなどで実装する
- CSRFトークンを発行する
- フォームやリクエストへトークンを含める
- サーバー側でトークンを検証する
- CookieへSameSite・Secure・HttpOnly属性を設定する
- 重要操作で再認証を求める
- 不正リクエストをログへ記録する
- テストを実施する
CSRF対策のテスト方法
開発やテストでは、主に次の内容を確認します。
- CSRFトークンなしのリクエストが拒否されるか
- 不正なトークンが拒否されるか
- 別利用者のトークンが使えないか
- 期限切れトークンが拒否されるか
- 外部サイトからのPOSTが拒否されるか
- SameSite属性が適切に設定されているか
- 重要なGETリクエストで更新されないか
- APIにも必要な対策があるか
CSRF攻撃を受けた場合の被害
- 登録情報の変更
- パスワード変更
- メールアドレス変更
- 商品購入
- 送金
- 投稿やコメントの作成
- アカウント削除
- 管理者権限の変更
- 多要素認証の解除
利用者が持っている権限が強いほど、被害も大きくなる可能性があります。
管理画面では特に注意する
管理者アカウントがCSRF攻撃を受けると、一般利用者より大きな被害につながる可能性があります。
例えば、次のような操作を実行される可能性があります。
- 新しい管理者の追加
- 利用者情報の削除
- 公開設定の変更
- セキュリティ設定の無効化
- 外部連携先の変更
管理画面では、CSRFトークン、再認証、多要素認証、アクセス元制限などを組み合わせます。
CSRFとログアウトの関係
ログアウト処理も、CSRFによって勝手に実行される可能性があります。
ログアウトだけであれば直接的な情報漏えいにつながらない場合もありますが、利用者の操作を妨害できます。
そのため、ログアウトをGETリクエストで実行するかどうかも、システム要件に応じて検討します。
IT業務で確認するポイント
設計・開発・レビューでは、次の項目を確認します。
- Cookie認証を使用しているか
- 更新処理にCSRFトークンがあるか
- GETでデータ変更していないか
- SameSite属性が設定されているか
- Secure属性が設定されているか
- 重要処理で再認証しているか
- OriginやRefererを確認しているか
- フレームワークのCSRF機能を無効化していないか
- APIにも対策が必要か
- CSRFエラーが監視されているか
よくある質問
CSRFではパスワードを盗まれますか?
CSRFは、パスワードを直接盗む攻撃ではありません。
ログイン済みのブラウザーを利用して、本人に意図しない操作を実行させます。
攻撃者はCookieの内容を知っていますか?
通常、知る必要はありません。
ブラウザーがCookieを自動送信する性質を利用します。
ログインしていなければCSRF攻撃は成立しませんか?
多くの場合、ログイン状態や権限が必要です。
ただし、ログイン不要の操作でも、利用者固有の状態を変更できる機能があれば影響を受ける可能性があります。
POSTリクエストなら安全ですか?
安全とは限りません。
攻撃者は外部ページのフォームからPOSTリクエストを送信させることができます。
CSRFトークンがあれば完全に安全ですか?
適切に実装すれば有効な対策ですが、トークンが漏れたり、検証が不十分だったりすると攻撃される可能性があります。
SameSite Cookieや再認証などと組み合わせます。
SameSite=Laxだけで十分ですか?
システムの構成や重要度によって異なります。
重要な更新処理では、CSRFトークンも使用するのが一般的です。
JWTを使えばCSRF対策は不要ですか?
JWTをCookieへ保存し、ブラウザーが自動送信する構成では、CSRF対策が必要です。
Authorizationヘッダーへ明示的に設定する場合は、一般的なCSRFの影響を受けにくくなりますが、XSSやトークン管理への対策が必要です。
CORSを設定すればCSRFを防げますか?
CORSだけでは十分ではありません。
CSRFトークン、SameSite Cookie、Origin確認などを利用します。
CSRF対策を自分で作るべきですか?
基本的には、利用しているWebフレームワークが提供する標準機能を使います。
独自実装では、トークン生成や検証に不備が入る可能性があります。
IT業務初心者が覚えておきたいポイント
- CSRFはログイン中の利用者へ意図しない操作をさせる攻撃
- Cross-Site Request Forgeryの略
- Cookieが自動送信される仕組みを悪用する
- 攻撃者はパスワードやCookieの中身を知らなくても攻撃できる場合がある
- 設定変更、購入、送金などが被害につながる
- POSTへ変更するだけでは防げない
- 代表的な対策はCSRFトークン
- SameSite Cookieも有効な対策
- 重要な操作では再認証を求める
- 更新処理をGETで実行しない
- CORSとCSRF対策は別のもの
- フレームワークの標準機能を利用する
関連して覚えておきたい用語
- Cookie
- セッション
- CSRFトークン
- SameSite
- Secure属性
- HttpOnly属性
- Originヘッダー
- Refererヘッダー
- XSS
- CORS
- セッションハイジャック
- クリックジャッキング
- JWT
- 多要素認証
まとめ
CSRFとは、ログイン中の利用者をだまし、本人が意図していない操作をWebサイトへ実行させる攻撃です。
ブラウザーがログインCookieを自動送信する仕組みを悪用するため、攻撃者がパスワードやCookieの内容を直接知らなくても成立する場合があります。
被害としては、メールアドレス変更、商品購入、送金、アカウント設定変更、管理者操作などが考えられます。
主な対策は、CSRFトークン、SameSite Cookie、OriginやRefererの確認、重要操作での再認証です。
また、重要な更新処理をGETリクエストで実行せず、利用しているWebフレームワークの標準的なCSRF対策機能を有効にすることが重要です。
まずは、「CSRFは、ログイン中の利用者の権限を悪用して、本人に勝手な操作をさせる攻撃」と理解しておきましょう。
