Web セキュリティ

CSRF (クロスサイトリクエストフォージェリ)

約 3 分で読めます

CSRF (クロスサイトリクエストフォージェリ) とは

CSRF (Cross-Site Request Forgery) とは、ユーザーが認証済みの Web サイトに対して、ユーザーの意図しないリクエストを送信させる攻撃手法です。攻撃者は罠となる Web ページやメールを用意し、被害者がそれを閲覧した瞬間に、被害者のブラウザから標的サイトへ不正なリクエストが自動送信されます。

ブラウザは同一ドメインへのリクエストにCookie を自動的に付与するため、被害者がログイン中であれば、攻撃者のリクエストも認証済みとして処理されます。パスワード変更、送金、メールアドレスの変更、商品の購入など、状態を変更する操作が攻撃の標的になります。

攻撃の仕組みと具体例

CSRF 攻撃は以下の流れで実行されます。

  1. 被害者が標的サイト (例: オンラインバンキング) にログインし、セッション Cookie がブラウザに保存される
  2. 被害者が攻撃者の用意した罠ページを閲覧する (メールのリンク、掲示板の投稿など)
  3. 罠ページに埋め込まれた HTML や JavaScript が、被害者のブラウザから標的サイトへリクエストを送信する
  4. ブラウザがセッション Cookie を自動付与するため、標的サイトは正規のリクエストとして処理する

例えば、送金機能が POST /transfer?to=attacker&amount=100000 のようなリクエストで動作する場合、攻撃者は罠ページに自動送信フォームを埋め込むだけで、被害者の口座から送金を実行できます。

XSS と混同されやすいですが、CSRF は攻撃者のスクリプトを被害者のブラウザで実行するのではなく、被害者のブラウザから正規のリクエストを偽造する点が根本的に異なります。

防御策の実装

CSRF 対策は、リクエストが正規のユーザーの意図に基づくものであることを検証する仕組みを導入することが核心です。

CSRF トークン

サーバーがフォームの表示時にランダムなトークンを生成し、hidden フィールドに埋め込みます。フォーム送信時にトークンの一致を検証することで、外部サイトからの偽造リクエストを拒否します。トークンはセッションごとに一意であり、攻撃者は被害者のトークンを知ることができません。

SameSite Cookie 属性

CookieSameSite 属性を設定することで、クロスサイトリクエストへの Cookie 付与を制御できます。

  • SameSite=Strict: 外部サイトからのすべてのリクエストに Cookie を付与しない。最も安全だが、外部リンクからのアクセス時にもログイン状態が維持されない
  • SameSite=Lax: トップレベルナビゲーション (リンクのクリック) の GET リクエストにのみ Cookie を付与する。POST リクエストには付与されないため、多くの CSRF 攻撃を防げる
  • SameSite=None: クロスサイトリクエストにも Cookie を付与する。Secure 属性との併用が必須

その他の対策

  • Origin / Referer ヘッダーの検証: リクエストの送信元が自サイトであることを確認する。ただし、プライバシー設定やプロキシにより Referer が送信されない場合がある
  • カスタムヘッダーの要求: X-Requested-With などのカスタムヘッダーを要求する。ブラウザの同一オリジンポリシーにより、クロスサイトリクエストにカスタムヘッダーを付与するには CORS のプリフライトが必要になるため、CSRF を防止できる
  • セキュリティヘッダーの適切な設定: 全体的なセキュリティ姿勢を強化する

モダンフレームワークでの CSRF 対策

現代の Web フレームワークの多くは、CSRF 対策を組み込みで提供しています。

  • Django: {% csrf_token %} テンプレートタグで自動的にトークンを埋め込み、ミドルウェアで検証する
  • Ruby on Rails: protect_from_forgery で自動的に CSRF トークンの生成と検証を行う
  • Spring Security: デフォルトで CSRF 保護が有効。CsrfToken をフォームに自動挿入する
  • Next.js / SPA: API ルートでは SameSite Cookie と Origin ヘッダーの検証を組み合わせる。WAF による追加の保護も検討する

フレームワークの CSRF 保護を無効化する場合は、代替の対策が確実に実装されていることを検証してください。API エンドポイントで CSRF 保護を除外する場合は、認証トークン (Bearer Token) による認証に切り替え、Cookie ベースの認証を使用しないことが前提です。

よくある誤解

GET リクエストでは CSRF は発生しない
GET リクエストでも状態を変更する操作 (削除、設定変更など) を実装していれば CSRF の対象になる。img タグの src 属性に URL を設定するだけで GET リクエストを送信できるため、状態変更は必ず POST/PUT/DELETE で実装すべき。
HTTPS を使っていれば CSRF は防げる
HTTPS は通信の暗号化と改ざん防止を提供するが、CSRF とは無関係。CSRF は正規のユーザーのブラウザから正規のリクエストを送信させる攻撃であり、通信が暗号化されていても攻撃は成立する。

関連用語

関連記事