From ceca26ae8780dbfe442e8ac44e88c150a4e523fe Mon Sep 17 00:00:00 2001 From: Paijo <14921983+oyi77@users.noreply.github.com> Date: Tue, 21 Apr 2026 14:49:57 +0700 Subject: [PATCH] fix(encryption): return null on decryption failure to prevent sending encrypted tokens to providers (#1462) Integrated into release/v3.7.0 --- src/lib/db/encryption.ts | 9 ++++++--- tests/unit/db-encryption.test.ts | 8 +++++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/lib/db/encryption.ts b/src/lib/db/encryption.ts index bff219c1ef..b491a09a47 100644 --- a/src/lib/db/encryption.ts +++ b/src/lib/db/encryption.ts @@ -110,14 +110,16 @@ export function decrypt(ciphertext: string | null | undefined): string | null | console.warn( "[Encryption] Found encrypted data but STORAGE_ENCRYPTION_KEY is not set. Cannot decrypt." ); - return ciphertext; + // Return null instead of encrypted ciphertext to prevent sending encrypted tokens to providers + return null; } const body = ciphertext.slice(PREFIX.length); const parts = body.split(":"); if (parts.length !== 3) { console.error("[Encryption] Malformed encrypted value"); - return ciphertext; + // Return null instead of encrypted ciphertext to prevent sending malformed encrypted tokens to providers + return null; } const [ivHex, encryptedHex, authTagHex] = parts; @@ -144,7 +146,8 @@ export function decrypt(ciphertext: string | null | undefined): string | null | } catch (err: unknown) { const message = err instanceof Error ? err.message : String(err); console.error("[Encryption] Decryption failed:", message); - return ciphertext; + // Return null instead of encrypted ciphertext to prevent sending encrypted tokens to providers + return null; } } diff --git a/tests/unit/db-encryption.test.ts b/tests/unit/db-encryption.test.ts index 97b290f241..092743358f 100644 --- a/tests/unit/db-encryption.test.ts +++ b/tests/unit/db-encryption.test.ts @@ -66,7 +66,7 @@ test("connection field helpers encrypt and decrypt all supported credential fiel assert.deepEqual(decrypted, connection); }); -test("decrypt returns the original ciphertext when the value is malformed or the key is wrong", async () => { +test("decrypt returns null when the value is malformed or the key is wrong", async () => { process.env.STORAGE_ENCRYPTION_KEY = "task-304-secret-c"; const firstModule = await importFresh("src/lib/db/encryption.ts"); const encrypted = firstModule.encrypt("top-secret"); @@ -74,6 +74,8 @@ test("decrypt returns the original ciphertext when the value is malformed or the process.env.STORAGE_ENCRYPTION_KEY = "task-304-secret-d"; const secondModule = await importFresh("src/lib/db/encryption.ts"); - assert.equal(secondModule.decrypt(encrypted), encrypted); - assert.equal(secondModule.decrypt("enc:v1:not-valid"), "enc:v1:not-valid"); + // When decryption fails with wrong key, return null (not encrypted ciphertext) + // This prevents sending encrypted tokens to APIs + assert.equal(secondModule.decrypt(encrypted), null); + assert.equal(secondModule.decrypt("enc:v1:not-valid"), null); });