1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Follow up of #25602

Since keys are truncated, ruby 2.4 doesn't accept keys greater than their lenghts.
keys of same value but different lenght and greater than key size of cipher, produce the same results
as reproduced at https://gist.github.com/rhenium/b81355fe816dcfae459cc5eadfc4f6f9
Since our default cipher is 'aes-256-cbc', key length for which is 32 bytes, limit the length of key being passed to Encryptor to 32 bytes.
This continues to support backwards compat with any existing signed data, already encrupted and signed with 32+ byte keys.
Also fixes the passing of this value in multiple tests.
This commit is contained in:
Vipul A M 2016-07-09 04:03:43 -07:00
parent fd2446cd81
commit ae32b69ab9
No known key found for this signature in database
GPG key ID: 4C9362FE1F574587
3 changed files with 41 additions and 15 deletions

View file

@ -567,17 +567,19 @@ module ActionDispatch
class EncryptedCookieJar < AbstractCookieJar # :nodoc:
include SerializedCookieJars
DEFAULT_CIPHER = 'aes-256-cbc'
def initialize(parent_jar)
super
def initialize(parent_jar, cipher: DEFAULT_CIPHER)
super(parent_jar)
if ActiveSupport::LegacyKeyGenerator === key_generator
raise "You didn't set secrets.secret_key_base, which is required for this cookie jar. " +
"Read the upgrade documentation to learn more about this new config option."
end
secret = key_generator.generate_key(request.encrypted_cookie_salt || "")
sign_secret = key_generator.generate_key(request.encrypted_signed_cookie_salt || "")
key_len = OpenSSL::Cipher.new(cipher).key_len
secret = key_generator.generate_key(request.encrypted_cookie_salt || '')[0, key_len]
sign_secret = key_generator.generate_key(request.encrypted_signed_cookie_salt || '')
@encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret, digest: digest, serializer: ActiveSupport::MessageEncryptor::NullSerializer)
end

View file

