CSRF対策とは?トークン方式の仕組みを解説

「ログイン中に、別のサイトを開いただけで、意図しない操作が実行される」——CSRF(クロスサイトリクエストフォージェリ)は、こうした攻撃です。

GETとPOSTの違いとセキュリティ でも軽く触れましたが、この記事ではCSRFの仕組みと、トークンによる対策方法を詳しく整理します。

関連

セキュリティ対策を横断的に確認したい方は、 Webアプリの脆弱性・セキュリティ対策まとめ もご覧ください。

CSRFとは何が起きているのか

CSRFが成立する前提は、「ブラウザはCookieを、リクエストの送信元がどこであっても自動的に付けて送る」という仕組みにあります。

例えば、あなたがオンラインバンキングにログインした状態のまま、別のタブで悪意のあるサイトを開いたとします。そのサイトに、次のような隠しフォームが仕込まれていたらどうなるでしょうか。

<form action="https://bank.example.com/transfer" method="POST">
 <input type="hidden" name="to" value="attacker">
 <input type="hidden" name="amount" value="10000">
</form>
<script>document.forms[0].submit()</script>

このフォームがページ読み込み時に自動送信されると、ブラウザはbank.example.com宛てのリクエストとしてログインCookieを付けて送信します。銀行のサーバーから見ると「ログイン中の本人からの正規のリクエスト」にしか見えません。あなたは何もクリックしていないのに、送金が実行されてしまいます。

体験|開いただけで送金されるか見る

実際に手を動かして確かめてみましょう。以下のデモは実際の通信を一切発生させません。「正規サイト」と「わなサイト」を模した2つのカードで、CSRFトークンの有無による違いをその場で確認できます。

体験デモ|開いただけで送金されるか見る

正規サイトわなサイトを見比べる

実際の通信は発生しません。あなたが「正規サイトにログイン中」という想定で、右側の「わなサイト」を開いたときに何が起きるかを確認してください。

現在の残高:¥50,000
正規サイト(ログイン中)

あなた自身が意図して押す、正規の操作です。

わなサイト(悪意のある外部サイト)

実際には「面白い画像はこちら」のようなリンクの裏で、送金フォームが自動送信される想定です。

上のボタンを押すと、実行結果がここに表示されます。

「CSRFトークンなし」の状態で「このページを開く(体験用)」を押すと、あなたは何も操作していないのに送金が成立してしまったはずです。「CSRFトークンあり」に切り替えると、同じボタンを押してもサーバー側でリクエストが拒否され、残高は変化しません。これがCSRFトークンの効果です。

対策の基本|CSRFトークン

CSRF対策として広く使われているのが、CSRFトークンという仕組みです。

  1. サーバーがフォーム表示時に、推測不可能なランダムな文字列(トークン)を発行し、フォームに埋め込んでおく
  2. フォーム送信時、このトークンも一緒にサーバーへ送られる
  3. サーバーは、送られてきたトークンが自分が発行したものと一致するかを確認する
  4. 一致しなければリクエストを拒否する

外部の悪意あるサイトは、正規サイトが発行したこのトークンの値を知ることができません。そのため、隠しフォームを自動送信しても、トークンが一致せずリクエストが拒否されます。

Djangoでは{% csrf_token %}タグをフォーム内に置くだけで、この仕組みが自動的に組み込まれます。多くのフレームワークで、同様の仕組みが標準機能として用意されています。

あわせて重要な設定|SameSite Cookie

もう1つの有効な対策が、CookieのSameSite属性です。

SameSite=LaxSameSite=Strictを設定すると、別サイトからのリクエストにはそもそもCookieが自動的に付与されなくなります。これにより、CSRFトークンとは別の層でも攻撃を防げます。

CSRFトークンとSameSite属性は排他的なものではなく、両方を設定しておくのが実務上の基本です。

実務で意識したいポイント

まとめ

CSRFは、ログイン中のCookieが自動的に送信される仕組みを悪用した攻撃です。対策の基本はCSRFトークンによる検証と、CookieのSameSite属性の設定の組み合わせです。

自分のアプリの状態変更フォームに、この2つがきちんと実装されているか、この機会に確認してみてください。

顧問契約、開発、プロジェクトのご依頼を承ります。
内容、期間により金額が変動しますのでお気軽にお問い合わせください。

※ 案件によりお受けできない場合もあります。

お問い合わせはこちら →
戻る