diff --git a/activesupport/lib/active_support/message_encryptor.rb b/activesupport/lib/active_support/message_encryptor.rb index bffdfc62019cdd4bac2067754c9b20648a3fe083..7773611e110744852d37b1a43227110e1c51a7de 100644 --- a/activesupport/lib/active_support/message_encryptor.rb +++ b/activesupport/lib/active_support/message_encryptor.rb @@ -76,12 +76,12 @@ def _encrypt(value) encrypted_data = cipher.update(@serializer.dump(value)) encrypted_data << cipher.final - [encrypted_data, iv].map {|v| ::Base64.strict_encode64(v)}.join("--") + "#{::Base64.strict_encode64 encrypted_data}--#{::Base64.strict_encode64 iv}" end def _decrypt(encrypted_message) cipher = new_cipher - encrypted_data, iv = encrypted_message.split("--").map {|v| ::Base64.decode64(v)} + encrypted_data, iv = encrypted_message.split("--").map {|v| ::Base64.strict_decode64(v)} cipher.decrypt cipher.key = @secret @@ -91,7 +91,7 @@ def _decrypt(encrypted_message) decrypted_data << cipher.final @serializer.load(decrypted_data) - rescue OpenSSLCipherError, TypeError + rescue OpenSSLCipherError, TypeError, ArgumentError raise InvalidMessage end diff --git a/activesupport/lib/active_support/message_verifier.rb b/activesupport/lib/active_support/message_verifier.rb index e0cd92ae3cb093221aa3a70af63ce197846e6a9e..a35d5980fe988f7f1b70b56973253a708ee0da86 100644 --- a/activesupport/lib/active_support/message_verifier.rb +++ b/activesupport/lib/active_support/message_verifier.rb @@ -37,7 +37,11 @@ def verify(signed_message) data, digest = signed_message.split("--") if data.present? && digest.present? && secure_compare(digest, generate_digest(data)) - @serializer.load(::Base64.decode64(data)) + begin + @serializer.load(::Base64.strict_decode64(data)) + rescue ArgumentError + raise InvalidSignature + end else raise InvalidSignature end diff --git a/activesupport/test/message_encryptor_test.rb b/activesupport/test/message_encryptor_test.rb index 203156baa12c92e691aafeac2fe1080296e5648c..b6c0a08b05411f6094cd20da19358ddc93b55a07 100644 --- a/activesupport/test/message_encryptor_test.rb +++ b/activesupport/test/message_encryptor_test.rb @@ -66,6 +66,17 @@ def test_alternative_serialization_method ActiveSupport.use_standard_json_time_format = prev end + def test_message_obeys_strict_encoding + bad_encoding_characters = "\n!@#" + message, iv = @encryptor.encrypt_and_sign("This is a very \n\nhumble string"+bad_encoding_characters) + + assert_not_decrypted("#{::Base64.encode64 message.to_s}--#{::Base64.encode64 iv.to_s}") + assert_not_verified("#{::Base64.encode64 message.to_s}--#{::Base64.encode64 iv.to_s}") + + assert_not_decrypted([iv, message] * bad_encoding_characters) + assert_not_verified([iv, message] * bad_encoding_characters) + end + private def assert_not_decrypted(value) @@ -81,7 +92,7 @@ def assert_not_verified(value) end def munge(base64_string) - bits = ::Base64.decode64(base64_string) + bits = ::Base64.strict_decode64(base64_string) bits.reverse! ::Base64.strict_encode64(bits) end