diff --git a/src/server/routes/index.ts b/src/server/routes/index.ts index 46ffba0f..3c847fc7 100644 --- a/src/server/routes/index.ts +++ b/src/server/routes/index.ts @@ -32,9 +32,24 @@ export default async (fastify: FastifyInstance) => { const encryptedHeader = request.headers['x-connection-encrypted']?.toString() if (encryptedHeader) { try { - request.headers.pg = CryptoJS.AES.decrypt(encryptedHeader, CRYPTO_KEY) + const decrypted = CryptoJS.AES.decrypt(encryptedHeader, CRYPTO_KEY) .toString(CryptoJS.enc.Utf8) .trim() + let resolved = decrypted + if (PG_CONNECTION) { + try { + const decryptedUrl = new URL(decrypted) + if (decryptedUrl.hostname === 'db') { + const configuredUrl = new URL(PG_CONNECTION) + decryptedUrl.hostname = configuredUrl.hostname + decryptedUrl.port = configuredUrl.port + } + resolved = decryptedUrl.toString() + } catch { + // malformed URL — leave as-is, caught by validation below + } + } + request.headers.pg = resolved } catch (e: any) { request.log.warn({ message: 'failed to parse encrypted connstring', diff --git a/test/server/ssl.ts b/test/server/ssl.ts index 5b6cc83b..1cac655c 100644 --- a/test/server/ssl.ts +++ b/test/server/ssl.ts @@ -126,3 +126,24 @@ test('query with missing host connection string encrypted connection string', as } `) }) + +test('query with encrypted connection string using internal "db" host respects PG_META_DB_PORT', async () => { + const res = await app.inject({ + method: 'POST', + path: '/query', + headers: { + 'x-connection-encrypted': CryptoJS.AES.encrypt( + 'postgresql://postgres:postgres@db:5432/postgres', + CRYPTO_KEY + ).toString(), + }, + payload: { query: 'select 1;' }, + }) + expect(res.json()).toMatchInlineSnapshot(` + [ + { + "?column?": 1, + }, + ] + `) +})