diff --git a/app/services/encryption/password_verifier.rb b/app/services/encryption/password_verifier.rb index 35e556e6534..feff92188b4 100644 --- a/app/services/encryption/password_verifier.rb +++ b/app/services/encryption/password_verifier.rb @@ -8,7 +8,7 @@ class PasswordVerifier keyword_init: true, ) do def self.parse_from_string(digest_string) - data = JSON.parse(digest_string, symbolize_names: true) + data = JSON.parse(digest_string, symbolize_names: true).slice(*members) new(data) rescue JSON::ParserError, TypeError, ArgumentError raise EncryptionError, 'digest contains invalid json' diff --git a/app/services/pii/attributes.rb b/app/services/pii/attributes.rb index dfc4e70211b..21290b1485e 100644 --- a/app/services/pii/attributes.rb +++ b/app/services/pii/attributes.rb @@ -12,8 +12,8 @@ module Pii ) do def self.new_from_hash(hash) attrs = new - hash. - select { |key, _val| members.include?(key&.to_sym) }. + hash.with_indifferent_access. + slice(*members). each { |key, val| attrs[key] = val } attrs end diff --git a/app/services/x509/attributes.rb b/app/services/x509/attributes.rb index d497b41bfaa..9463a39f1b3 100644 --- a/app/services/x509/attributes.rb +++ b/app/services/x509/attributes.rb @@ -4,7 +4,7 @@ module X509 ) do def self.new_from_hash(hash) attrs = new - hash.each { |key, val| attrs[key] = val } + hash.slice(*members).each { |key, val| attrs[key] = val } attrs end diff --git a/spec/services/encryption/encryptors/pii_encryptor_spec.rb b/spec/services/encryption/encryptors/pii_encryptor_spec.rb index b1eb85c6eb7..27ce0ca94a1 100644 --- a/spec/services/encryption/encryptors/pii_encryptor_spec.rb +++ b/spec/services/encryption/encryptors/pii_encryptor_spec.rb @@ -6,6 +6,18 @@ subject { described_class.new(password) } + describe Encryption::Encryptors::PiiEncryptor::Ciphertext do + describe '.parse_from_string' do + it 'does not blow up with unknown/new keys' do + blob = Encryption::Encryptors::PiiEncryptor::Ciphertext.new('encrypted_data').to_s + str = JSON.parse(blob).merge(some_new_field: 'some_new_field').to_json + + ciphertext = Encryption::Encryptors::PiiEncryptor::Ciphertext.parse_from_string(str) + expect(ciphertext.encrypted_data).to eq('encrypted_data') + end + end + end + describe '#encrypt' do it 'returns encrypted text' do ciphertext = subject.encrypt(plaintext, user_uuid: 'uuid-123-abc') diff --git a/spec/services/encryption/password_verifier_spec.rb b/spec/services/encryption/password_verifier_spec.rb index 73666eb4559..1bd47c8497a 100644 --- a/spec/services/encryption/password_verifier_spec.rb +++ b/spec/services/encryption/password_verifier_spec.rb @@ -4,6 +4,23 @@ let(:password) { 'saltypickles' } let(:user_uuid) { 'asdf-1234' } + describe Encryption::PasswordVerifier::PasswordDigest do + describe '.parse_from_string' do + it 'does not blow up with unknown/new keys' do + str = { + encrypted_password: 'encrypted_password', + encryption_key: 'encryption_key', + password_salt: 'password_salt', + password_cost: 'password_cost', + some_new_field: 'some_new_field', + }.to_json + + digest = Encryption::PasswordVerifier::PasswordDigest.parse_from_string(str) + expect(digest.encrypted_password).to eq('encrypted_password') + end + end + end + describe '#digest' do it 'creates a digest from the password' do salt = '1' * 64 # 32 hex encoded bytes is 64 characters diff --git a/spec/services/encryption/uak_password_verifier_spec.rb b/spec/services/encryption/uak_password_verifier_spec.rb index 163ce803494..c6f7a13e6f3 100644 --- a/spec/services/encryption/uak_password_verifier_spec.rb +++ b/spec/services/encryption/uak_password_verifier_spec.rb @@ -1,6 +1,24 @@ require 'rails_helper' describe Encryption::UakPasswordVerifier do + describe Encryption::UakPasswordVerifier::PasswordDigest do + describe '.parse_from_string' do + it 'does not blow up with unknown/new keys' do + digest = Encryption::UakPasswordVerifier.digest('password') + str = JSON.parse(digest).merge(some_new_field: 'some_new_field').to_json + + digest = Encryption::UakPasswordVerifier::PasswordDigest.parse_from_string(str) + expect(digest.encrypted_password).to be_present + end + + it 'raises an encryption error when the password digest is nil' do + expect do + Encryption::UakPasswordVerifier::PasswordDigest.parse_from_string(nil) + end.to raise_error(Encryption::EncryptionError) + end + end + end + describe '.digest' do it 'creates a digest from the password' do salt = '1' * 64 # 32 hex encoded bytes is 64 characters @@ -72,10 +90,4 @@ expect(result).to eq(true) end end - - it 'raises an encryption error when the password digest is nil' do - expect do - Encryption::UakPasswordVerifier::PasswordDigest.parse_from_string(nil) - end.to raise_error(Encryption::EncryptionError) - end end diff --git a/spec/services/pii/attributes_spec.rb b/spec/services/pii/attributes_spec.rb index 2c54e600123..e84ad7ae39d 100644 --- a/spec/services/pii/attributes_spec.rb +++ b/spec/services/pii/attributes_spec.rb @@ -26,6 +26,15 @@ expect(pii.last_name).to eq nil end + + it 'ignores unknown keys' do + pii = described_class.new_from_hash( + first_name: 'Test', + some_unknown_field: 'unknown', + ) + + expect(pii.first_name).to eq('Test') + end end describe '#new_from_json' do diff --git a/spec/services/x509/attributes_spec.rb b/spec/services/x509/attributes_spec.rb index f4b22cade00..fbb5291af48 100644 --- a/spec/services/x509/attributes_spec.rb +++ b/spec/services/x509/attributes_spec.rb @@ -27,6 +27,15 @@ expect(x509.subject).to eq nil expect(x509.presented).to eq nil end + + it 'ignores unknown keys' do + x509 = described_class.new_from_hash( + subject: 'O=US, OU=DoD, CN=John.Doe.1234', + some_unknown_field: 'unknown', + ) + + expect(x509.subject).to eq('O=US, OU=DoD, CN=John.Doe.1234') + end end describe '#new_from_json' do