From 36b25aa1c4863cc70c74fd783fb54ba44a3a128e Mon Sep 17 00:00:00 2001
From: Milo Winningham <milo@winningham.net>
Date: Fri, 21 Jun 2019 23:29:05 -0700
Subject: Add test for cookie being modified by rotation

---
 actionpack/test/dispatch/cookies_test.rb | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/actionpack/test/dispatch/cookies_test.rb b/actionpack/test/dispatch/cookies_test.rb
index d129fa717d..e4d4792de6 100644
--- a/actionpack/test/dispatch/cookies_test.rb
+++ b/actionpack/test/dispatch/cookies_test.rb
@@ -893,6 +893,19 @@ class CookiesTest < ActionController::TestCase
     assert_equal 45, encryptor.decrypt_and_verify(@response.cookies["foo"])
   end
 
+  def test_cookie_with_hash_value_not_modified_by_rotation
+    @request.env["action_dispatch.signed_cookie_digest"] = "SHA256"
+    @request.env["action_dispatch.cookies_rotations"].rotate :signed, digest: "SHA1"
+
+    key_generator = @request.env["action_dispatch.key_generator"]
+    old_secret = key_generator.generate_key(@request.env["action_dispatch.signed_cookie_salt"])
+    old_value = ActiveSupport::MessageVerifier.new(old_secret).generate(bar: "baz")
+
+    @request.headers["Cookie"] = "foo=#{old_value}"
+    get :get_signed_cookie
+    assert_equal({ bar: "baz" }, @controller.send(:cookies).signed[:foo])
+  end
+
   def test_cookie_with_all_domain_option
     get :set_cookie_with_domain
     assert_response :success
-- 
cgit v1.2.3


From 27db230bd105e77e27375033ddcb487ef481686b Mon Sep 17 00:00:00 2001
From: Milo Winningham <milo@winningham.net>
Date: Sat, 22 Jun 2019 00:09:44 -0700
Subject: Prevent serialized hash from being used as options

---
 actionpack/lib/action_dispatch/middleware/cookies.rb | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb
index 642f155085..1f3bf7fca6 100644
--- a/actionpack/lib/action_dispatch/middleware/cookies.rb
+++ b/actionpack/lib/action_dispatch/middleware/cookies.rb
@@ -532,9 +532,13 @@ module ActionDispatch
           if value
             case
             when needs_migration?(value)
-              self[name] = Marshal.load(value)
+              Marshal.load(value).tap do |v|
+                self[name] = { value: v }
+              end
             when rotate
-              self[name] = serializer.load(value)
+              serializer.load(value).tap do |v|
+                self[name] = { value: v }
+              end
             else
               serializer.load(value)
             end
-- 
cgit v1.2.3