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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions