diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md index 8378de50617..a21a817fbbb 100644 --- a/activesupport/CHANGELOG.md +++ b/activesupport/CHANGELOG.md @@ -7,12 +7,12 @@ *Daniel Ma* -* Allow the hash function used to generate non-sensitive digests, such as the - ETag header, to be specified with `config.active_support.hash_digest_class`. +* Use SHA-1 to generate non-sensitive digests, such as the ETag header. - The object provided must respond to `#hexdigest`, e.g. `Digest::SHA1`. + Enabled by default for new apps; upgrading apps can opt in by setting + `config.active_support.use_sha1_digests = true`. - *Dmitri Dolguikh* + *Dmitri Dolguikh*, *Eugene Kenny* ## Rails 5.2.0.beta2 (November 28, 2017) ## diff --git a/activesupport/lib/active_support/railtie.rb b/activesupport/lib/active_support/railtie.rb index 6b8fa676a98..605b50d346c 100644 --- a/activesupport/lib/active_support/railtie.rb +++ b/activesupport/lib/active_support/railtie.rb @@ -70,9 +70,10 @@ module ActiveSupport end initializer "active_support.set_hash_digest_class" do |app| - if app.config.active_support.hash_digest_class - ActiveSupport::Digest.hash_digest_class = - app.config.active_support.hash_digest_class + config.after_initialize do + if app.config.active_support.use_sha1_digests + ActiveSupport::Digest.hash_digest_class = ::Digest::SHA1 + end end end end diff --git a/guides/source/caching_with_rails.md b/guides/source/caching_with_rails.md index 780e69c1466..cd9f4b4a68c 100644 --- a/guides/source/caching_with_rails.md +++ b/guides/source/caching_with_rails.md @@ -100,9 +100,9 @@ called key-based expiration. Cache fragments will also be expired when the view fragment changes (e.g., the HTML in the view changes). The string of characters at the end of the key is a -template tree digest. It is an MD5 hash computed based on the contents of the -view fragment you are caching. If you change the view fragment, the MD5 hash -will change, expiring the existing file. +template tree digest. It is a hash digest computed based on the contents of the +view fragment you are caching. If you change the view fragment, the digest will +change, expiring the existing file. TIP: Cache stores like Memcached will automatically delete old cache files. diff --git a/guides/source/configuring.md b/guides/source/configuring.md index 1668f9e81ad..879a1ea89f2 100644 --- a/guides/source/configuring.md +++ b/guides/source/configuring.md @@ -672,6 +672,8 @@ 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. Defaults to false. + * `ActiveSupport::Logger.silencer` is set to `false` to disable the ability to silence logging in a block. The default is `true`. * `ActiveSupport::Cache::Store.logger` specifies the logger to use within cache store operations. diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb index 5d8d6740c88..f02aef94e05 100644 --- a/railties/lib/rails/application/configuration.rb +++ b/railties/lib/rails/application/configuration.rb @@ -102,6 +102,7 @@ module Rails if respond_to?(:active_support) active_support.use_authenticated_message_encryption = true + active_support.use_sha1_digests = true end if respond_to?(:action_controller) diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_5_2.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_5_2.rb.tt index ae665b960aa..b4ef4558020 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_5_2.rb.tt +++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_5_2.rb.tt @@ -25,3 +25,6 @@ # Store boolean values are in sqlite3 databases as 1 and 0 instead of 't' and # 'f' after migrating old data. # Rails.application.config.active_record.sqlite3.represent_boolean_as_integer = true + +# Use SHA-1 instead of MD5 to generate non-sensitive digests, such as the ETag header. +# Rails.application.config.active_support.use_sha1_digests = true diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb index 437b1ded725..5f932f38dbf 100644 --- a/railties/test/application/configuration_test.rb +++ b/railties/test/application/configuration_test.rb @@ -1914,17 +1914,25 @@ module ApplicationTests assert_equal true, ActiveSupport::MessageEncryptor.use_authenticated_message_encryption end - test "config.active_support.hash_digest_class is Digest::MD5 by default" do + test "ActiveSupport::Digest.hash_digest_class is Digest::SHA1 by default for new apps" do + app "development" + + assert_equal Digest::SHA1, ActiveSupport::Digest.hash_digest_class + end + + test "ActiveSupport::Digest.hash_digest_class is Digest::MD5 by default for upgraded apps" do + remove_from_config '.*config\.load_defaults.*\n' + app "development" assert_equal Digest::MD5, ActiveSupport::Digest.hash_digest_class end - test "config.active_support.hash_digest_class can be configured" do - app_file "config/environments/development.rb", <<-RUBY - Rails.application.configure do - config.active_support.hash_digest_class = Digest::SHA1 - end + test "ActiveSupport::Digest.hash_digest_class can be configured via config.active_support.use_sha1_digests" do + remove_from_config '.*config\.load_defaults.*\n' + + app_file "config/initializers/new_framework_defaults_5_2.rb", <<-RUBY + Rails.application.config.active_support.use_sha1_digests = true RUBY app "development" diff --git a/railties/test/application/per_request_digest_cache_test.rb b/railties/test/application/per_request_digest_cache_test.rb index e9bc91785c2..10d3313f6e5 100644 --- a/railties/test/application/per_request_digest_cache_test.rb +++ b/railties/test/application/per_request_digest_cache_test.rb @@ -59,7 +59,7 @@ class PerRequestDigestCacheTest < ActiveSupport::TestCase assert_equal 200, last_response.status values = ActionView::LookupContext::DetailsKey.digest_caches.first.values - assert_equal [ "8ba099b7749542fe765ff34a6824d548" ], values + assert_equal [ "effc8928d0b33535c8a21d24ec617161" ], values assert_equal %w(david dingus), last_response.body.split.map(&:strip) end