CSRFとは?仕組み・被害例・対策をわかりやすく解説

Vulnerability

「ログインしたまま別のサイトを見ていただけなのに、勝手にパスワードが変更されていた」「知らないうちにSNSで意図しない投稿がされていた」――こうした被害を引き起こす攻撃手法がCSRF(クロスサイトリクエストフォージェリ)です。

CSRFはXSSやSQLインジェクションほど名前が知られていないものの、IPA(情報処理推進機構)への届出件数でも上位に入る、Webアプリケーションの代表的な脆弱性の一つです。ユーザーがログイン状態であることを悪用するため、「自分は何もしていないのに」という状況で被害が発生する厄介な攻撃です。

この記事では、CSRFの仕組み・被害パターン・具体的な防御策について、現場で実践できるレベルで解説します。「CSRFという言葉は聞いたことがあるけれど、何が起きるのかよく分からない」という方にも理解できるようまとめました。

CSRFとは?仕組み・被害例・対策をわかりやすく解説

CSRF(クロスサイトリクエストフォージェリ)とは?なぜ危険なのか

CSRF(Cross-Site Request Forgery)とは、Webサービスにログイン中のユーザーに対して、意図しないリクエスト(操作要求)を送信させる攻撃手法です。「Request Forgery(リクエストの偽造)」という名前の通り、ユーザー本人が意図していない操作を、本人の権限で実行させてしまいます。

CSRFが危険である理由は主に3つあります。

正規のセッションを悪用する: 攻撃者がパスワードを盗む必要はない。ユーザーがログイン中であれば、そのセッション(認証済みの接続状態)をそのまま利用できる
被害者自身の操作として処理される: サーバーから見ると「正規ユーザーからの正当なリクエスト」に見えるため、ログを確認しても攻撃と判別しにくい
ユーザーが被害に気づきにくい: 攻撃は別タブや不正サイトの裏側で実行されるため、被害者は操作が行われたこと自体を認識できないケースが多い

XSSが「ブラウザ上でスクリプトを実行させる攻撃」であるのに対し、CSRFは「ログイン済みユーザーの権限を借りて不正な操作を実行させる攻撃」です。攻撃の対象が「ブラウザ」か「Webアプリケーションの操作権限」かという違いを押さえておきましょう。

攻撃の仕組み ― CSRFはどのように成立するのか

CSRFの攻撃フローは、以下のステップで成立します。

1. ユーザーが対象サイトにログインする

まず、被害者となるユーザーがECサイト・ネットバンキング・業務システムなど、認証が必要なWebサービスにログインします。ログイン後、ブラウザにはセッションCookie(認証情報)が保存されます。

2. 攻撃者が罠ページを用意する

攻撃者は、対象サイトへの操作リクエストを自動送信する罠ページを別のドメインに設置します。罠ページには、たとえばパスワード変更や送金処理のリクエストをフォームやimgタグで仕込んでおきます。

3. ユーザーが罠ページにアクセスする

ユーザーがログイン状態のまま罠ページにアクセスすると、ブラウザが自動的にセッションCookieを付けて対象サイトにリクエストを送信します。対象サイトのサーバーは、正規ユーザーからの正当な操作だと判断し、リクエストを処理してしまいます。

この一連の流れで重要なのは、攻撃者がユーザーのパスワードやセッション情報を知る必要がないという点です。ブラウザが自動的にCookieを送信する仕組みを悪用しているため、ユーザーがログインさえしていれば攻撃が成立します。

CSRFで発生する具体的な被害

CSRFによる被害は「ログインユーザーが実行できる操作」の範囲で発生します。代表的な被害例を見てみましょう。

被害パターン 具体例 影響度
パスワードの不正変更 攻撃者が指定したパスワードに勝手に変更され、アカウントが乗っ取られる 重大
不正な送金・決済 ネットバンキングで攻撃者の口座に送金が実行される 重大
設定の不正変更 メールアドレスの変更、管理者権限の付与、セキュリティ設定の無効化など
意図しない投稿・発言 SNSや掲示板に攻撃者が用意した内容が投稿される
商品の不正購入 ECサイトでユーザーの登録済みクレジットカードで購入が実行される 重大

特に注意が必要なのは、管理画面を持つ業務システムやCMSです。管理者がCSRFの被害を受けると、ユーザーアカウントの一括削除や設定ファイルの書き換えなど、システム全体に影響する操作が実行される恐れがあります。

具体的な防御手順

CSRFの防御は「リクエストが正規の画面操作から送信されたものかどうかを検証する」ことが基本です。以下の対策を組み合わせましょう。

1. CSRFトークンを実装する

最も効果的で広く採用されている対策です。フォームの送信時に、サーバーが発行した一意のトークン(推測不可能なランダム文字列)を隠しフィールドに埋め込み、リクエスト受信時にサーバー側で照合します。

# HTMLフォームへのトークン埋め込み例 # <form method="POST" action="/change-password"> # <input type="hidden" name="csrf_token" value="ランダムな文字列"> # <input type="password" name="new_password"> # <button type="submit">変更する</button> # </form>

攻撃者は罠ページからリクエストを送信することはできても、正規ページに埋め込まれたCSRFトークンの値を知ることはできません。トークンが一致しなければサーバーはリクエストを拒否するため、CSRFが成立しなくなります。

主要なWebフレームワークには、CSRFトークンを自動生成・検証する仕組みが標準で搭載されています。

# フレームワーク別のCSRFトークン機能 # Django: {% csrf_token %} テンプレートタグ + CsrfViewMiddleware # Laravel: @csrf ディレクティブ + VerifyCsrfToken ミドルウェア # Rails: protect_from_forgery メソッド + authenticity_token # Spring Security: CsrfFilter(デフォルトで有効)

2. SameSite属性をCookieに設定する

CookieのSameSite属性は、異なるサイトからのリクエストにCookieを自動送信するかどうかを制御します。CSRFは「別サイトからのリクエストにCookieが付与される」ことを悪用するため、SameSite属性はCSRF対策として非常に有効です。

# SameSite属性の設定値 # Strict: 異なるサイトからのリクエストには一切Cookieを送信しない(最も厳格) # Lax: GETリクエストのみCookieを送信する(推奨設定) # None: すべてのリクエストでCookieを送信する(Secure属性が必須) # PHPでの設定例 # session.cookie_samesite = Lax(php.iniで設定)

現在の主要ブラウザはSameSite属性が未指定の場合「Lax」をデフォルトとして扱いますが、古いブラウザではこの挙動が保証されません。明示的に設定しておくことが推奨されます。

3. Originヘッダー・Refererヘッダーを検証する

ブラウザがリクエスト時に送信するOriginヘッダーやRefererヘッダーを確認し、リクエストが自サイトから送信されたものかどうかを検証する方法です。

# サーバー側での検証イメージ(擬似コード) # if request.headers['Origin'] != 'https://example.com': # return 403 Forbidden

OriginヘッダーはPOSTリクエストで送信されるため、CSRF対策の補助として有効です。ただし、Refererヘッダーはプライバシー設定やプロキシによって送信されないケースがあるため、これだけに頼るのは避けてください。CSRFトークンとの併用が推奨されます。

4. 重要な操作に再認証を要求する

パスワード変更、送金、メールアドレス変更など、影響が大きい操作の前に現在のパスワードの再入力やワンタイムパスワードの確認を求める方法です。

再認証はCSRF対策としてだけでなく、セッションハイジャック(セッション情報を盗んでなりすます攻撃)への対策としても有効です。ユーザーの利便性との兼ね合いから、すべての操作に適用するのではなく、影響が重大な操作に絞って導入するのが現実的です。

中小企業でも今日からできること

「自社でWebアプリケーションを開発していないから関係ない」と思いがちですが、WordPressなどのCMSや業務用のWebシステムを使っているなら、CSRFの対策は必要です。

対策 内容 コスト
CMS・プラグインの更新 WordPress等のCMSとプラグインを最新版に保つ。CSRF対策の修正が含まれるアップデートは少なくない 無料
管理画面へのIP制限 管理画面のURLにIP制限をかけ、外部からのアクセスを遮断する。CSRFの攻撃対象を減らせる 無料
ブラウザの使い分け 業務システムのログインと日常的なWeb閲覧を別ブラウザで行う。同一ブラウザでの罠ページアクセスを防げる 無料
自動ログアウトの設定 一定時間操作がない場合にセッションを自動で切断する。ログイン状態が長時間放置されるリスクを軽減する 無料
開発会社への確認 自社Webシステムの状態変更処理(パスワード変更、設定変更等)にCSRFトークンが実装されているか確認する 無料

