CSRF
Cross-Site Request Forgery
概要(サマリー)
CSRF(クロスサイトリクエストフォージェリ)とは、あなたがログイン中のWebサイト(銀行やSNSなど)に対して、悪意のある別サイト経由で「勝手な操作」を命令される攻撃手法である。
たとえば、あなたが鍵を開けて入室している会員サイトがあるとする。そこにいる間、怪しいメールのリンクを踏んで別のWebサイト(悪意あるサイト)を開いてしまう。すると、その悪意あるサイトの裏側で「会員サイトのパスワードを変更せよ」「商品を注文せよ」という偽の命令書(リクエスト)が勝手に作られ、あなたのブラウザを通じて送信されてしまう。
会員サイト側は、あなたのブラウザから正しい手続き(ログイン済みの状態)で送られてきた命令であるため、偽物だと見抜けずに処理を実行してしまうのである。
詳細解説
CSRFが成立する仕組み
CSRF攻撃は、ブラウザが持つ「ログイン状態を維持する仕組み(Cookie)」を悪用して行われる。
通常、一度ログインしたWebサイトにアクセスする際、ブラウザは自動的にログイン情報のCookieをリクエストに添付して送信する。
攻撃者は、罠サイトを用意し、そこに「ターゲットサイトに特定のデータを送信するフォーム」や「ページを開いた瞬間にデータを送信するJavaScript」を仕込んでおく。ユーザーが罠サイトを踏むと、ブラウザは自動的にターゲットサイトへリクエストを送るが、この時にユーザー自身のCookieも一緒に添付されてしまう。その結果、ターゲットサイトは「本人からの正規のリクエスト」と判断して処理を受け入れてしまう。
CSRFで発生する被害の例
この攻撃によって、ユーザー自身が全く意図していない操作が勝手に実行されてしまう。
* 登録情報の改ざん: パスワードやメールアドレスを変更され、アカウントを乗っ取られる。
* 不正な書き込み: SNSなどで勝手に投稿されたり、掲示板に犯罪予告などを書き込まれたりする。
* 不正な決済: 買い物サイトで高額な商品を購入されたり、銀行サイトで勝手に送金されたりする。
CSRFの対策:ワンタイムトークン(CSRFトークン)
最も一般的な防御策は、フォーム送信時に「予測できない一時的な文字列(トークン)」を埋め込み、サーバー側で検証することである。
サーバーは、正規のページを表示する際に「CSRFトークン」というランダムな値を生成し、フォームの隠しフィールド(hidden)とユーザーのセッションの両方に保存する。
フォームが送信された際、サーバーは送られてきたトークンとセッション内のトークンが一致するかを確認する。罠サイトから送られたリクエストには、このランダムなトークンを含めることができないため、サーバー側で不正なリクエストとしてブロックできる。
CookieのSameSite属性による保護
近年では、Cookieに SameSite 属性を設定することで、外部のサイトから送られるリクエストにCookieを添付させないようにする対策も広く用いられている。
SameSite=Lax を設定すると、外部サイトからの画像読み込みやフォーム送信など、一部のクロスサイトリクエストではCookieが送信されにくくなる。一方で、通常のリンククリックのようなトップレベル遷移ではCookieが送信される場合があるため、CSRFトークンと組み合わせて考えるのが安全である。
SameSite=Strict はより強く制限するが、ログイン後の遷移や外部サイトからの流入で使い勝手に影響することがある。
AIコーディングとの関係
AIによるCSRF対策コードの生成
AIにWebフォームやログイン機能のコードを生成させると、多くの場合はフレームワーク標準のCSRF対策を組み込んだコードを出力してくれる。
しかし、プレーンなPHPやNode.js(Express)などでフォームの実装をゼロから指示した場合、CSRF対策が漏れてしまうことがある。AIに実装を依頼する際は、必ず「CSRF対策も考慮したセキュアなコードにしてください」と明示することが推奨される。
指示を出す際のポイント
AIにCSRF対策の実装を依頼する際は、以下のように具体的に指示すると、確実性の高い実装コードが得られる。
* 「Expressでフォーム送信を受け取るコードを書いて。ミドルウェアとして csurf(または最新の推奨パッケージ)を使ってCSRF対策を行って」
* 「HTMLフォーム内にCSRFトークンを埋め込む方法と、それをサーバーで検証するPHPのコードを書いて」
よくある勘違い
CSRFとXSSは同じもの?
全く異なる攻撃手法である。
* XSS(クロスサイトスクリプティング): サイト内に悪意のある「JavaScriptプログラム」を仕込んで実行させ、情報を盗み取る攻撃。
* CSRF: ユーザーのブラウザを利用して、標的サイトへ「偽の操作命令(リクエスト)」を送信させる攻撃。
XSSが「プログラムの実行」を狙うのに対し、CSRFは「ログイン状態を悪用したなりすまし操作」を狙うものである。
ログインしていなければCSRFの心配はない?
ログインが必要な操作(マイページ等)においては安全だが、ログイン不要の操作でも影響を受ける場合がある。
たとえば、ログイン不要のお問い合わせフォームであっても、CSRF攻撃によってスパムメールを大量に送信させられるなどの悪用をされる可能性がある。そのため、データ送信が発生するフォームには原則としてすべてCSRF対策を行うのが基本である。
CORSを設定していればCSRF対策は不要?
CORS(Cross-Origin Resource Sharing)はCSRF対策にはならない。
CORSは「外部サイトからAPIのレスポンス(返ってきたデータ)を読み取れるかどうか」を制御する仕組みである。CSRF攻撃は、攻撃者がレスポンスの中身を見られなくても、「リクエストを送信してサーバー側で処理を実行させる」だけで成立してしまう。そのため、CORSとは別にCSRF対策(トークン検証など)を必ず実装しなければならない。
まとめ
- CSRFは、ログイン中のユーザーを罠サイトに誘導し、意図しない操作を標的サイトへ強制的に送る攻撃である。
- ブラウザがログイン情報のCookieを自動送信する仕組みを悪用している。
- 対策の基本は、予測不可能な「CSRFトークン」をフォームに埋め込んでサーバーで照合することである。
- Cookieの
SameSite属性を設定することでも攻撃の成立を防ぐことができる。 - AIにデータ送信フォームを作らせる際は、CSRF対策が抜けていないか必ず確認する。
情報ソース
より詳しくAIに聞いてみよう
- CSRF攻撃が成立する具体的なシナリオを、図解するようにテキストで説明してください。
- PHPでフレームワークを使わずにセッションを活用した簡易的なCSRFトークンの実装例を示してください。
- CookieのSameSite属性(Strict, Lax, None)の違いと、CSRF対策における効果について説明してください。
- AIに認証機能を実装してもらうとき、CSRFとセッション固定化攻撃を防ぐためのプロンプトの例を教えてください。
- 作成したNode.jsのフォーム送信コードを見せるので、CSRF脆弱性がないかレビューしてください。