提交 2a412b3d 编写于 作者: G Godfrey Chan

Fixed an issue with migrating legacy json cookies.

Previously, the `VerifyAndUpgradeLegacySignedMessage` assumes all incoming
cookies are marshal-encoded. This is not the case when `secret_token` is
used in conjunction with the `:json` or `:hybrid` serializer.

In those case, when upgrading to use `secret_key_base`, this would cause a
`TypeError: incompatible marshal file format` and a 500 error for the user.

Fixes #14774.

*Godfrey Chan*
上级 650585da
* Fixed an issue with migrating legacy json cookies.
Previously, the `VerifyAndUpgradeLegacySignedMessage` assumes all incoming
cookies are marshal-encoded. This is not the case when `secret_token` is
used in conjunction with the `:json` or `:hybrid` serializer.
In those case, when upgrading to use `secret_key_base`, this would cause a
`TypeError: incompatible marshal file format` and a 500 error for the user.
Fixes #14774.
*Godfrey Chan*
* Make URL escaping more consistent:
1. Escape '%' characters in URLs - only unescaped data should be passed to URL helpers
......
......@@ -176,11 +176,11 @@ def signed_or_encrypted
module VerifyAndUpgradeLegacySignedMessage
def initialize(*args)
super
@legacy_verifier = ActiveSupport::MessageVerifier.new(@options[:secret_token])
@legacy_verifier = ActiveSupport::MessageVerifier.new(@options[:secret_token], serializer: NullSerializer)
end
def verify_and_upgrade_legacy_signed_message(name, signed_message)
@legacy_verifier.verify(signed_message).tap do |value|
deserialize(name, @legacy_verifier.verify(signed_message)).tap do |value|
self[name] = { value: value }
end
rescue ActiveSupport::MessageVerifier::InvalidSignature
......
......@@ -681,6 +681,123 @@ def test_legacy_signed_cookie_is_read_and_transparently_encrypted_by_encrypted_c
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
@request.env["action_dispatch.cookies_serializer"] = :json
@request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33"
@request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff"
legacy_value = ActiveSupport::MessageVerifier.new("b3c631c314c0bbca50c1b2843150fe33", serializer: JSON).generate(45)
@request.headers["Cookie"] = "user_id=#{legacy_value}"
get :get_signed_cookie
assert_equal 45, @controller.send(:cookies).signed[:user_id]
key_generator = @request.env["action_dispatch.key_generator"]
secret = key_generator.generate_key(@request.env["action_dispatch.signed_cookie_salt"])
verifier = ActiveSupport::MessageVerifier.new(secret, serializer: JSON)
assert_equal 45, verifier.verify(@response.cookies["user_id"])
end
def test_legacy_json_signed_cookie_is_read_and_transparently_encrypted_by_encrypted_json_cookie_jar_if_both_secret_token_and_secret_key_base_are_set
@request.env["action_dispatch.cookies_serializer"] = :json
@request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33"
@request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff"
@request.env["action_dispatch.encrypted_cookie_salt"] = "4433796b79d99a7735553e316522acee"
@request.env["action_dispatch.encrypted_signed_cookie_salt"] = "00646eb40062e1b1deff205a27cd30f9"
legacy_value = ActiveSupport::MessageVerifier.new("b3c631c314c0bbca50c1b2843150fe33", serializer: JSON).generate('bar')
@request.headers["Cookie"] = "foo=#{legacy_value}"
get :get_encrypted_cookie
assert_equal 'bar', @controller.send(:cookies).encrypted[:foo]
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"])
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
@request.env["action_dispatch.cookies_serializer"] = :hybrid
@request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33"
@request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff"
legacy_value = ActiveSupport::MessageVerifier.new("b3c631c314c0bbca50c1b2843150fe33", serializer: JSON).generate(45)
@request.headers["Cookie"] = "user_id=#{legacy_value}"
get :get_signed_cookie
assert_equal 45, @controller.send(:cookies).signed[:user_id]
key_generator = @request.env["action_dispatch.key_generator"]
secret = key_generator.generate_key(@request.env["action_dispatch.signed_cookie_salt"])
verifier = ActiveSupport::MessageVerifier.new(secret, serializer: JSON)
assert_equal 45, verifier.verify(@response.cookies["user_id"])
end
def test_legacy_json_signed_cookie_is_read_and_transparently_encrypted_by_encrypted_hybrid_cookie_jar_if_both_secret_token_and_secret_key_base_are_set
@request.env["action_dispatch.cookies_serializer"] = :hybrid
@request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33"
@request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff"
@request.env["action_dispatch.encrypted_cookie_salt"] = "4433796b79d99a7735553e316522acee"
@request.env["action_dispatch.encrypted_signed_cookie_salt"] = "00646eb40062e1b1deff205a27cd30f9"
legacy_value = ActiveSupport::MessageVerifier.new("b3c631c314c0bbca50c1b2843150fe33", serializer: JSON).generate('bar')
@request.headers["Cookie"] = "foo=#{legacy_value}"
get :get_encrypted_cookie
assert_equal 'bar', @controller.send(:cookies).encrypted[:foo]
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"])
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
@request.env["action_dispatch.cookies_serializer"] = :hybrid
@request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33"
@request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff"
legacy_value = ActiveSupport::MessageVerifier.new("b3c631c314c0bbca50c1b2843150fe33").generate(45)
@request.headers["Cookie"] = "user_id=#{legacy_value}"
get :get_signed_cookie
assert_equal 45, @controller.send(:cookies).signed[:user_id]
key_generator = @request.env["action_dispatch.key_generator"]
secret = key_generator.generate_key(@request.env["action_dispatch.signed_cookie_salt"])
verifier = ActiveSupport::MessageVerifier.new(secret, serializer: JSON)
assert_equal 45, verifier.verify(@response.cookies["user_id"])
end
def test_legacy_marshal_signed_cookie_is_read_and_transparently_encrypted_by_encrypted_hybrid_cookie_jar_if_both_secret_token_and_secret_key_base_are_set
@request.env["action_dispatch.cookies_serializer"] = :hybrid
@request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33"
@request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff"
@request.env["action_dispatch.encrypted_cookie_salt"] = "4433796b79d99a7735553e316522acee"
@request.env["action_dispatch.encrypted_signed_cookie_salt"] = "00646eb40062e1b1deff205a27cd30f9"
legacy_value = ActiveSupport::MessageVerifier.new("b3c631c314c0bbca50c1b2843150fe33").generate('bar')
@request.headers["Cookie"] = "foo=#{legacy_value}"
get :get_encrypted_cookie
assert_equal 'bar', @controller.send(:cookies).encrypted[:foo]
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"])
end
def test_legacy_signed_cookie_is_treated_as_nil_by_signed_cookie_jar_if_tampered
@request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33"
@request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册