特に効果が高いのは「管理画面へのIP制限」と「CMS・プラグインの更新」です。管理画面が外部からアクセスできない状態であれば、たとえCSRFの脆弱性が存在しても攻撃者がリクエストの送信先として悪用する余地が大幅に減ります。

WordPressの場合、/wp-admin/ へのアクセスを社内ネットワークやVPN経由に限定するだけで、CSRF以外の攻撃リスクも同時に下げられます。

よくある誤解と注意点

【注意】「GETリクエストでは被害が起きない」は誤解

CSRF対策の文脈で「POSTリクエストだけ守ればよい」という説明を見かけることがありますが、これはWebアプリケーションの設計が正しいことが前提です。パスワード変更や削除処理をGETリクエストで受け付けるように作られたシステムでは、imgタグのsrc属性にURLを仕込むだけでCSRFが成立します。状態を変更する処理は必ずPOSTメソッドで実装し、GETでは受け付けない設計にすることが大前提です。

【注意】「CSRFトークンさえ入れれば安全」ではない

CSRFトークンの実装にも落とし穴があります。トークンの生成に予測可能な値(タイムスタンプやユーザーIDのハッシュなど)を使っている場合、攻撃者に推測される恐れがあります。また、トークンの検証をスキップするロジック(トークンが空の場合は検証しない等)が残っていると、攻撃者はトークンを付けずにリクエストを送るだけで突破できてしまいます。暗号論的に安全な乱数生成器で十分な長さのトークンを生成し、検証は必ず行う実装が求められます。

【注意】「APIだからCSRF対策は不要」は危険な思い込み

REST APIでCookieベースの認証を使用している場合、CSRFのリスクがあります。APIであってもブラウザから呼び出される可能性がある場合は、CSRFトークンの検証またはカスタムヘッダー(X-Requested-Withなど)の確認を行いましょう。Bearer Token認証やAPI Key認証のようにCookieを使わない認証方式であれば、CSRFのリスクは発生しません。

本記事のまとめ

CSRF(クロスサイトリクエストフォージェリ)は、ログイン中のユーザーの権限を悪用し、本人が意図しない操作をWebアプリケーション上で実行させる攻撃手法です。パスワードの不正変更、不正送金、設定の改ざんなど、ログインユーザーが実行できるあらゆる操作が被害対象となり得ます。

防御の基本は「CSRFトークンの実装」です。これにCookieのSameSite属性設定、Originヘッダーの検証、重要操作での再認証を組み合わせることで、堅実な多層防御を構築できます。

脅威 対策 優先度
不正なリクエストの送信 CSRFトークンの実装と検証 最優先
外部サイトからのCookie送信 CookieのSameSite属性設定(Lax推奨) 最優先
異なるオリジンからのリクエスト Origin / Refererヘッダーの検証
重要操作の不正実行 パスワード再入力・ワンタイムパスワードによる再認証
既知の攻撃パターン CMS・プラグインの最新版更新

CSRFと併せて押さえておきたいXSSやSQLインジェクションの対策については、本サイトの関連記事で詳しく解説しています。Webアプリケーションの脆弱性対策は、一つの攻撃手法だけでなく複数の脅威を横断的に理解することが重要です。

WebサーバーのセッションCookie設定やApacheのセキュリティヘッダー設定については、姉妹サイトLinuxMaster.JPで詳しく解説しています。サーバー設定とアプリケーション対策を組み合わせることで、より堅牢なWeb環境を構築できます。

自社のWebシステム、CSRF対策は万全ですか?

CSRFをはじめとするWebアプリケーションの脆弱性は、正しい知識と適切な実装で防御力を大きく高められます。
正しいセキュリティ知識を体系的に身につけたい方へ、メルマガで実践的なセキュリティ対策ノウハウをお届けしています。

コメント

タイトルとURLをコピーしました