Skip to content

Encryption and decryption is not thread safe #344

@DimitriosLisenko

Description

@DimitriosLisenko

We are observing the following sporadic errors when using this gem:

  • ArgumentError with must specify an iv
  • OpenSSL::Cipher::CipherError

I can replicate this with multiple threads - when one thread is setting the encrypted value to an empty string, and another is setting it to a non-empty string, it's possible for the internal state of @encrypted_attributes to be changed such that the iv is not loaded when it is actually required.

Here is a reproduction script for the ArgumentError, using the example in the current README (though I have also obtained the OpenSSL::Cipher::CipherError with it when I was saving objects to the database):

require "securerandom"
class TestCase
	extend AttrEncrypted
	attr_accessor :name
	attr_encrypted :ssn, key: SecureRandom.hex(16)
end

def replicate_issue(x, times)
	loop do
		threads = []
		times.times do
			threads << Thread.new do
				x.ssn = ""
			end
			threads << Thread.new do
				x.ssn = "hello"
			end
		end
		threads.each(&:join)
	end
end

x = TestCase.new
replicate_issue(x, 10)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions