fix(adapter-pg): destroy pg connections after transaction database errors to prevent response leaking - #30413
AbhilashG12 wants to merge 1 commit into
Conversation
…rors to prevent response leaking Signed-off-by: AbhilashG12 <abhilashggg15@gmail.com>
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
|
@coderabbitai review |
|
CodeRabbit chat interactions are restricted to organization members for this repository. Ask an organization member to interact with CodeRabbit, or set |
Linked issue
Fixes #30374
Summary
This fixes a critical data-corruption vulnerability where queries on a
@prisma/adapter-pgclient could receive payloads belonging to other queries after a transaction database error.Root Cause:
When a database error (e.g., duplicate key) is raised inside a transaction, the underlying TCP socket in
pggoes out of sync. Currently, when the engine triggers aROLLBACK, thePgTransaction.rollback()method callsthis.client.release()with no arguments. Inpg, this incorrectly signals that the connection is healthy, returning a corrupted socket to the pool. The very next query to check out that connection reads the leftover wire bytes, resulting in anError P2023or returning another user's data.Solution:
isPoisonedboolean flag onPgQueryable.performIOcatches a database error,isPoisonedis flipped totrue.PgTransaction.commit()andPgTransaction.rollback(), we check this flag. Iftrue, we pass an Error tothis.client.release(err).pg.Poolto sever and destroy the poisoned TCP socket rather than returning it to the idle pool.Testing performed
pg.test.tsto assertclient.release()receives anErrorobject after a failed transaction, but receivesundefinedafter a healthy transaction.pnpm --filter @prisma/adapter-pg testSkill update
n/a — internal only