Bug#1124080: trixie-pu: package pgbouncer/1.24.1-1+deb13u1
Package: release.debian.org
Severity: normal
Tags: trixie
X-Debbugs-Cc: pgbouncer@packages.debian.org
Control: affects -1 + src:pgbouncer
User: release.debian.org@packages.debian.org
Usertags: pu
[ Reason ]
security update.
[ Impact ]
security according to CVE description.
[ Tests ]
Build-time tests has run locally.
Additional tests (autopkgtest, etc) has been run via debusine upload:
https://debusine.debian.net/debian/developers/work-request/296751/
[ Risks ]
The update includes one fix for a pre-auth problem and the package
already includes authentication tests, so hopefulyl the risk of
regressions are low.
[ Checklist ]
[x] *all* changes are documented in the d/changelog
[x] I reviewed all changes and I approve them
[x] attach debdiff against the package in (old)stable
[x] the issue is verified as fixed in unstable
[ Changes ]
Added a patch to debian/patches that is a commit backported from
upstream.
All backporting changes has been described at the end of the patch
header ending in `//ah`.
[ Other info ]
The current git branches exists (for both bookworm and trixie) at:
https://salsa.debian.org/ah/pgbouncer/-/commits/bookworm
https://salsa.debian.org/ah/pgbouncer/-/commits/trixie
I'll tag and push to official debian packaging repo once I have the go ahead
to upload.
A bug report similar to this one, for bookworm update, was filed as:
https://bugs.debian.org/1124079
Regards,
Andreas Henriksson
on behalf of the LTS Security Team.
diff -Nru pgbouncer-1.24.1/debian/changelog pgbouncer-1.24.1/debian/changelog
--- pgbouncer-1.24.1/debian/changelog 2025-04-17 10:21:09.000000000 +0200
+++ pgbouncer-1.24.1/debian/changelog 2025-12-20 13:52:56.000000000 +0100
@@ -1,3 +1,14 @@
+pgbouncer (1.24.1-1+deb13u1) trixie; urgency=medium
+
+ * Non-maintainer upload by the Debian LTS Security Team.
+ * CVE-2025-12819: execute arbitrary SQL during authentication.
+ Untrusted search path in auth_query connection handler in PgBouncer
+ before 1.25.1 allows an unauthenticated attacker to execute arbitrary
+ SQL during authentication via a malicious search_path parameter in the
+ StartupMessage.
+
+ -- Andreas Henriksson <andreas@fatal.se> Sat, 20 Dec 2025 13:52:56 +0100
+
pgbouncer (1.24.1-1) unstable; urgency=medium
[ Christoph Berg ]
diff -Nru pgbouncer-1.24.1/debian/patches/CVE-2025-12819.patch pgbouncer-1.24.1/debian/patches/CVE-2025-12819.patch
--- pgbouncer-1.24.1/debian/patches/CVE-2025-12819.patch 1970-01-01 01:00:00.000000000 +0100
+++ pgbouncer-1.24.1/debian/patches/CVE-2025-12819.patch 2025-12-20 13:51:33.000000000 +0100
@@ -0,0 +1,115 @@
+From 85acffac5ddf56657706812f600c5f7f477abbab Mon Sep 17 00:00:00 2001
+From: Jelte Fennema-Nio <postgres@jeltef.nl>
+Date: Wed, 5 Nov 2025 22:59:06 +0100
+Subject: [PATCH] Harden auth_query connection setup (fixes CVE-2025-12819)
+
+We were sending `SET` commands based on an unauthenticated
+StartupMessage over the connection used to run an `auth_query` on the
+Postgres server. In default configurations this doesn't have any clear
+security implications, because the only settings that an attacker can
+send are the `DateStyle`, `client_encoding`, `TimeZone`,
+`standard_conforming_strings`, `application_name` and `IntervalStyle`.
+For the default `auth_query` those shouldn't matter.
+
+For users that configured some special security sensitive GUC in
+`track_extra_parameters` like `search_path` this does pose a security
+problem though.
+---
+ src/objects.c | 12 ++++++++--
+ test/test_auth.py | 58 +++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 68 insertions(+), 2 deletions(-)
+
+
+fuzz fixed in test_auth.py, offsets updated. //ah
+
+diff --git a/src/objects.c b/src/objects.c
+index 5309eeae53a2..f922f57d5b3f 100644
+--- a/src/objects.c
++++ b/src/objects.c
+@@ -938,8 +938,16 @@ bool find_server(PgSocket *client)
+ }
+ Assert(!server || server->state == SV_IDLE);
+
+- /* send var changes */
+- if (server) {
++ /*
++ * Send var changes. However, Don't send SET commands over a connection
++ * that runs the auth_query query. Since the user is not authenticated,
++ * it might have security implications if a susceptible GUC is set in
++ * track_extra_parameters (e.g. search_path). In general, it also just
++ * isn't necessary, to do so for the auth_query. Connections for the
++ * auth_query should be isolated connections from the actual
++ * connections, e.g. they also use a completely different user.
++ */
++ if (server && !sending_auth_query(client)) {
+ res = varcache_apply(server, client, &varchange);
+ if (!res) {
+ disconnect_server(server, true, "var change failed");
+diff --git a/test/test_auth.py b/test/test_auth.py
+index c09427eb2edb..92b67645560c 100644
+--- a/test/test_auth.py
++++ b/test/test_auth.py
+@@ -1111,3 +1111,63 @@ def test_auth_user_at_db_level_with_same_forced_user(bouncer):
+ with bouncer.conn(dbname="p3", user="postgres", password="asdasd") as cn:
+ with cn.cursor() as cur:
+ cur.execute("select 1")
++
++
++@pytest.mark.skipif("WINDOWS", reason="Windows does not have SIGHUP")
++def test_auth_query_no_set_commands(bouncer, pg):
++ """
++ Test that SET commands from client variables are not sent over the
++ auth_query connection. This prevents unauthenticated clients from
++ potentially affecting the auth_query execution via track_extra_parameters.
++ """
++ # Create a custom auth query that will fail if search_path is set incorrectly
++ # We'll use a function that checks current_setting('search_path')
++ pg.sql(
++ """
++ CREATE OR REPLACE FUNCTION auth_check_search_path(username TEXT)
++ RETURNS TABLE(usename name, passwd text) AS $$
++ BEGIN
++ -- This auth query will fail if search_path contains 'malicious_schema'
++ IF current_setting('search_path') LIKE '%malicious_schema%' THEN
++ RAISE EXCEPTION 'malicious search_path detected in auth query';
++ END IF;
++ RETURN QUERY SELECT u.usename, u.passwd FROM pg_shadow u WHERE u.usename = username;
++ END;
++ $$ LANGUAGE plpgsql SECURITY DEFINER;
++ """
++ )
++
++ config = f"""
++ [databases]
++ postgres = host={bouncer.pg.host} port={bouncer.pg.port} auth_query='SELECT * FROM auth_check_search_path($1)'
++ [pgbouncer]
++ auth_query = SELECT * FROM auth_check_search_path($1)
++ auth_user = pswcheck
++ stats_users = stats
++ listen_addr = {bouncer.host}
++ admin_users = pgbouncer
++ auth_type = md5
++ auth_file = {bouncer.auth_path}
++ listen_port = {bouncer.port}
++ logfile = {bouncer.log_path}
++ auth_dbname = postgres
++ track_extra_parameters = search_path
++ """
++
++ try:
++ with bouncer.run_with_config(config):
++ # Connect with a malicious search_path in the startup parameters
++ # With the fix, this should succeed because SET commands are not sent
++ # over the auth_query connection
++ # Without the fix, this would cause the auth query to fail
++ bouncer.sql(
++ query="SELECT 1",
++ user="stats",
++ password="stats",
++ dbname="postgres",
++ options="-c search_path=malicious_schema,public",
++ )
++ finally:
++ pg.sql("DROP FUNCTION IF EXISTS auth_check_search_path(TEXT)")
++
++
diff -Nru pgbouncer-1.24.1/debian/patches/series pgbouncer-1.24.1/debian/patches/series
--- pgbouncer-1.24.1/debian/patches/series 2025-04-17 10:20:32.000000000 +0200
+++ pgbouncer-1.24.1/debian/patches/series 2025-12-20 13:45:25.000000000 +0100
@@ -1 +1,2 @@
debian-config
+CVE-2025-12819.patch
Reply to: