Shinichi Maeshima
Posted on November 26, 2024
What is config.active_support.hash_digest_class = OpenSSL::Digest::SHA256
?
I occasionally update the config.load_defaults
version at work in Rails applications. This involves understanding the purpose of each new configuration in the target version, assessing its impact, and creating individual pull requests for each change. Based on my experience, this process can be quite challenging, and I suspect few projects carry it out with a thorough understanding of the impact. I decided to write this blog post to assist others planning to update config.load_defaults
.
Today, I’ll focus on config.active_support.hash_digest_class = OpenSSL::Digest::SHA256
, which is included in config.load_defaults 7.0
.
- Relevant Commit: Change the default digest for new apps to SHA256 · rails/rails@ba9207f
- Related Documentation: Upgrading Ruby on Rails — Ruby on Rails Guides
This setting changes the default hash function used for cache keys to SHA256. The default was originally MD5, then updated to SHA1 in Rails 5.2, and now to SHA256 in Rails 7.0.
Since this hash function primarily applies to cache keys, the change wasn’t prompted by security issues with SHA1. Instead, the shift to SHA256 aligns Rails with modern security standards, simplifying compliance checks.
Related Areas in Rails
The following are the main areas in Rails where this hash function is used:
-
Determining keys for fragment cache templates
- Used to compute the template tree digest in the
cache
method.
- Used to compute the template tree digest in the
-
Setting cache keys when using
cache(User.all)
with anActiveRecord::Relation
- Specifically, it computes the
id
portion of the key.
- Specifically, it computes the
-
Generating strong ETags
- Reference: Rails Caching Guide
- Shortening long cache keys
You can safely apply this setting change if your project doesn’t rely on these caching features.
How to Verify Affected Areas
You can verify whether caching is used by adding a monkey patch like the following, which logs whenever ActiveSupport::Digest.hexdigest
is called. This works for all related areas except "shortening long cache keys." Merge logs appropriately if your CI runs tests in parallel.
# config/application.rb or config/initializers/something.rb
module MonkeyPatch
def monkeypatch_logger
@monkeypatch_logger ||= Logger.new(Rails.root.join('log/monkeypatch.log'))
end
def hexdigest(*)
monkeypatch_logger.debug("ActiveSupport::Digest.hexdigest is called from: #{caller(2, 1).first}")
super
end
end
class ActiveSupport::Digest
class << self
prepend MonkeyPatch
end
end
Before running tests, enable caching and set the cache store to :null_store
to avoid unexpected behavior:
# config/environments/test.rb
config.action_controller.perform_caching = true
config.cache_store = :null_store
If you find any areas using caching, note that this change will invalidate all related caches after deployment. This could increase server or database load, so consider temporarily scaling up your application servers and database resources to handle the extra traffic.
Posted on November 26, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.