class Rack::Protection::EncryptedCookie
def initialize(app, options = {})
def initialize(app, options = {}) # Assume keys are hex strings and convert them to raw byte strings for # actual key material @secrets = options.values_at(:secret, :old_secret).compact.map do |secret| [secret].pack('H*') end warn <<-MSG unless secure?(options) SECURITY WARNING: No secret option provided to Rack::Protection::EncryptedCookie. This poses a security threat. It is strongly recommended that you provide a secret to prevent exploits that may be possible from crafted cookies. This will not be supported in future versions of Rack, and future versions will even invalidate your existing user cookies. Called from: #{caller[0]}. MSG warn <<-MSG if @secrets.first && @secrets.first.length < 32 SECURITY WARNING: Your secret is not long enough. It must be at least 32 bytes long and securely random. To generate such a key for use you can run the following command: ruby -rsecurerandom -e 'p SecureRandom.hex(32)' Called from: #{caller[0]}. MSG if options.key?(:legacy_hmac_secret) @legacy_hmac = options.fetch(:legacy_hmac, OpenSSL::Digest::SHA1) # Multiply the :digest_length: by 2 because this value is the length of # the digest in bytes but session digest strings are encoded as hex # strings @legacy_hmac_length = @legacy_hmac.new.digest_length * 2 @legacy_hmac_secret = options[:legacy_hmac_secret] @legacy_hmac_coder = (options[:legacy_hmac_coder] ||= Base64::Marshal.new) else @legacy_hmac = false end # If encryption is used we can just use a default Marshal encoder # without Base64 encoding the results. # # If no encryption is used, rely on the previous default (Base64::Marshal) @coder = (options[:coder] ||= (@secrets.any? ? Marshal.new : Base64::Marshal.new)) super(app, options.merge!(cookie_only: true)) end