サイトアイコン プログラマー(PG)・システムエンジニア(SE)になるための入門講座

【初心者向け】CSRFとは?仕組み・XSSとの違い・対策方法をやさしく解説

【初心者向け】CSRFとは?仕組み・XSSとの違い・対策方法をやさしく解説

Webシステムの開発やセキュリティに関わると、CSRFという言葉を目にすることがあります。

「CSRFはどのような攻撃なの?」
「ログインしているだけで被害に遭うの?」
「XSSとは何が違うの?」

このような疑問を持つIT業務初心者の方は少なくありません。

CSRFとは、ログイン中の利用者をだまして、本人が意図していない操作をWebサイトへ実行させる攻撃です。

例えば、利用者がログインしているネットバンキングや会員サイトに対して、勝手に送金、設定変更、商品購入などを実行させる可能性があります。

この記事では、CSRFの基本的な仕組み、被害の具体例、XSSとの違い、開発時に必要な対策方法を、IT業務に従事する初心者向けに分かりやすく解説します。


  1. CSRFとは?
  2. CSRFを一言で表すと?
  3. CSRFを身近な例で考えてみよう
  4. CSRFが成立する基本的な条件
  5. CSRF攻撃の流れ
  6. Cookieが悪用される理由
  7. CSRFの具体例
    1. 登録メールアドレスを勝手に変更する
    2. パスワードを変更する
    3. 商品を購入する
    4. 送金先を変更する
    5. 管理者設定を変更する
  8. 簡単なCSRF攻撃のイメージ
  9. GETとPOSTの違い
  10. CSRFとXSSの違い
  11. CSRFとセッションハイジャックの違い
  12. CSRFとクリックジャッキングの違い
  13. CSRF対策の基本
  14. CSRFトークンとは?
  15. CSRFトークンを使ったフォーム例
  16. CSRFトークンに必要な条件
  17. SameSite Cookieとは?
  18. SameSite=Strictとは?
  19. SameSite=Laxとは?
  20. SameSite=Noneとは?
  21. SameSite属性だけで十分?
  22. Originヘッダーの確認
  23. Refererヘッダーの確認
  24. 重要な操作では再認証を求める
  25. 更新処理をGETで実行しない
  26. フレームワークのCSRF対策機能を使う
  27. APIでもCSRF対策は必要?
  28. Cookie認証とトークン認証の違い
  29. JSONならCSRFは防げる?
  30. CORSはCSRF対策になる?
  31. CSRF対策でよくある間違い
    1. POSTにすれば安全だと思う
    2. 秘密のURLなら安全だと思う
    3. Referer確認だけで十分だと思う
    4. CORSだけ設定すればよいと思う
    5. SameSiteだけに依存する
    6. トークンを固定値にする
  32. CSRF対策の実装手順
  33. CSRF対策のテスト方法
  34. CSRF攻撃を受けた場合の被害
  35. 管理画面では特に注意する
  36. CSRFとログアウトの関係
  37. IT業務で確認するポイント
  38. よくある質問
    1. CSRFではパスワードを盗まれますか?
    2. 攻撃者はCookieの内容を知っていますか?
    3. ログインしていなければCSRF攻撃は成立しませんか?
    4. POSTリクエストなら安全ですか?
    5. CSRFトークンがあれば完全に安全ですか?
    6. SameSite=Laxだけで十分ですか?
    7. JWTを使えばCSRF対策は不要ですか?
    8. CORSを設定すればCSRFを防げますか?
    9. CSRF対策を自分で作るべきですか?
  39. IT業務初心者が覚えておきたいポイント
  40. 関連して覚えておきたい用語
  41. まとめ

CSRFとは?

CSRFは、Cross-Site Request Forgeryの略です。

日本語では、クロスサイト・リクエスト・フォージェリリクエスト強要と呼ばれます。

簡単にいうと、利用者がログイン中のWebサイトへ、攻撃者が不正なリクエストを送らせる攻撃です。

利用者がWebサイトへログイン中
  ↓
攻撃者の用意したページを開く
  ↓
本人のブラウザーから不正なリクエストが送られる
  ↓
Webサイトが本人の操作だと誤認する