@ -603,7 +603,7 @@ class CookiesTest < ActionController::TestCase
secret = key_generator.generate_key(encrypted_cookie_salt)
sign_secret = key_generator.generate_key(encrypted_signed_cookie_salt)
marshal_value = ActiveSupport::MessageEncryptor.new(secret, sign_secret, serializer: Marshal).encrypt_and_sign("bar")
marshal_value = ActiveSupport::MessageEncryptor.new(secret[0..31], sign_secret, serializer: Marshal).encrypt_and_sign("bar")
@request.headers["Cookie"] = "foo=#{marshal_value}"
get :get_encrypted_cookie
@ -612,7 +612,7 @@ class CookiesTest < ActionController::TestCase
assert_not_equal "bar", cookies[:foo]
assert_equal "bar", cookies.encrypted[:foo]
encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret, serializer: JSON)
encryptor = ActiveSupport::MessageEncryptor.new(secret[0..31], sign_secret, serializer: JSON)
assert_equal "bar", encryptor.decrypt_and_verify(@response.cookies["foo"])
end
@ -624,7 +624,7 @@ class CookiesTest < ActionController::TestCase
encrypted_signed_cookie_salt = @request.env["action_dispatch.encrypted_signed_cookie_salt"]
secret = key_generator.generate_key(encrypted_cookie_salt)
sign_secret = key_generator.generate_key(encrypted_signed_cookie_salt)
json_value = ActiveSupport::MessageEncryptor.new(secret, sign_secret, serializer: JSON).encrypt_and_sign("bar")
json_value = ActiveSupport::MessageEncryptor.new(secret[0..31], sign_secret, serializer: JSON).encrypt_and_sign("bar")
@request.headers["Cookie"] = "foo=#{json_value}"
get :get_encrypted_cookie
@ -636,6 +636,20 @@ class CookiesTest < ActionController::TestCase
assert_nil @response.cookies["foo"]
end
def test_compat_encrypted_cookie_using_64_byte_key
# Cookie generated with 64 bytes secret
message = ["566d4e75536d686e633246564e6b493062557079626c566d51574d30515430394c53315665564a694e4563786555744f57537454576b396a5a31566a626e52525054303d2d2d34663234333330623130623261306163363562316266323335396164666364613564643134623131"].pack('H*')
@request.headers["Cookie"] = "foo=#{message}"
get :get_encrypted_cookie
cookies = @controller.send :cookies
assert_not_equal "bar", cookies[:foo]
assert_equal "bar", cookies.encrypted[:foo]
assert_nil @response.cookies["foo"]
end
def test_accessing_nonexistent_encrypted_cookie_should_not_raise_invalid_message
get :set_encrypted_cookie
assert_nil @controller.send(:cookies).encrypted[:non_existent_attribute]
@ -799,8 +813,8 @@ class CookiesTest < ActionController::TestCase
key_generator = @request.env["action_dispatch.key_generator"]
secret = key_generator.generate_key(@request.env["action_dispatch.encrypted_cookie_salt"])
sign_secret = key_generator.generate_key(@request.env["action_dispatch.encrypted_signed_cookie_salt"])
encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret)
assert_equal "bar", encryptor.decrypt_and_verify(@response.cookies["foo"])
encryptor = ActiveSupport::MessageEncryptor.new(secret[0..31], sign_secret)
assert_equal 'bar', encryptor.decrypt_and_verify(@response.cookies["foo"])
end
def test_legacy_json_signed_cookie_is_read_and_transparently_upgraded_by_signed_json_cookie_jar_if_both_secret_token_and_secret_key_base_are_set
@ -838,8 +852,8 @@ class CookiesTest < ActionController::TestCase
key_generator = @request.env["action_dispatch.key_generator"]
secret = key_generator.generate_key(@request.env["action_dispatch.encrypted_cookie_salt"])
sign_secret = key_generator.generate_key(@request.env["action_dispatch.encrypted_signed_cookie_salt"])
encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret, serializer: JSON)
assert_equal "bar", encryptor.decrypt_and_verify(@response.cookies["foo"])
encryptor = ActiveSupport::MessageEncryptor.new(secret[0..31], sign_secret, serializer: JSON)
assert_equal 'bar', encryptor.decrypt_and_verify(@response.cookies["foo"])
end
def test_legacy_json_signed_cookie_is_read_and_transparently_upgraded_by_signed_json_hybrid_jar_if_both_secret_token_and_secret_key_base_are_set
@ -877,8 +891,8 @@ class CookiesTest < ActionController::TestCase
key_generator = @request.env["action_dispatch.key_generator"]
secret = key_generator.generate_key(@request.env["action_dispatch.encrypted_cookie_salt"])
sign_secret = key_generator.generate_key(@request.env["action_dispatch.encrypted_signed_cookie_salt"])
encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret, serializer: JSON)
assert_equal "bar", encryptor.decrypt_and_verify(@response.cookies["foo"])
encryptor = ActiveSupport::MessageEncryptor.new(secret[0..31], sign_secret, serializer: JSON)
assert_equal 'bar', encryptor.decrypt_and_verify(@response.cookies["foo"])
end
def test_legacy_marshal_signed_cookie_is_read_and_transparently_upgraded_by_signed_json_hybrid_jar_if_both_secret_token_and_secret_key_base_are_set
@ -916,8 +930,8 @@ class CookiesTest < ActionController::TestCase
key_generator = @request.env["action_dispatch.key_generator"]
secret = key_generator.generate_key(@request.env["action_dispatch.encrypted_cookie_salt"])
sign_secret = key_generator.generate_key(@request.env["action_dispatch.encrypted_signed_cookie_salt"])
encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret, serializer: JSON)
assert_equal "bar", encryptor.decrypt_and_verify(@response.cookies["foo"])
encryptor = ActiveSupport::MessageEncryptor.new(secret[0..31], sign_secret, serializer: JSON)
assert_equal 'bar', encryptor.decrypt_and_verify(@response.cookies["foo"])
end
def test_legacy_signed_cookie_is_treated_as_nil_by_signed_cookie_jar_if_tampered

View file

@ -48,6 +48,16 @@ class MessageEncryptorTest < ActiveSupport::TestCase
assert_equal @data, @encryptor.decrypt_and_verify(message)
end
def test_backwards_compat_for_64_bytes_key
# 64 bit key
secret = ["3942b1bf81e622559ed509e3ff274a780784fe9e75b065866bd270438c74da822219de3156473cc27df1fd590e4baf68c95eeb537b6e4d4c5a10f41635b5597e"].pack('H*')
# Encryptor with 32 bit key, 64 bit secret for verifier
encryptor = ActiveSupport::MessageEncryptor.new(secret[0..31], secret)
# Message generated with 64 bit key
message = "eHdGeExnZEwvMSt3U3dKaFl1WFo0TjVvYzA0eGpjbm5WSkt5MXlsNzhpZ0ZnbWhBWFlQZTRwaXE1bVJCS2oxMDZhYVp2dVN3V0lNZUlWQ3c2eVhQbnhnVjFmeVVubmhRKzF3WnZyWHVNMDg9LS1HSisyakJVSFlPb05ISzRMaXRzcFdBPT0=--831a1d54a3cda8a0658dc668a03dedcbce13b5ca"
assert_equal 'data', encryptor.decrypt_and_verify(message)[:some]
end
def test_alternative_serialization_method
prev = ActiveSupport.use_standard_json_time_format
ActiveSupport.use_standard_json_time_format = true