From 4c32f153390ca12f3bff7e04bb57737c352b6102 Mon Sep 17 00:00:00 2001 From: robobun Date: Wed, 11 Feb 2026 22:45:47 -0800 Subject: [PATCH] fix(sql): use constant-time comparison for SCRAM server signature (#26937) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Replace `bun.strings.eqlLong` with BoringSSL's `CRYPTO_memcmp` for SCRAM-SHA-256 server signature verification in the PostgreSQL client - The previous comparison (`eqlLong`) returned early on the first mismatching byte, potentially leaking information about the expected server signature via timing side-channel - `CRYPTO_memcmp` is already used elsewhere in the codebase for constant-time comparisons (CSRF tokens, `crypto.timingSafeEqual`, KeyObject comparison) ## Test plan - [x] `bun bd` compiles successfully - [ ] Existing SCRAM-SHA-256 integration tests in `test/js/sql/sql.test.ts` pass (require Docker/PostgreSQL) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Bot Co-authored-by: Claude --- src/sql/postgres/PostgresSQLConnection.zig | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/sql/postgres/PostgresSQLConnection.zig b/src/sql/postgres/PostgresSQLConnection.zig index 0cdbf71600..3e7d3e7745 100644 --- a/src/sql/postgres/PostgresSQLConnection.zig +++ b/src/sql/postgres/PostgresSQLConnection.zig @@ -1626,7 +1626,10 @@ pub fn on(this: *PostgresSQLConnection, comptime MessageType: @Type(.enum_litera // This will usually start with "v=" const comparison_signature = final.data.slice(); - if (comparison_signature.len < 2 or !bun.strings.eqlLong(server_signature, comparison_signature[2..], true)) { + if (comparison_signature.len < 2 or + server_signature.len != comparison_signature.len - 2 or + BoringSSL.c.CRYPTO_memcmp(server_signature.ptr, comparison_signature[2..].ptr, server_signature.len) != 0) + { debug("SASLFinal - SASL Server signature mismatch\nExpected: {s}\nActual: {s}", .{ server_signature, comparison_signature[2..] }); this.fail("The server did not return the correct signature", error.SASL_SIGNATURE_MISMATCH); } else {