Safeguard
Vulnerability Analysis•

CVE-2025-2291: High Expired Password Bypass in PgBouncer

CVE-2025-2291 lets PgBouncer accept expired Postgres passwords because auth_query ignored VALID UNTIL. Update to 1.24.1 or fix your auth_query.

Safeguard Security Team
4 min read

CVE-2025-2291 is a high severity (CVSS 8.1) flaw in PgBouncer where auth_query ignored a Postgres password's VALID UNTIL date, so an expired password could still log in. It is fixed in PgBouncer 1.24.1. Custom auth_query functions must also be updated by hand.

What's affected

The PgBouncer changelog for 1.24.1, dated 16 April 2025, calls this release "CVE-2025-2291 VALID UNTIL yesterday". It says PgBouncer did not take the VALID UNTIL of a user password into account when it queried for password hashes with auth_query. When PgBouncer is used as a transparent proxy in front of Postgres, passwords that had already expired could be accepted.

The record also lists Debian Linux, since Debian published a long term support announcement for the fix. The changelog gives two ways to fix it: update to PgBouncer 1.24.1, or, on an earlier release, change the config to use the new default auth_query. If you use a custom auth_query, you must update it yourself.

How to check if you're exposed

Check the running version and your auth_query setting:

pgbouncer --version
grep -n auth_query /etc/pgbouncer/pgbouncer.ini

In the admin console you can also run SHOW VERSION. If auth_query is set, read the query. If it selects a password hash from pg_shadow or a function without comparing the expiry date, it needs the change described in the changelog. If you do not use auth_query, for instance because you use a userlist file, this specific path does not apply.

On Debian based systems, check your package version against the distribution's security notice.

Reading an inventory is faster than checking host by host. Safeguard has a free in-browser dependency scan at gold.safeguard.sh/scan and a Gold directory you can search for any CVE. Reachability analysis helps you see whether a vulnerable component is actually used in your code, so you can fix the exposed ones first.

What to do now

  1. Upgrade PgBouncer to 1.24.1 or later, or apply your distribution's patched package.
  2. If you run a custom auth_query, change it to account for VALID UNTIL, following the examples in the updated PgBouncer documentation.
  3. If you cannot upgrade yet, switch to the new default auth_query on your current release, as the changelog allows.
  4. Audit Postgres roles that have an expired VALID UNTIL and confirm they cannot log in through the pooler.
  5. Check that the PgBouncer admin console and ports are not reachable from untrusted networks.

Why it matters

CWE-324 is the use of a key past its expiration date. Postgres enforces a password's VALID UNTIL when it checks credentials itself. PgBouncer, sitting in front, fetched the hash through its own query and did not apply that date, so the expiry rule that DBAs relied on silently stopped working.

This is a good example of a control that fails at a seam between two components. The database was correct. The proxy ran a copy of the check without one condition. Teams that rotate access by letting passwords expire, for contractors or temporary accounts, are the ones who would have counted on this. The record's attack complexity is high and the KEV flag is false, so no active exploitation is claimed.

Try it yourself

Click through it at your own pace, or open it full screen.

Quick check

Do I need to upgrade if I use a custom auth_query?

Updating PgBouncer is not enough on its own. The changelog says to update a custom auth_query to account for VALID UNTIL.

Is there a fix without upgrading?

Yes. On a previous release you can change your config to use the new default auth_query, per the changelog.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.