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

Validate encrypted message formats

This prevents parsing random JSON data as encrypted payloads during
initial encryption processes
This commit is contained in:
Jorge Manrubia 2021-10-15 16:13:34 +02:00 committed by Jeremy Daer
parent 5b33d46705
commit 42c625af50
2 changed files with 30 additions and 2 deletions

View file

@ -33,10 +33,20 @@ module ActiveRecord
private
def parse_message(data, level)
raise ActiveRecord::Encryption::Errors::Decryption, "More than one level of hash nesting in headers is not supported" if level > 2
validate_message_data_format(data, level)
ActiveRecord::Encryption::Message.new(payload: decode_if_needed(data["p"]), headers: parse_properties(data["h"], level))
end
def validate_message_data_format(data, level)
if level > 2
raise ActiveRecord::Encryption::Errors::Decryption, "More than one level of hash nesting in headers is not supported"
end
unless data.is_a?(Hash) && data.has_key?("p")
raise ActiveRecord::Encryption::Errors::Decryption, "Invalid data format: hash without payload"
end
end
def parse_properties(headers, level)
ActiveRecord::Encryption::Properties.new.tap do |properties|
headers&.each do |key, value|

View file

@ -22,12 +22,30 @@ class ActiveRecord::Encryption::MessageSerializerTest < ActiveRecord::Encryption
end
test "won't load classes from JSON" do
class_loading_payload = '{"json_class": "MessageSerializerTest::SomeClassThatWillNeverExist"}'
class_loading_payload = JSON.dump({ p: ::Base64.strict_encode64("Some payload"), json_class: "MessageSerializerTest::SomeClassThatWillNeverExist" })
assert_raises(ArgumentError) { JSON.load(class_loading_payload) }
assert_nothing_raised { @serializer.load(class_loading_payload) }
end
test "detects random JSON data and raises an invalid dencryption error" do
assert_raises ActiveRecord::Encryption::Errors::Decryption do
@serializer.load JSON.dump("hey there")
end
end
test "detects random JSON hashes and raises an invalid decryption error" do
assert_raises ActiveRecord::Encryption::Errors::Decryption do
@serializer.load JSON.dump({ some: "other data" })
end
end
test "detects JSON hashes with a 'p' key that is not encoded in base64" do
assert_raises ActiveRecord::Encryption::Errors::Encoding do
@serializer.load JSON.dump({ p: "some data not encoded" })
end
end
test "raises ForbiddenClass when trying to serialize other data types" do
assert_raises ActiveRecord::Encryption::Errors::ForbiddenClass do
@serializer.dump("it can only serialize messages!")