diff options
-rw-r--r-- | actionpack/test/dispatch/cookies_test.rb | 19 | ||||
-rw-r--r-- | activesupport/lib/active_support/message_encryptor.rb | 2 | ||||
-rw-r--r-- | guides/source/security.md | 5 |
3 files changed, 23 insertions, 3 deletions
diff --git a/actionpack/test/dispatch/cookies_test.rb b/actionpack/test/dispatch/cookies_test.rb index 2051f7546f..40cbad3b0d 100644 --- a/actionpack/test/dispatch/cookies_test.rb +++ b/actionpack/test/dispatch/cookies_test.rb @@ -917,6 +917,25 @@ class CookiesTest < ActionController::TestCase assert_equal "bar", encryptor.decrypt_and_verify(@response.cookies["foo"]) end + def test_rotating_signed_cookies_digest + @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(45) + + @request.headers["Cookie"] = "user_id=#{old_value}" + get :get_signed_cookie + + assert_equal 45, @controller.send(:cookies).signed[:user_id] + + secret = key_generator.generate_key(@request.env["action_dispatch.signed_cookie_salt"]) + verifier = ActiveSupport::MessageVerifier.new(secret, digest: "SHA256") + assert_equal 45, verifier.verify(@response.cookies["user_id"]) + end + def test_legacy_hmac_aes_cbc_encrypted_marshal_cookie_is_upgraded_to_authenticated_encrypted_cookie key_generator = @request.env["action_dispatch.key_generator"] encrypted_cookie_salt = @request.env["action_dispatch.encrypted_cookie_salt"] diff --git a/activesupport/lib/active_support/message_encryptor.rb b/activesupport/lib/active_support/message_encryptor.rb index 8a1918039c..0cc4f58453 100644 --- a/activesupport/lib/active_support/message_encryptor.rb +++ b/activesupport/lib/active_support/message_encryptor.rb @@ -77,7 +77,7 @@ module ActiveSupport # Though if both the secret and the cipher was changed at the same time, # the above should be combined into: # - # verifier.rotate old_secret, cipher: "aes-256-cbc" + # crypt.rotate old_secret, cipher: "aes-256-cbc" class MessageEncryptor prepend Messages::Rotator::Encryptor diff --git a/guides/source/security.md b/guides/source/security.md index bf9af88c5d..cfa777d433 100644 --- a/guides/source/security.md +++ b/guides/source/security.md @@ -169,11 +169,12 @@ you would first assign the new configuration value: Rails.application.config.action_dispatch.signed_cookie_digest = "SHA256" ``` -Then you'd set up a rotation with the old configuration to keep it alive. +Now add a rotation for the old SHA1 digest so existing cookies are +seamlessly upgraded to the new SHA256 digest. ```ruby Rails.application.config.action_dispatch.cookies_rotations.tap do |cookies| - cookies.rotate :signed, digest: "SHA256" + cookies.rotate :signed, digest: "SHA1" end ``` |