47ng / prisma-field-encryption

Transparent field-level encryption at rest for Prisma
https://github.com/franky47/prisma-field-encryption-sandbox
MIT License
223 stars 27 forks source link

Plaintext values with mode=strict do not throw errors #106

Open richmirza opened 2 months ago

richmirza commented 2 months ago

Given this schema:

model EncryptionTest {
  id                 String                 @id
  data               String? /// @encrypted?mode=strict
}

and this test:

    await prisma.$queryRawUnsafe(
      `INSERT INTO encryption_test (id, data) VALUES ('id', 'plaintextdata')`,
    );

    const encryptionTest = await prisma.encryptionTest.findFirst({
      where: { id: 'id' },
    });

I would expect this test case to throw an exception. Is my understanding incorrect?

It's a simple fix if indeed it's unexpected behaviour. https://github.com/47ng/prisma-field-encryption/blob/next/src/encryption.ts#L179 is currently

        if (!cloakedStringRegex.test(cipherText)) {
          return
        }

so if a field is in the database as plaintext (which doesn't match the cloakedStringRegex) then strict mode is not taken into account. Proposed fix:

        if (!cloakedStringRegex.test(cipherText)) {
          if (fieldConfig.strictDecryption) {
            throw new Error('Value is not encrypted and mode=strict')
          }
          return
        }
franky47 commented 2 months ago

That is indeed a missing branch, could you open a PR with your proposed fix please? Thanks!

Note: please add an error for it in this file, with some context (model/field where the cleartext data was found) to help users debug their application.