Package: release.debian.org
Severity: normal
Tags: trixie
X-Debbugs-Cc: [email protected]
Control: affects -1 + src:pgbouncer
User: [email protected]
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 <[email protected]>  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 <[email protected]>
+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")
++
++
[email protected]("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 via email to