pgJDBC now enforces the channel binding it requires
pgJDBC 42.7.12 fixes a silent downgrade from required channel binding. The failure combined an empty library result with a driver check of advertised mechanisms instead of the negotiated result.
A connection could request channelBinding=require and authenticate without channel binding. pgJDBC checked that the server advertised a channel-binding mechanism, but it did not establish that the negotiated mechanism actually used it. CVE-2026-54291 exposes the gap between requesting a security property and verifying the result of negotiation.
The July 6 PostgreSQL announcement identifies pgJDBC 42.7.12 as the security release. Its changelog dates the release June 29. The driver advisory also appeared June 29, before today's PostgreSQL-site announcement.
The affected versions are 42.7.4 through 42.7.11, and the broken guarantee concerns connections configured to require channel binding. The default prefer policy already permits fallback. Describing the issue as every SCRAM connection being broken would obscure the particular promise that the driver failed to enforce.
Unsupported certificate algorithms produced an empty binding
The announcement describes a certificate signature algorithm for which the client cannot derive a tls-server-end-point channel-binding hash. It names Ed25519, Ed448 and post-quantum algorithms as examples. An attacker able to intercept the TLS connection can present such a certificate to trigger the vulnerable path.
The bundled com.ongres.scram:scram-client, versions 3.1 or 3.2, returns an empty byte array when it cannot derive the hash. That behavior is the separate library issue GHSA-p9jg-fcr6-3mhf, as described in the driver advisory. An empty value propagates through a path where the requested security property requires a usable binding.
That library behavior is only part of the explanation. pgJDBC's ScramAuthenticator also fails to enforce the caller's requirement at the relevant decision points. It checks whether a -PLUS mechanism was advertised but does not reject the empty binding. It also fails to verify that the mechanism selected through negotiation uses channel binding.
The resulting authentication can use plain SCRAM-SHA-256 instead of SCRAM-SHA-256-PLUS. The connection has therefore lost the man-in-the-middle protection that the required channel-binding setting was meant to guarantee. Authentication succeeds under a weaker condition than the application requested.
Advertisement and selection answer different questions
A server advertising a mechanism establishes that it claims to offer that option. It does not establish that the option was selected or that the client supplied the material needed to use it. The vulnerable driver treated the advertisement as sufficient evidence for a requirement that applied to the completed authentication.
The advisory explicitly says the driver could still downgrade even with a fixed scram-client, because pgJDBC itself lacked the final enforcement. That makes a dependency-only account incomplete. The driver owns the meaning of its connection policy and must reject outcomes that violate it, regardless of how a supporting library behaves.
Version 42.7.12 adds two checks in the driver's own code. Under channelBinding=require, failure to extract channel-binding data from the server certificate fails the connection. The error identifies the certificate signature algorithm. After negotiation, the driver also requires a selected -PLUS mechanism whenever channel binding is mandatory.
Those checks address different stages. The first rejects missing input needed for the binding. The second rejects a negotiation result that lacks the required property. Together they make a successful connection evidence that the driver has enforced its requested channel-binding policy across both decisions.
I value PostgreSQL partly because its behavior is usually documented precisely enough to reason about. A setting named require needs that same precision in a driver. It should turn an unsupported authentication path into an explicit connection failure, since an application cannot act on a protection that disappeared silently.
The narrower affected scope is still important
The announcement says releases before 42.7.4 are unaffected because they do not support channel binding. That statement describes vulnerability scope, not a recommendation to deploy an older driver. A release without the capability cannot provide the required guarantee merely because it predates this defect.
Connections using prefer are also outside the stated policy violation because fallback is documented behavior for that setting. The distinction is about the security contract. A client permitting fallback and a client prohibiting it should not silently end up with the same behavior when the stronger mechanism cannot be used.
The advisory lists allow and disable among policies where falling back to plain SCRAM is documented. It reserves the affected classification for connections explicitly requiring channel binding. This is why inventory of connection settings matters alongside inventory of driver versions when determining which applications relied on the broken guarantee.
The attack also has a stated prerequisite. An attacker must be able to intercept the TLS connection and cause the problematic certificate path. The source does not describe an unauthenticated SQL query that changes another client's negotiation. The failure occurs during connection authentication under the network conditions identified by the advisory.
Certificate verification supplies an independent defense
The driver advisory says no pgJDBC setting restores channel-binding enforcement in an affected release. Upgrading is the fix. That is more specific than suggesting a different combination of channel-binding settings can repair the vulnerable enforcement code.
For installations unable to upgrade immediately, the advisory recommends verifying the server certificate at the TLS layer. It specifies sslmode=verify-full and a truststore containing only the server's CA. This defense prevents the attacker from substituting the certificate needed to trigger the downgrade. It is independent of channel binding.
That independence should remain explicit. Certificate verification does not make the vulnerable driver perform its missing checks. It blocks the same attacker through a different verification step. Applications that rely on channelBinding=require in place of certificate verification have no equivalent workaround according to the advisory.
My preference is to keep those guarantees separately understood. Server-certificate verification and required channel binding each impose a condition on connection establishment. A failure in one does not justify assuming that the other was configured, and a workaround based on the other must preserve the truststore restriction described by the project.
The substantive change in 42.7.12 is that the driver's own policy now governs the actual authentication outcome. An unusable certificate binding produces failure, and a negotiated mechanism without binding cannot satisfy require. Applications depending on that setting need the repaired driver to obtain the guarantee their configuration already expressed.