From 0f6c9bc78690f84afd4cf4f514d447fe01e98b72 Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Thu, 10 Sep 2020 14:06:18 +0200 Subject: [PATCH] Add an ActiveSupport option to allow setting a digest class Right now it's already possible to set a digest class manually, but this is not through a publicly supported and approved API. With these configuration options, it is possible to configure a digest class to use for digests inside Rails. The reason for this is that it allows configuring other classes in certain conditions like running in FIPS mode. FIPS disallows MD5 and discourages SHA1. Even though this isn't used in Rails for security related things, using newer hash algorithms means not having to explain it to auditors which always makes life easier. That's not the only reason though. If today Ruby is built and running for example in an Ubuntu 18.04 FIPS approved environment, the default Digest classes break, see https://bugs.ruby-lang.org/issues/13681 as well. By allowing a class to be configured, the following can be used so that things work properly (using the new API proposed here): ``` Rails.application.config.active_support.hash_digest_class = OpenSSL::Digest::SHA256 ``` This would then use the OpenSSL certified FIPS implementation as well. --- activesupport/lib/active_support/railtie.rb | 9 +++++++++ guides/source/configuring.md | 4 ++-- railties/CHANGELOG.md | 6 ++++++ railties/lib/rails/application/configuration.rb | 2 +- railties/test/application/configuration_test.rb | 12 ++++++++++++ 5 files changed, 30 insertions(+), 3 deletions(-) diff --git a/activesupport/lib/active_support/railtie.rb b/activesupport/lib/active_support/railtie.rb index cd22065c71..f363125a38 100644 --- a/activesupport/lib/active_support/railtie.rb +++ b/activesupport/lib/active_support/railtie.rb @@ -85,8 +85,17 @@ module ActiveSupport initializer "active_support.set_hash_digest_class" do |app| config.after_initialize do if app.config.active_support.use_sha1_digests + ActiveSupport::Deprecation.warn(<<-MSG.squish) + config.active_support.use_sha1_digests is deprecated and will + be removed from Rails 6.2. Use config.active_support.hash_digest_class + instead. + MSG ActiveSupport::Digest.hash_digest_class = ::Digest::SHA1 end + + if klass = app.config.active_support.hash_digest_class + ActiveSupport::Digest.hash_digest_class = klass + end end end end diff --git a/guides/source/configuring.md b/guides/source/configuring.md index 5b49fd4a26..30116a9147 100644 --- a/guides/source/configuring.md +++ b/guides/source/configuring.md @@ -819,7 +819,7 @@ There are a few configuration options available in Active Support: * `config.active_support.time_precision` sets the precision of JSON encoded time values. Defaults to `3`. -* `config.active_support.use_sha1_digests` specifies whether to use SHA-1 instead of MD5 to generate non-sensitive digests, such as the ETag header. +* `config.active_support.hash_digest_class` allows configuring the digest class to use to generate non-sensitive digests, such as the ETag header. * `config.active_support.use_authenticated_message_encryption` specifies whether to use AES-256-GCM authenticated encryption as the default cipher for encrypting messages instead of AES-256-CBC. @@ -1035,7 +1035,7 @@ text/javascript image/svg+xml application/postscript application/x-shockwave-fla - `config.active_record.cache_versioning`: `true` - `config.action_dispatch.use_authenticated_cookie_encryption`: `true` - `config.active_support.use_authenticated_message_encryption`: `true` -- `config.active_support.use_sha1_digests`: `true` +- `config.active_support.hash_digest_class`: `::Digest::SHA1` - `config.action_controller.default_protect_from_forgery`: `true` - `config.action_view.form_with_generates_ids`: `true` diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md index 4b489bb59d..2595f83070 100644 --- a/railties/CHANGELOG.md +++ b/railties/CHANGELOG.md @@ -1,3 +1,9 @@ +* Deprecate `config.active_support.use_sha1_digests` + + `config.active_support.use_sha1_digests` is deprecated. It is replaced with `config.active_support.hash_digest_class` which allows setting the desired Digest instead. The Rails version defaults have been updated to use this new method as well so the behavior there is unchanged. + + *Dirkjan Bussink* + * Change the default logging level from :debug to :info to avoid inadvertent exposure of personally identifiable information (PII) in production environments. diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb index aca01f216b..c2a0ccf747 100644 --- a/railties/lib/rails/application/configuration.rb +++ b/railties/lib/rails/application/configuration.rb @@ -115,7 +115,7 @@ module Rails if respond_to?(:active_support) active_support.use_authenticated_message_encryption = true - active_support.use_sha1_digests = true + active_support.hash_digest_class = ::Digest::SHA1 end if respond_to?(:action_controller) diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb index 6ceedf9838..947e77bcfb 100644 --- a/railties/test/application/configuration_test.rb +++ b/railties/test/application/configuration_test.rb @@ -2225,6 +2225,18 @@ module ApplicationTests assert_equal Digest::SHA1, ActiveSupport::Digest.hash_digest_class end + test "ActiveSupport::Digest.hash_digest_class can be configured via config.active_support.hash_digest_class" do + remove_from_config '.*config\.load_defaults.*\n' + + app_file "config/initializers/custom_digest_class.rb", <<-RUBY + Rails.application.config.active_support.hash_digest_class = Digest::SHA256 + RUBY + + app "development" + + assert_equal Digest::SHA256, ActiveSupport::Digest.hash_digest_class + end + test "custom serializers should be able to set via config.active_job.custom_serializers in an initializer" do class ::DummySerializer < ActiveJob::Serializers::ObjectSerializer; end