攻撃者が利用者のパスワードを直接知らなくても、ログイン済みの状態を悪用できる点が特徴です。


CSRFを一言で表すと?

CSRFを一言で表すと、本人のログイン状態を勝手に使って操作させる攻撃です。

利用者本人が正規のWebサイトへログインしているため、ブラウザーにはログイン情報を示すCookieなどが保存されています。

攻撃者は、この状態を利用して、利用者のブラウザーから不正な操作を送信させます。


CSRFを身近な例で考えてみよう

CSRFは、本人の印鑑を悪用して、知らないうちに書類へ押印させるような攻撃です。

例えば、会社で本人確認済みの印鑑を持っている社員がいるとします。

攻撃者が別の書類を本人に気付かれないように差し出し、その印鑑を押させると、会社側は本人が承認した書類だと判断してしまいます。

CSRFでも、Webサイトはログイン済みのCookieを確認し、本人から届いた正しい操作だと誤認することがあります。


CSRFが成立する基本的な条件

CSRFは、主に次の条件がそろった場合に成立しやすくなります。

特に、Cookieがブラウザーから自動送信される仕組みが悪用されます。


CSRF攻撃の流れ

CSRF攻撃は、次のような流れで行われます。

  1. 利用者が正規のWebサイトへログインする
  2. ブラウザーへログイン用のCookieが保存される
  3. 利用者が攻撃者の用意したページを開く
  4. 攻撃用ページから正規サイトへリクエストが送信される
  5. ブラウザーがログインCookieを自動送信する
  6. 正規サイトが本人の操作だと誤認する
  7. 意図していない処理が実行される
正規サイトへログイン
  ↓
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トークンとは?

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トークンに必要な条件

短い連番やユーザー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対策機能が用意されています。

例えば、次のような処理を自動で行う場合があります。

独自に対策を実装するよりも、標準機能を正しく利用する方法が安全です。


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対策の実装手順

一般的な実装の流れは次のとおりです。

  1. フレームワークのCSRF機能を確認する
  2. 更新処理をPOST・PUT・PATCH・DELETEなどで実装する
  3. CSRFトークンを発行する
  4. フォームやリクエストへトークンを含める
  5. サーバー側でトークンを検証する
  6. CookieへSameSite・Secure・HttpOnly属性を設定する
  7. 重要操作で再認証を求める
  8. 不正リクエストをログへ記録する
  9. テストを実施する

CSRF対策のテスト方法

開発やテストでは、主に次の内容を確認します。


CSRF攻撃を受けた場合の被害

利用者が持っている権限が強いほど、被害も大きくなる可能性があります。


管理画面では特に注意する

管理者アカウントがCSRF攻撃を受けると、一般利用者より大きな被害につながる可能性があります。

例えば、次のような操作を実行される可能性があります。

管理画面では、CSRFトークン、再認証、多要素認証、アクセス元制限などを組み合わせます。


CSRFとログアウトの関係

ログアウト処理も、CSRFによって勝手に実行される可能性があります。

ログアウトだけであれば直接的な情報漏えいにつながらない場合もありますが、利用者の操作を妨害できます。

そのため、ログアウトをGETリクエストで実行するかどうかも、システム要件に応じて検討します。


IT業務で確認するポイント

設計・開発・レビューでは、次の項目を確認します。


よくある質問

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とは、ログイン中の利用者をだまし、本人が意図していない操作をWebサイトへ実行させる攻撃です。

ブラウザーがログインCookieを自動送信する仕組みを悪用するため、攻撃者がパスワードやCookieの内容を直接知らなくても成立する場合があります。

被害としては、メールアドレス変更、商品購入、送金、アカウント設定変更、管理者操作などが考えられます。

主な対策は、CSRFトークン、SameSite Cookie、OriginやRefererの確認、重要操作での再認証です。

また、重要な更新処理をGETリクエストで実行せず、利用しているWebフレームワークの標準的なCSRF対策機能を有効にすることが重要です。

まずは、「CSRFは、ログイン中の利用者の権限を悪用して、本人に勝手な操作をさせる攻撃」と理解しておきましょう。

モバイルバージョンを終了