Skip to content
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

Rails 4.0.1 encrypted attributes not getting saved #72

Closed
finbarr opened this issue Nov 13, 2013 · 14 comments
Closed

Rails 4.0.1 encrypted attributes not getting saved #72

finbarr opened this issue Nov 13, 2013 · 14 comments

Comments

@finbarr
Copy link

finbarr commented Nov 13, 2013

Hi,

I'm running into an issue where attributes marked as attr_encrypt{ed,or} don't get saved to the db. When writing changes to the models I can read back the encrypted and decrypted values, but the encrypted_column_changed? methods return false and calling save doesn't write anything to the database.

I'm using Postgres and Rails 4.0.1. Any ideas?

Thanks.

Finbarr

@sbfaulkner
Copy link
Member

I have not yet tested with AR 4.x ... anyone?

@mhurwi
Copy link

mhurwi commented Nov 19, 2013

I'm getting this error on Rails 3.2.11 using Mongoid. I think my implementation is correct, but I'm still learning.

Am I doing it wrong?

Here's an example of what I mean:

First, I create a new class with a field 'color' that should be encryptable.

3.2.11 @ 1.9.3 (main)>class AttrTester
3.2.11 @ 1.9.3 (main)>  include Mongoid::Document
3.2.11 @ 1.9.3 (main)>  attr_encryptor :color, key: "SECRET"
3.2.11 @ 1.9.3 (main)>  field :color, type: String
3.2.11 @ 1.9.3 (main)>end
=> #<Mongoid::Fields::Standard:0x007fd974561fd0
 @default_val=nil,
 @label=nil,
 @name="color",
 @options={:type=>String, :klass=>AttrTester}>

Then I make a new instance. Color does not save to db.

3.2.11 @ 1.9.3 (main)>tester = AttrTester.new(color: "red")
=> #<AttrTester _id: 528ba32c88f929d3d7000006, _type: nil, color: nil>

Set the color again and, yes, it can be encrypted...

3.2.11 @ 1.9.3 (main)>tester.color = "red"
=> "red"
3.2.11 @ 1.9.3 (main)>tester.encrypted_color
=> "\x9Cq\x1Ek\xF1\x0E\x8Fw/\aT\x94\x06\xDA'="

But again, the color is not saved to the db.

3.2.11 @ 1.9.3 (main)>tester.save
  MOPED: 127.0.0.1:27017 COMMAND      database=admin command={:ismaster=>1} (0.5939ms)
  MOPED: 127.0.0.1:27017 INSERT       database=saleschute_dev collection=attr_testers documents=[{"_id"=>"528ba32c88f929d3d7000006"}] flags=[] (0.1490ms)
=> true
3.2.11 @ 1.9.3 (main)>tester
=> #<AttrTester _id: 528ba32c88f929d3d7000006, _type: nil, color: nil>
3.2.11 @ 1.9.3 (main)>

@cthulhu
Copy link

cthulhu commented Nov 20, 2013

Confirming for rails 4.0.1 saving works

@sbfaulkner
Copy link
Member

@cthulhu thanks for confirming.

@finbarr are you able to reduce this to a small test case?

@mhurwi seems like a separate issue from this one, but there are a couple of other mongoid-related issues already open... maybe see if what you're describing matches them?

@josegrad
Copy link

This is getting quite fragmented, but I'm on Rails 4.0.0 and Mongoid 4.0.0, on the console I can build an object and get the encrypted value of a field. However nothing gets saved to db.

The field I want to encrypt is called words.

So on the model I use:

attr_encrypted :words, :key => "my key"
field :words, :type => String
field :encrypted_words, :type => String

On the controller:

params.require(:feedback).permit(:words, :encrypted_words) 

@josegrad
Copy link

This is how I fixed my problem by changing the way the fields are declared on the model:

field :encrypted_words, :type => String
attr_encrypted :words, :key => "mykey", :encode => true, :charset => "utf-8"

I followed the test for the mongoid adapter.

Now the record gets saved on the DB (mongodb) which contains a fields called encrypted_words. Calling .words on an object returns the correct decrypted value.

Not sure it is a feature, a documentation issue, bug. I've used attr_encrypted with AR and declaration was different. But it works now for me.

@sbfaulkner
Copy link
Member

@josegrad @mhurwi please see #51 ... this is not related to Rails 4

@arrtchiu
Copy link

I'm seeing this issue too:

class Obj < ActiveRecord::Base
  attr_encrypted :secret_stuff
end
obj = Obj.new
obj.secret_stuff = "super confidential"

obj.encrypted_secret_stuff
# => "<encrypted data>"

obj.read_attribute(:secret_stuff)
# => nil

However, if I do the following, it works correctly:

obj.send(:write_attribute, :secret_stuff, obj.encrypted_secret_stuff)
obj.read_attribute(:secret_stuff)
# => "<encrypted data>"

I've created a patch in my own branch to work around this, however, write_attribute is a private method and I think it's highly likely there is a better solution.

arrtchiu added a commit to arrtchiu/attr_encrypted that referenced this issue Feb 14, 2014
@arrtchiu
Copy link

#75 may be a better solution to this.

@fernandes
Copy link

just a point that I get in trouble using the gem today for the first time, if you are trying to crypt your password and then you forget to run the command:

be rails g migration AddEncryptedFieldsToModel encrypted_password:string encrypted_password_iv:string encrypted_password_salt:string

The crypto field won't be saved to database and its a silent, no error is shown...

hope it helps

@jgautsch
Copy link

I was having the exact same issue described in this thread. @fernandes had the fix for me. Before switching to this gem I had rolled my own encryption solution which basically used custom setters and getters, making additional fields in the database unnecessary. Because this is how I had already approached the problem, it wasn't immediately obvious to me that I needed to add fields to the db.

I think this requirement to add fields to the db should be made more obvious in the "Basic" section in the readme.

EDIT: I actually didn't do exactly what @fernandes described. I just added a field for :encrypted_#{attribute}

@fernandes
Copy link

hey @jgautsch good to hear my comment pointed the solution, adding just :encrypted_#{attribute} is ok, I added :encrypted_#{attribute}iv and :encrypted#{attribute}_salt to use:

mode: :per_attribute_iv_and_salt

So I have an iv and salt per attribute, if you would like to understand better why use this mode, check this issue: #32

@dawsonc
Copy link

dawsonc commented Jul 9, 2014

I am also having this problem. I just added attr_encrypted to my ActiveRecord model with attr_encryptor :cred_key, :key => "test_key", and even though I ran a migration to create the encrypted_cred_key field in the DB.

I can create instances of the model fine in the console, and the encryption works in the console, but when I save the record, the "encrypted_cred_key" field is NULL, and once I reload the console the cred_key attribute returns nil.

@sbfaulkner
Copy link
Member

all problems I've seen with this description come down to not naming the field correctly in the database.

by default, if your attribute is "name", the database column should be "encrypted_name"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants