2021年12月16日に公式 Twitter からもアナウンスされたように Ruby on Rails の新しいメジャーバージョンである 7.0
がリリースされたので、アップグレードする時の参考記事として書いてみました。アップグレードの手順と、Rails 7 へ完全対応するための new_framework_defaults_7_0.rb
の調査をしてみたたので需要あれば良いなと。
なお、たまたまこの記事を公開する時に Ruby on Rails Advent Calendar 2021 の Rails 7 リリース日が未投稿状態でしたので代わりに投稿をさせて頂きました。
Rails 7 へのアップグレード
現在自分が仕事で扱っているプロダクトも Rails 7 へアップデートすべく Rails アップグレードガイド に従い現在アップグレード準備を進めている段階です。
公式の手順でも示されているように、
- テストを書き、テストがパスすることを確認する。
- 現時点のバージョンのパッチバージョンを最新のパッチに移行する。
- テストを修正し、非推奨の機能を修正する。
- 次のマイナーバージョンの最新パッチに移行する。
の手順に従いこの Rails 7 が出た直後にはアップグレードをするための準備は整えておきました。
Rails はこの時の最新である 6.1.4.4
を利用していたので、この時には他の依存パッケージをできる限り最新にする作業を行いました。
そしていよいよ Rails 7 へのアップグレードです。
いつも通り
bin/rails app:update
を打って作成される config/initializers/new_framework_defaults_7_0.rb
との戦いの開始です。
new_framework_defaults_7_0.rb の内容
初期値はいつも通り全てコメントアウト状態で、 config.load_defaults 6.1
であれば全て '6.1と互換性のある動きになります。目指すのは、このファイルの設定部分のコメントアウトを全て外し
config.load_defaults 7.0` にし、このファイル自体を削除する事がゴールです。
まずは以下が元の内容です。
# Be sure to restart your server when you modify this file.
#
# This file eases your Rails 7.0 framework defaults upgrade.
#
# Uncomment each configuration one by one to switch to the new default.
# Once your application is ready to run with all new defaults, you can remove
# this file and set the `config.load_defaults` to `7.0`.
#
# Read the Guide for Upgrading Ruby on Rails for more info on each option.
# https://guides.rubyonrails.org/upgrading_ruby_on_rails.html
# `button_to` view helper will render `<button>` element, regardless of whether
# or not the content is passed as the first argument or as a block.
# Rails.application.config.action_view.button_to_generates_button_tag = true
# `stylesheet_link_tag` view helper will not render the media attribute by default.
# Rails.application.config.action_view.apply_stylesheet_media_default = false
# Change the digest class for the key generators to `OpenSSL::Digest::SHA256`.
# Changing this default means invalidate all encrypted messages generated by
# your application and, all the encrypted cookies. Only change this after you
# rotated all the messages using the key rotator.
#
# See upgrading guide for more information on how to build a rotator.
# https://guides.rubyonrails.org/v7.0/upgrading_ruby_on_rails.html
# Rails.application.config.active_support.key_generator_hash_digest_class = OpenSSL::Digest::SHA256
# Change the digest class for ActiveSupport::Digest.
# Changing this default means that for example Etags change and
# various cache keys leading to cache invalidation.
# Rails.application.config.active_support.hash_digest_class = OpenSSL::Digest::SHA256
# Don't override ActiveSupport::TimeWithZone.name and use the default Ruby
# implementation.
# Rails.application.config.active_support.remove_deprecated_time_with_zone_name = true
# Change the format of the cache entry.
# Changing this default means that all new cache entries added to the cache
# will have a different format that is not supported by Rails 6.1 applications.
# Only change this value after your application is fully deployed to Rails 7.0
# and you have no plans to rollback.
# Rails.application.config.active_support.cache_format_version = 7.0
# Calls `Rails.application.executor.wrap` around test cases.
# This makes test cases behave closer to an actual request or job.
# Several features that are normally disabled in test, such as Active Record query cache
# and asynchronous queries will then be enabled.
# Rails.application.config.active_support.executor_around_test_case = true
# Define the isolation level of most of Rails internal state.
# If you use a fiber based server or job processor, you should set it to `:fiber`.
# Otherwise the default of `:thread` if preferable.
# Rails.application.config.active_support.isolation_level = :thread
# Set both the `:open_timeout` and `:read_timeout` values for `:smtp` delivery method.
# Rails.application.config.action_mailer.smtp_timeout = 5
# The ActiveStorage video previewer will now use scene change detection to generate
# better preview images (rather than the previous default of using the first frame
# of the video).
# Rails.application.config.active_storage.video_preview_arguments =
# "-vf 'select=eq(n\\,0)+eq(key\\,1)+gt(scene\\,0.015),loop=loop=-1:size=2,trim=start_frame=1' -frames:v 1 -f image2"
# Automatically infer `inverse_of` for associations with a scope.
# Rails.application.config.active_record.automatic_scope_inversing = true
# Raise when running tests if fixtures contained foreign key violations
# Rails.application.config.active_record.verify_foreign_keys_for_fixtures = true
# Disable partial inserts.
# This default means that all columns will be referenced in INSERT queries
# regardless of whether they have a default or not.
# Rails.application.config.active_record.partial_inserts = false
#
# Protect from open redirect attacks in `redirect_back_or_to` and `redirect_to`.
# Rails.application.config.action_controller.raise_on_open_redirects = true
# Change the variant processor for Active Storage.
# Changing this default means updating all places in your code that
# generate variants to use image processing macros and ruby-vips
# operations. See the upgrading guide for detail on the changes required.
# The `:mini_magick` option is not deprecated; it's fine to keep using it.
# Rails.application.config.active_storage.variant_processor = :vips
# If you're upgrading and haven't set `cookies_serializer` previously, your cookie serializer
# was `:marshal`. Convert all cookies to JSON, using the `:hybrid` formatter.
#
# If you're confident all your cookies are JSON formatted, you can switch to the `:json` formatter.
#
# Continue to use `:marshal` for backward-compatibility with old cookies.
#
# If you have configured the serializer elsewhere, you can remove this.
#
# See https://guides.rubyonrails.org/action_controller_overview.html#cookies for more information.
# Rails.application.config.action_dispatch.cookies_serializer = :hybrid
# Enable parameter wrapping for JSON.
# Previously this was set in an initializer. It's fine to keep using that initializer if you've customized it.
# To disable parameter wrapping entirely, set this config to `false`.
# Rails.application.config.action_controller.wrap_parameters_by_default = true
# Specifies whether generated namespaced UUIDs follow the RFC 4122 standard for namespace IDs provided as a
# `String` to `Digest::UUID.uuid_v3` or `Digest::UUID.uuid_v5` method calls.
#
# See https://guides.rubyonrails.org/configuring.html#config-active-support-use-rfc4122-namespaced-uuids for
# more information.
# Rails.application.config.active_support.use_rfc4122_namespaced_uuids = true
# Change the default headers to disable browsers' flawed legacy XSS protection.
# Rails.application.config.action_dispatch.default_headers = {
# "X-Frame-Options" => "SAMEORIGIN",
# "X-XSS-Protection" => "0",
# "X-Content-Type-Options" => "nosniff",
# "X-Download-Options" => "noopen",
# "X-Permitted-Cross-Domain-Policies" => "none",
# "Referrer-Policy" => "strict-origin-when-cross-origin"
# }
これらを一個ずつ調べて解説していこうと思います。
(実際に動かして確認までしていないものもあるので、予想も含めて書いているので訂正あればリクエストをお願いしますmm)
new_framework_defaults_7_0.rb の設定項目 (ここが本題)
こちらの設定項目は Rails アプリケーションを設定する にも個別に説明はされているのですが、このファイルに出てくる設定のみに絞って順番に調査していこうと思います。
config.action_view.button_to_generates_button_tag
# `button_to` view helper will render `<button>` element, regardless of whether
# or not the content is passed as the first argument or as a block.
Rails.application.config.action_view.button_to_generates_button_tag = true
だとこれまで以下のように button_to View ヘルパーを利用すると
= button_to 'name'
このような <input type="submit">
のボタンが吐かれていましたが、
<form class="button_to" method="post" action="/">
<input type="submit" value="name">
<input type="hidden" name="authenticity_token" value="************">
</form>
このフラグをコメントアウトすると <button type="submit">
のボタンが吐かれるようになります。
<form class="button_to" method="post" action="/">
<button type="submit">name</button>
<input type="hidden" name="authenticity_token" value="************" autocomplete="off">
</form>
対応方針
単純な HTML だけを見た時の動作としてはほとんど変化はないかと思いますが、以下のような点を対応すれば良いかと思います。
- input を想定して js/css を書いている箇所の変更
- input を想定して system テストを書いてしまっている箇所の修正
config.action_view.apply_stylesheet_media_default
# `stylesheet_link_tag` view helper will not render the media attribute by default.
Rails.application.config.action_view.apply_stylesheet_media_default = false
media属性が提供されていない stylesheet_link_tag
View ヘルパーを利用する際に、デフォルトで media="screen"
として出力されていましたが、このフラグをコメントアウトすると media
属性は吐かれなくなります。
対応方針
-
media="screen"
となることを期待するようであれば、media: 'screen'
を指定する -
media="screen"
が不要でも問題なければ対応も不要
config.active_support.key_generator_hash_digest_class
# Change the digest class for the key generators to `OpenSSL::Digest::SHA256`.
# Changing this default means invalidate all encrypted messages generated by
# your application and, all the encrypted cookies. Only change this after you
# rotated all the messages using the key rotator.
#
# See upgrading guide for more information on how to build a rotator.
# https://guides.rubyonrails.org/v7.0/upgrading_ruby_on_rails.html
Rails.application.config.active_support.key_generator_hash_digest_class = OpenSSL::Digest::SHA256
これまでは OpenSSL::Digest::SHA1
を利用していたが OpenSSL::Digest::SHA256
になるという話らしいです。 (知らんけど)
古いダイジェストクラスを使ったメッセージを読めるようにするためには、ローテータを利用する必要があります。
以下はローテータの例です
Rails.application.config.action_dispatch.cookies_rotations.tap do |cookies|
salt = Rails.application.config.action_dispatch.authenticated_encrypted_cookie_salt
secret_key_base = Rails.application.secrets.secret_key_base
key_generator = ActiveSupport::KeyGenerator.new(
secret_key_base, iterations: 1000, hash_digest_class: OpenSSL::Digest::SHA1
)
key_len = ActiveSupport::MessageEncryptor.key_len
secret = key_generator.generate_key(salt, key_len)
cookies.rotate :encrypted, secret
end
対応方針
- セッション Cookie で利用している場合、セッションが引き継げなくなってしまうためローテータを利用する
- 上記コードの secret_key_base は
Rails.application.secret_key_base
の場合もあるので環境に合わせて変更した方が良さそうです
- 上記コードの secret_key_base は
- Devise gem で利用しているみたいだがメールアドレス確認トークンやパスワードリセットトークンの生成等で利用されているだけっぽいので問題はなさそう
- その他 gem についても
ActiveSupport::KeyGenerator
を使ったコードがないかを確認して、必要あればローテータのようなコード実装をする等対応が必要かも?
config.active_support.hash_digest_class
# Change the digest class for ActiveSupport::Digest.
# Changing this default means that for example Etags change and
# various cache keys leading to cache invalidation.
Rails.application.config.active_support.hash_digest_class = OpenSSL::Digest::SHA256
重要でないダイジェスト(ETagヘッダーなど)の生成に用いられているらしい。
対応方針
- ETag を使っている場合は気にする必要あるかも? (よくわからなかったのでスルー
config.active_support.remove_deprecated_time_with_zone_name
# Don't override ActiveSupport::TimeWithZone.name and use the default Ruby
# implementation.
Rails.application.config.active_support.remove_deprecated_time_with_zone_name = true
ActiveSupport::TimeWithZone.name
を Ruby デフォルト実装の name
にてクラス名を得るようにするものです。以前までは "Time"
を返していたようですが、"ActiveSupport::TimeWithZone"
を返すようになるみたいです。
参考: https://github.com/rails/rails/blob/v7.0.0/activesupport/lib/active_support/time_with_zone.rb#L44-L53
対応方針
- このメソッド自体使っている箇所は少ないように思うが、テストが通ればコメントアウトしても良いかも
- gem で利用している箇所も無いとは言えないので、テストの充実が大事!
- 与えられた日時系のクラスタイプを
name
で判別するような箇所があれば修正かなー (知らんけど
config.active_support.cache_format_version
# Change the format of the cache entry.
# Changing this default means that all new cache entries added to the cache
# will have a different format that is not supported by Rails 6.1 applications.
# Only change this value after your application is fully deployed to Rails 7.0
# and you have no plans to rollback.
Rails.application.config.active_support.cache_format_version = 7.0
Rails 7 (Active Support 7.0) より新しいキャッシュフォーマットの形式が追加された。 ActiveSupport::Cache
シリアライズにより高速でコンパクトなフォーマットとのことだが、Rails 6.1 ではサポートされない形式になっている。7 で 旧形式のキャッシュを読み込めるようにされているため、移行時にそのままキャッシュを引き継jげるようになっているが、 6.1 のアプリケーションと共存や並行運用する事ができない。また一度 7 で運用を開始するとキャッシュの形式が新しくなるため 6.1 へ戻すとキャッシュが読み込めなくなるため、ロールバックはできないようです
対応方針
- 他のロールバック可能な部分を全て移行出来てから最後に コメントアウトするのが良さそう
- 最後はエイヤーでやるしか無い!
config.active_support.executor_around_test_case
# Calls `Rails.application.executor.wrap` around test cases.
# This makes test cases behave closer to an actual request or job.
# Several features that are normally disabled in test, such as Active Record query cache
# and asynchronous queries will then be enabled.
Rails.application.config.active_support.executor_around_test_case = true
Rails.application.executor
フックが全てののテストの前後で実行されるようになり、テスト間でステートが漏れ出さないようにシミュレートされるようになったらしい。
対応方針
- rspec 勢は関係なさそう?
- これでテストが通らなくなれば、 そのテストに問題があるという事だと思うので、積極的にここはコメントアウトしておくのが良さそう
config.active_support.isolation_level
# Define the isolation level of most of Rails internal state.
# If you use a fiber based server or job processor, you should set it to `:fiber`.
# Otherwise the default of `:thread` if preferable.
# Rails.application.config.active_support.isolation_level = :thread
これまでよく同一リクエスト内で共有して利用したい値などを Thread.current[:hoge]
のような形でよく利用していたが、名前に反してこれは Fiber
ベースで共有されているため、Fiber が切り替わるような実装になっていると見えなくなっていた。これをスレッドベースでの共有に変更するもののようです。
対応方針
- ファイバーベースのサーバやジョブプロセッサを利用していない限りはこのコメントアウトをしても問題にはならなさそう
- あとはマルチ Fiber を理解・意識して実装している箇所があれば改修の必要はありそうですが、私のように特に気にせず
Thread.current[:hoge]
を使っているのであれば、テストが通ればヨシ!
config.action_mailer.smtp_timeout
# Set both the `:open_timeout` and `:read_timeout` values for `:smtp` delivery method.
# Rails.application.config.action_mailer.smtp_timeout = 5
SMTP のタイムアウトが指定できるようになったみたいです。
Rails.application.config.action_mailer.smtp_settings = {
open_timeout: 5,
read_timeout: 5,
}
のように open_timeout
と read_timeout
を個別に設定も可能なようですがこれを一気に同じ値で設定できるのがこのオプションのようです。
https://github.com/rails/rails/commit/52db7f2ef3c4a902227cac163657c89282986e25
対応方針
- 特に何も考えずにコメントアウトでも良さそう (ほんま知らんけど
config.active_storage.video_preview_arguments
# The ActiveStorage video previewer will now use scene change detection to generate
# better preview images (rather than the previous default of using the first frame
# of the video).
Rails.application.config.active_storage.video_preview_arguments =
"-vf 'select=eq(n\\,0)+eq(key\\,1)+gt(scene\\,0.015),loop=loop=-1:size=2,trim=start_frame=1' -frames:v 1 -f image2"
ActiveStorage の ffmpeg 動画プレビュー画像生成方法を変更できるようになったようです。これまでプレビュー画像が生成できなかったのか、生成できたけど設定を変更できなかっただけなのか、、、雰囲気後者っぽいけど使ったことないから知らないw
対応方針
- 現在 ActiveStorage も動画も扱っていないのであれば何も考えずコメントアウトで良さそう
- 使っている場合でもいい感じのプレビューを生成してくれるオプションなのでこのデフォルト値でも良いし、カスタマイズしても良い
config.active_record.automatic_scope_inversing
# Automatically infer `inverse_of` for associations with a scope.
Rails.application.config.active_record.automatic_scope_inversing = true
スコープ付き関連付けで inverse_of
を自動的に推論してくれるようになります。
Rails 4.1 以降では、簡単なモデルでは inverse_of
オプションを付ける必要はなくなりこのオプションの存在自体最近忘れていましたが、簡単ではない (?しらんけど?) モデルでも inverse_of
を推論してくれるようになったのでしょうかね?そうなれば逆にどんなパターンで inverse_of
が付けられず手動で付けなければならないのかがますます分からなく・・・
対応方針
- こちらもテストが充実しているのであれば、通ればヨシで行きましょう! (まじで知らん
config.active_record.verify_foreign_keys_for_fixtures
# Raise when running tests if fixtures contained foreign key violations
Rails.application.config.active_record.verify_foreign_keys_for_fixtures = true
フィクスチャがテストに読み込まれた後で、全ての外部キー制約が有効化されるようになります。 (ただし PostgreSQL と SQLite のみ)
対応方針
- 後で有効化されるとのことなので、結局は外部キー制約に引っかかるようなフィクスチャは作成できないのであまり気にする必要は無いかも
- ただし、後で有効化されるとのことなのでレコード作成の順番を子から行うことも可能ということかな?
- MySQL 使っているならそもそもなのでw サクッとコメントアウトしちゃいましょう!
config.active_record.partial_inserts
# Disable partial inserts.
# This default means that all columns will be referenced in INSERT queries
# regardless of whether they have a default or not.
Rails.application.config.active_record.partial_inserts = false
新規レコード作成で部分書き込みを行うかどうかのフラグです。この場合のデフォルトは多分モデルのデフォルトではなくテーブル定義のデフォルト値の事で、デフォルト値がテーブル定義で設定されている場合に省略するか否かのフラグのようです。
対応方針
- 特に変わった利用の仕方をしていなければ非互換な動作はなさそうなので、テストが通れば良いと思います
config.action_controller.raise_on_open_redirects
# Protect from open redirect attacks in `redirect_back_or_to` and `redirect_to`.
Rails.application.config.action_controller.raise_on_open_redirects = true
まず、「オープンリダイレクト (Open-Redirect)」とは
オープンリダイレクトとはWebブラウザによるインターネット上のサイトアクセスに関して、入力したサイトから他のサイトへ自動的に移動する機能のこと。
これを誤って利用すると脆弱性が発生する可能性がある。
例えば信頼したサイトを http://<aaa>.com/ 、 悪意のサイトを http://<bbb>.com/とする
http://<aaa>.com/ に"オープンリダイレクト"の脆弱性がある場合、 http://<aaa>.com/xxx.php?url=http://<bbb>.com/
のようにパラメータに悪意のサイトを指定して悪意のサイトに飛ばすことが可能となる。
ユーザはアクセスしているサイトが信頼したサイトであり、また証明書も正しいためユーザは気が付かない可能性がある。
悪意のサイトでユーザ名/パスワードの入力をさせることによりパスワードの盗み取りが可能となる。
リダイレクトする場合は、
(1)中間にクッションページを設置する
(2)リダイレクト先のドメインをチェックする
などの対策が必須である。
またWebサーバ側は③アドレスバーを非表示、ステータスバーを非表示にするなどのデザインは禁止④すべきである。
参考: http://tooljp.com/jyosho/glossary/Open-Redirect.html
なるほど。オープンリダイレクトを使いたければ raise_on_open_redirects = true
した上で redirect_to
や reirect_back_or_to
の引数に allow_other_host: true
を指定してやれば出来るらしい。 allow_other_host: true
を付けるのは開発者の責任という事ですね。
対応方針
- こちらをコメントアウトする分には良さそう
- もしオープンリダイレクトをしている箇所があり、そこが脆弱性がないかまたは自社サイト内であれば
allow_other_host: true
を付けるで良いんではないでしょうかね
config.active_storage.variant_processor
# Change the variant processor for Active Storage.
# Changing this default means updating all places in your code that
# generate variants to use image processing macros and ruby-vips
# operations. See the upgrading guide for detail on the changes required.
# The `:mini_magick` option is not deprecated; it's fine to keep using it.
Rails.application.config.active_storage.variant_processor = :vips
ActiveStorage のバリアント生成時に利用する画像処理ライブラリのデフォルトが ruby-vips に変更されたようです。 MiniMagick は非推奨になった訳ではにとは言いつつデフォルトが変わったということはまぁそういう事なんでしょう。
対応方針
- 正直どちらでも良いです
- このコメントアウトを外して
:vips
にするでも良いですし、:mini_magick
でも良いと思います- 個人的には MiniMagick は苦い経験 (メモリやクラッシュ関連) をしたので ruby-vips を一度使ってみたいかなと思っている
- ただ、それ以前に↑の経験により Rails サーバでは画像処理をしない派 (画像サービスや CDN にお任せ) になったので使う機会があるか、、
config.action_dispatch.cookies_serializer
# If you're upgrading and haven't set `cookies_serializer` previously, your cookie serializer
# was `:marshal`. Convert all cookies to JSON, using the `:hybrid` formatter.
#
# If you're confident all your cookies are JSON formatted, you can switch to the `:json` formatter.
#
# Continue to use `:marshal` for backward-compatibility with old cookies.
#
# If you have configured the serializer elsewhere, you can remove this.
#
# See https://guides.rubyonrails.org/action_controller_overview.html#cookies for more information.
Rails.application.config.action_dispatch.cookies_serializer = :hybrid
Cookie というとざっくりしすぎだけど、いわゆる Controller で利用する cookies
で利用するシリアライザが、これまでの Marshal
から JSON 形式のものに変更されるようです。こちらも config.active_support.cache_format_version
と同様に透過的に移行は可能なようだけど JSON 形式になることによる非互換に注意が必要なようです。
If you're confident all your cookies are JSON formatted, you can switch to the `:json` formatter.
適当訳 JSON 形式に切り替える自信のある時だけ :json
に切り替えろ。とw
気をつけるべきポイントとしては、 Marshal
されなくなるという事は Ruby オブジェクトを cookie に入れるという行為を止めれば良さそうな雰囲気。基本的には
- ハッシュオブジェクト
- 数値
- 文字列
のに留めておくと良さそうですね。
対応方針
- まずは cookies を利用しているか否かが大きかなと思います。多くの場合 session を利用しているかと思うので、利用していないようであれば即コメントアウトでおk
- 利用している場合でも JSON 化しても復元可能な値しか利用していなければコメントアウトしましょう!エイヤー
config.action_controller.wrap_parameters_by_default
# Enable parameter wrapping for JSON.
# Previously this was set in an initializer. It's fine to keep using that initializer if you've customized it.
# To disable parameter wrapping entirely, set this config to `false`.
Rails.application.config.action_controller.wrap_parameters_by_default = true
JSON リクエストがデフォルトで ParamsWrapper
でラップされるようになります。ParamsWrapper
はルート要素を指定しない JSON をリクエストする事が可能で、ラップは自動的に行なってくれます。ParamsWrapper 自体は以前から存在するものですのでググれば出てくると思いますのでここでの解説は割愛します。
対応方針
- こちらをコメントアウトする分には多分問題は無さそうな気はしている
- なぜなら既存箇所は全てラップしたリクエストを行なっているはずなので動くはず (と期待しています
- JS 等で Rails のリクエスト形式に合わせたラップを行なっている箇所は結構気持ち悪い思いをしていると思うので、そういう箇所についてはコメントアウト後に少しずつアンラップしたリクエストへの変更を試していくと良いと思います
config.active_support.use_rfc4122_namespaced_uuids
# Specifies whether generated namespaced UUIDs follow the RFC 4122 standard for namespace IDs provided as a
# `String` to `Digest::UUID.uuid_v3` or `Digest::UUID.uuid_v5` method calls.
#
# See https://guides.rubyonrails.org/configuring.html#config-active-support-use-rfc4122-namespaced-uuids for
# more information.
Rails.application.config.active_support.use_rfc4122_namespaced_uuids = true
Digest::UUID.uuid_v3
や Digest::UUID.uuid_v5
メソッドに文字列として渡す「名前空間ID」を RFC 4122 標準に準拠させるかどうかの指定しです。てか RFC 標準じゃなかったのだ。
対応方針
- 名前空間を利用した UUID (v3, v5) を利用している箇所があれば RFC に従ったものを利用しているか確認を行う
- もし RFC に従っていない名前空間を利用していればどうするんだろ、、
- ↑ の利用箇所がなければコメントアウトすれば良いかな
- gem までは分からないので、テスト通れば良さそうに思います
config.action_dispatch.default_headers
# Change the default headers to disable browsers' flawed legacy XSS protection.
Rails.application.config.action_dispatch.default_headers = {
"X-Frame-Options" => "SAMEORIGIN",
"X-XSS-Protection" => "0",
"X-Content-Type-Options" => "nosniff",
"X-Download-Options" => "noopen",
"X-Permitted-Cross-Domain-Policies" => "none",
"Referrer-Policy" => "strict-origin-when-cross-origin"
}
HTTP ヘッダーで使われる値のデフォルト値が上記のようになります。6.1 までは以下のようになっているので
{
"X-Frame-Options" => "SAMEORIGIN",
"X-XSS-Protection" => "1; mode=block",
"X-Content-Type-Options" => "nosniff",
"X-Download-Options" => "noopen",
"X-Permitted-Cross-Domain-Policies" => "none",
"Referrer-Policy" => "strict-origin-when-cross-origin"
}
差分としては以下の部分になります。
- "X-XSS-Protection" => "1; mode=block",
+ "X-XSS-Protection" => "0",
「X-XSS-Protection」ヘッダーとは
Internet Explorer, Chrome, Safari の機能で、反射型クロスサイトスクリプティング (XSS) 攻撃を検出したときに、ページの読み込みを停止するためのものです。強い Content-Security-Policy をサイトが実装して、インライン JavaScript の使用を無効にしていれば ('unsafe-inline')、現在のブラウザーではこれらの防御は大枠で不要なものですが、まだ CSP に対応していない古いウェブブラウザーを使用しているユーザーには防御になります。
参考: https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/X-XSS-Protection
とのことで Rails 7 からのデフォルトとしては XSS フィルタリングを無効化するようです。
詳しくはこちらの PR に書いてありますが X-XSS-Protection
ヘッダーは非推奨となり各ブラウザでも削除・廃止されているようです。
対応方針
- 各ブラウザで利用できなくなっているのでこの変更を行なっても特に問題にはならないかと思います
- もし必要な場合は
Rails.application.config.action_dispatch.default_headers
を上書いて利用しましょう
- もし必要な場合は
まとめ
ということで new_framework_defaults_7_0.rb の調査といいつつ、各種ドキュメントからのコピペと翻訳の寄せ集めになりました。が、一箇所にまとめる事はできたので誰か (というか来年の自分) の役に立てば良いかな思っています。
良いお年を。