reidmorrison / symmetric-encryption

Symmetric Encryption for Ruby Projects using OpenSSL

Home Page:https://logger.rocketjob.github.io/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Rails: Accessing the decrypted attribute corrupts the encrypted attribute content

gr8bit opened this issue · comments

Environment

Ruby 2.5.1
Rails 5.2.1
Symmetric Encryption 4.1.1

Symmetric Encryption config for environment

development:
  ciphers:
  - key: 1234567890ABCDEF
    iv: 1234567890ABCDEF
    cipher_name: aes-128-cbc
    version: 1
    encoding: :none
    always_add_header: true

class

class Foo < ActiveRecord::Base

	attr_encrypted :sender, random_iv: true

end

create a new model

2.5.1 :001 > i=Foo.create! sender: "+123456"
 => #<Foo id: 19, created_at: "2018-10-27 19:16:08", updated_at: "2018-10-27 19:16:08", encrypted_sender: "@EnC\x01@\x10\x00\\\x9C\xA1H!$\x98\xD99Uk\x16!\x16\x84\xBA\\\x80\x8Av\"\xA5\x03\xB2]\xED~Q\xC6\x9Es\xB8">
2.5.1 :002 > i.encrypted_sender_change
 => nil 
2.5.1 :003 > i.sender
 => "+123456" 
2.5.1 :004 > i.sender.present?
 => true 
2.5.1 :005 > i.encrypted_sender_change
 => nil 

load the newly created model

2.5.1 :001 > i=Foo.last
 => #<Foo id: 19, created_at: "2018-10-27 19:16:08", updated_at: "2018-10-27 19:16:08", encrypted_sender: "@EnC\x01@\x10\x00\\\x9C\xA1H!$\x98\xD99Uk\x16!\x16\x84\xBA\\\x80\x8Av\"\xA5\x03\xB2]\xED~Q\xC6\x9Es\xB8">
2.5.1 :002 > i.encrypted_sender_change
 => nil 
2.5.1 :003 > i.sender
 => "+123456" 
2.5.1 :004 > i.encrypted_sender_change
 => ["@EnC\x01@\x10\x00\\\x9C\xA1H!$\x98\xD99Uk\x16!\x16\x84\xBA\\\x80\x8Av\"\xA5\x03\xB2]\xED~Q\xC6\x9Es\xB8", "\\\x80\x8Av\"\xA5\x03\xB2]\xED~Q\xC6\x9Es\xB8"] 

Why does accessing the attribute trigger a change?
If I save the model, the encrypted_sender attribute is filled with corrupted data (actually saving fails thanks to the symmetric_encryption validator).

Expected Behavior

Accessing an encrypted attribute should not trigger a change, rendering the model in dirty state.

Actual Behavior

Accessing the "sender" encrypted attribute sets it with corrupted data (missing header?)

I found the bug. I use encoding: :none in the config and the SymmetricEncryption::Encoder::None is the only encoder which doesn't create a new string object on encode and decode but rather returns the passed string as-is.
At some point SymmetricEncryption.decrypt() calls header.parse!(decoded) which modifies the variable decoded in place, which -in our case- is still the original encrypted string. So the original attribute becomes cropped in place and by that, invalid.

PR is on the way.