コドモン Product Team Blog

株式会社コドモンの開発チームで運営しているブログです。エンジニアやPdMメンバーが、プロダクトや技術やチームについて発信します!

ブラウザの仕様とともに考えるCSRF対策

こちらは「コドモン Advent Calendar 2025🎄」の4日目の記事になります。

こんにちは! プロダクト開発部の村松です!

昨今、有名OSSのサプライチェーン攻撃や、大手企業へのサイバー攻撃が相次いで報じられています。 今年の4月からプロダクトセキュリティチームにJOINしたこともあり、セキュリティについて学んできました。
今回は、そのなかでもCSRF攻撃とその対策について、学んだことをこの記事では紹介します。

※ Cookieを用いたセッション管理を行っているものを対象にしています。

CSRF攻撃について

CSRFによる攻撃手法は下記のとおりです。

引用: 安全なウェブサイトの作り方 - 1.6 CSRF(クロスサイト・リクエスト・フォージェリ)

  1. ユーザー(被害者)がログイン操作を行う
  2. セッションIDが発行され、cookieに保存される
  3. セッションの有効期限までログイン状態が維持される
  4. 攻撃者からのメールなどで罠サイトに誘導され、ユーザー(被害者)がアクセスする
  5. ユーザー(被害者)のブラウザで罠サイトのスクリプトが実行され、cookieと一緒に意図しないリクエストが送られる

API側で対策を行わない場合、上記の手法でデータの改ざんが行えてしまいます。

CSRF攻撃のリスクのあるリクエスト条件

次に、CSRFのリスクのある条件について紹介します。
下記の条件に当てはまる場合は、CSRF攻撃の対策を行う必要があります。

単純リクエストかどうか

単純リクエストの場合、CSRF攻撃の対策をする必要があります。
(単純リクエストの定義は下記のドキュメントをご参照ください)

developer.mozilla.org

一例としてはHTMLにおけるformタグでのPOSTリクエストは単純リクエストに該当します。
上記に該当するリクエストの場合はCSRF攻撃の対策を行いましょう。

データを更新するようなリクエストかどうか

CSRF攻撃では攻撃者はAPIからのレスポンスを確認することができません。
しかし、データの更新などのリクエストは行うことができるため、データの改ざんなどは行うことができてしまいます。
データの更新などを行うAPIに関しては対策をしましょう。

よくある誤解

認証のcookieの属性がSameSite=Laxの場合、CSRFは成立しない

多くのブラウザではcookieの属性がデフォルトでLaxとなっています。(Google ChromeではGoogle Chrome 80以降)
SameSite=Laxの場合、POST、PUT、DELETEのリクエストでは罠サイトからcookieを送ることができません。
しかし、安全なメソッド(GETリクエストなど)の場合はCSRFの攻撃が成立します。
詳しくは下記のドキュメントをご参照ください。

developer.mozilla.org

加えて特定のブラウザでは、デフォルト値としてLaxが設定されている場合に2分間SameSite=Noneとして扱う仕様があります。
これにより、2分間はPOSTリクエストでもcookieが送れるため、CSRF攻撃が成立する事になってしまいます。
※ Google Chromeでは2020年の2月にこの仕様が適応されました。

developers-jp.googleblog.com

そのため、上記の場合も対策が必要です。

CSRF対策

ここではCSRF攻撃に対して有効な対策をいくつか紹介します。

Originヘッダーをチェックする

CSRF攻撃は罠サイトからの攻撃になります。
そこでOriginヘッダーをチェックすることで、罠サイトからのリクエストを判別できます。
適切なOriginヘッダーが含まれないリクエストは受け付けないようにしましょう。

cookieのSameSite属性を設定する

SameSite属性のLaxに関して、ブラウザによってはデフォルト値、または明示的な設定かで仕様差分があります。
デフォルトでの設定の場合、2分間Noneとして扱われる可能性があります。
LaxまたはStrictを設定することで、POST、PUT、DELETEのリクエストでCSRF攻撃を防ぐことができるため、設定するようにしましょう。

GETリクエストでデータの更新などを行わないようにする

GETリクエストは下記のCSRF攻撃のリスクがあります。

  • imgタグからリクエストできるので、ユーザーは気づきにくく攻撃が容易
  • SameSite属性がLaxであっても、罠サイトからcookieが送れてしまう

上記の対策のためにも、データ改ざんリスクがある場合は適切なリクエストメソッドを使いましょう。

Content Typeを限定する

リクエストヘッダーのContent-Typeがapplication/jsonの場合、単純リクエストに該当しません。 そのため、仮にContent-Typeを限定できる場合はCSRF攻撃を防ぐことができます。
この対策を行うとformが使えなくなるため、プロダクトの性質を考慮して検討してみましょう。

CSRFトークンでの認証

昔からある対策として、トークンを発行し検証する方法があります。
適切なライフサイクルで罠サイトから推測不可能なトークンを発行し、リクエストのたびにリクエストヘッダーに含めるようにします。
Webフレームワークによっては標準的に、あるいはミドルウェアとして提供されていることが多いです。

学んだ感想

CSRF攻撃は昔から知られている攻撃手法ですが、ブラウザ側の仕様変更やセキュリティ対策に伴い、取れる対策の選択肢が増え、対策する難易度が下がった様に感じました。
いずれ今まで有効だった対策も、ブラウザの進化に伴い不要になるケースも生まれるかもしれません。
適切な対策を取るためにもブラウザの進化に追従し、攻撃手法とブラウザ仕様を照らし合わせて対策を考えていこうと思いました。