-
Notifications
You must be signed in to change notification settings - Fork 427
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Encryption and decryption is not thread safe #344
Comments
Looks like this is fixed in master: d4ca0e2 Took us a while to figure this out too. This seems pretty bad. |
I have just run the code provided above against master and it as you can see it is still an issue.
|
It seems #345 works well. |
@engwan , I tested against master, it fails. I guess the key here is each of two threads setting the value to a blank and a non-blank value. It eventually will raise |
I see the problem now. It happens when it's the same instance being modified by multiple threads. d4ca0e2 fixed the problem where different instances were modified in separate threads because the attributes were stored in a class variable. Now it's stored per instance. Yes this is still a bug, but I think it's less severe than the previous one. I think it's not so common to modify the same instance in multiple threads. |
@engwan, |
See my response on #344 (comment) - this issue is resolved if you point to the commits on master Seems there is something that still causes this. It takes alot of throughput to generate the error (attempts to reproduce on my local machine using threads pumping decrypts through have been unsuccessful). In my case, every non-threaded environment (accessing from a console, running in a standalone daemon, multi process servers) never hits an issue. But when run in a threaded environment (sidekiq) with high throughput, I get the issue hundreds of times a day. I have three models.
The code is very vanilla model lookups. The job starts with a The only thing that has helped was moving these models/jobs to a special sidekiq process with single thread concurrency (so effectively making them non-threaded environments). Just noting this here in case anyone else experiences it. |
In response to my comment above, the fix on master does fix my issue. What I didn't realize was a new version of this gem has not been released since Feb 2018, and the fix was merged into master on Jul 2018 🤯. The main concept of this particular issue (actually updating the same instance between threads) is not really a realistic case imo (but was very helpful for debugging!). |
We are observing the following sporadic errors when using this gem:
ArgumentError
withmust 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 theOpenSSL::Cipher::CipherError
with it when I was saving objects to the database):The text was updated successfully, but these errors were encountered: