[Rails] protect_from_forgery の明示的なストラテジー指定が必須に - デフォルト動作の非推奨化

rails/rails

背景: 一貫性のない動作が引き起こす混乱

Railsでは、CSRF(Cross-Site Request Forgery)攻撃からアプリケーションを保護するため、protect_from_forgeryメソッドを使用します。しかし、このメソッドには長年の一貫性の問題がありました。

protect_from_forgeryを引数なしで呼び出すと、デフォルトで:null_sessionストラテジーが使用されます。一方、config.action_controller.default_protect_from_forgeryを有効にした場合は:exceptionストラテジーが使用されます。この不一致により、開発者が意図しない動作に遭遇するケースがありました。

#56537で報告されたこの問題に対処するため、Rails 8.2ではprotect_from_forgeryを戦略指定なしで呼び出すことが非推奨となりました。

技術的な変更内容

新しい設定オプションの追加

新たにconfig.action_controller.default_protect_from_forgery_with設定が導入されました。この設定により、アプリケーション全体でのデフォルトストラテジーを統一的に管理できます。

if respond_to?(:action_controller)
  action_controller.forgery_protection_verification_strategy = :header_only
  action_controller.default_protect_from_forgery_with = :exception
end

Rails 8.2では、この設定のデフォルト値は:exceptionに変更されます。ただし、後方互換性のため、現在のバージョンでは:null_sessionのままです。

クラスレベルでの設定管理

RequestForgeryProtectionモジュールに新しいクラス変数とデリゲートメソッドが追加されました。

singleton_class.delegate :default_protect_from_forgery_with, :default_protect_from_forgery_with=, to: :config
delegate :default_protect_from_forgery_with, :default_protect_from_forgery_with=, to: :config
self.default_protect_from_forgery_with = :null_session

protect_from_forgeryメソッドの動作変更

:withオプションが指定されていない場合、非推奨警告が表示されるようになりました。

strategy = if options.key?(:with)
  options[:with]
else
  if default_protect_from_forgery_with == :null_session
    ActiveSupport::Deprecation.warn(<<~MSG.squish, ActionController.deprecator)
      Calling `protect_from_forgery` without specifying a strategy is deprecated.
      Please specify a strategy with the `:with` option.
    MSG
  end
  default_protect_from_forgery_with
end

self.forgery_protection_strategy = protection_method_class(strategy)

移行方法

Rails 8.2の新しい動作を早期に採用する

Rails 8.2の動作を今すぐ採用したい場合は、以下の設定を追加します。

config.action_controller.default_protect_from_forgery_with = :exception

非推奨警告を解消しつつ現在の動作を維持する

現在の動作を維持したい場合は、明示的に:withオプションを指定します。

class ApplicationController < ActionController::Base
  protect_from_forgery with: :null_session
end

ストラテジーの違い

Railsは3つの主要なCSRF保護ストラテジーを提供しています。

:exception

CSRF検証が失敗した場合、ActionController::InvalidCrossOriginRequest例外を発生させます。これが今後の推奨デフォルトです。

:reset_session

CSRF検証が失敗した場合、セッション全体をリセットします。

:null_session

CSRF検証が失敗した場合、リクエスト中は空のセッションを提供しますが、完全にリセットはしません。現在のデフォルトですが、将来的には:exceptionに変更されます。

テストへの影響

この変更により、既存のテストコードも更新が必要になる場合があります。

変更前:

PrependTrueController = Class.new(PrependProtectForgeryBaseController) do
  protect_from_forgery prepend: true
end

変更後:

PrependTrueController = Class.new(PrependProtectForgeryBaseController) do
  protect_from_forgery prepend: true, with: :null_session
end

まとめ

この変更により、RailsアプリケーションにおけるCSRF保護の動作がより明示的で予測可能になります。:exceptionストラテジーへの移行は、セキュリティの観点からも望ましい変更といえるでしょう。既存のアプリケーションは、非推奨警告に従って適切にストラテジーを明示することで、スムーズに移行できます。

記事メタデータ

Generated by:
Claude Sonnet 4.5 for DiffDaily

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
Gemini 2.5 Pro for DiffDaily

Review Criteria:

ガイドライン準拠 ✓ PASS

記事構成とDiffDaily Styleへの準拠状況

記事構成、カスタムMarkdown構文、対象読者への適合性、すべてのガイドライン項目を完璧に満たしています。特に、コードブロック前後の空行やファイル名指定が正しく使われており、可読性が非常に高いです。

  • 記事構成(Title、Context、Technical Detail)
  • DiffDaily Styleガイド準拠
  • カスタムMarkdown活用
  • 対象読者への適合性
技術的整合性 ✓ PASS

技術的な正確性と表現の適切性

Diff内容との照合、技術用語の正確性、説明の論理整合性、すべて問題ありません。引用されたコードはPRの目的と完全に一致しており、技術的な説明も正確です。

  • 技術用語の正確性
  • コード例の正確性
  • 説明の技術的正確性
PR内容との整合性 ✓ PASS

元のPR情報との一致度

PRのタイトルや目的と記事内容が完全に一致しています。PR情報から逸脱した主張や憶測(ハルシネーション)は見られず、事実に基づいた忠実な解説となっています。PR番号やIssue番号も正確です。

  • タイトル・説明の一致
  • Diff内容の正確な反映
  • 推測の排除