michelp / pgsodium

Modern cryptography for PostgreSQL using libsodium.
Other
555 stars 32 forks source link

Updated value in secret column does not get encrypted #76

Closed timreibe closed 1 year ago

timreibe commented 1 year ago

Hi everyone,

following my setup in #73, I have a secret value stored in secret_column, which is encrypted at insert. Now, when updating the value, I expect it to be encrypted again, but it won't. Edit: It is stored as clear text.

Is this behavior expected, or is this, again, an issue I have with supabase?

Kind regards Tim

edit: I added the database setup scripts in my comment below

timreibe commented 1 year ago

As a workaround, I created an update trigger, which sets a new key_id and nonce and encryptes the secret value again with both.

SECURITY LABEL FOR pgsodium ON COLUMN table_name1.secret_column IS 'ENCRYPT WITH KEY COLUMN key_id NONCE nonce ASSOCIATED owner';

CREATE VIEW decrypted_table_name1 AS SELECT id, convert_from(pgsodium.crypto_aead_det_decrypt( pg_catalog.decode(secret_column, 'base64'), pg_catalog.convert_to(owner::text, 'utf8'), key_id::uuid, nonce ), 'utf8') AS secret_column FROM table_name1;


- **Create Trigger**
```pgsql
create or replace function set_table_name1_pgsodium_values()
    returns trigger
as
$$
begin

    new.key_id := (pgsodium.create_key()).id;
    new.nonce :=  pgsodium.crypto_aead_det_noncegen();

    new.secret_column := pg_catalog.encode(
        pgsodium.crypto_aead_det_encrypt(
            pg_catalog.convert_to(new.secret_column, 'utf8'),
            pg_catalog.convert_to(old.owner::text, 'utf8'),
            new.key_id,
            new.nonce
        ),
    'base64');
    return new;
end ;
$$
    language plpgsql;

create trigger trg_set_table_name1_pgsodium_values
    before update
    on table_name1
    for each row
execute procedure set_table_name1_pgsodium_values();
ioguix commented 1 year ago

Now, when updating the value, I expect it to be encrypted again, but it won't.

What do you mean "it won't"? Does the updated data is written in clear text/bytea?

Here is a similar Q+A if it could help: https://github.com/michelp/pgsodium/issues/61#issuecomment-1374003149

timreibe commented 1 year ago

Hi @ioguix, the updated data is written in clear text and not encrypted.

Thanks for the Q&A, so to trigger the encryption correctly, I have to update the value via the decrypted view, correct? Is there any advantage/disadvantage over having a trigger that encrypts the value on an update call?

Another thing is: I'd like to update the key_id and nonce on every change of the secret column, can I somehow integrate this in an alternative way than using an update trigger?

ioguix commented 1 year ago

Hi,

I have to update the value via the decrypted view, correct?

Not necessarily if you don't build the new value with the old one.

I have no idea why your trigger does not fire:

76=# select secret_column, decrypted_secret_column from decrypted_table_name1 ;
                  secret_column                   | decrypted_secret_column 
--------------------------------------------------+-------------------------
 ke6mSPa146SZZFdMa+8bJzN8bHjg/sC45oGEUk3UzNRsX21/ | chut
(1 row)

76=# update table_name1 set secret_column = 'chuuuuuut';
UPDATE 1
76=# select secret_column, decrypted_secret_column from decrypted_table_name1 ;
                      secret_column                       | decrypted_secret_column 
----------------------------------------------------------+-------------------------
 9ubE1JtNuXWxtslVDdzv68vFKUaiu7bponbkMaIcWmRujdv+mSZjD5g= | chuuuuuut
(1 row)

I don't understand either why you create the decrypted_table_name1 view yourself as pgsodium is supposed to build it for you.

timreibe commented 1 year ago

That the decrypted view is not generated dynamically seems to be related with my supabase setup again. Some others had the same issue: https://github.com/supabase/supabase/issues/11209. This might be an issue with the supabase version my project is built with. On a new project, pgsodium just works flawlessly - also the value update! Now I have to figure out how I can upgrade my project.

Thank you @ioguix