November 11, 2021·4 min read·engineeringpostgresqlsecurityreplication

PostgreSQL 14.1 rejects cleartext left across an encryption handshake

November's security fixes reject data that could cross the transition into an encrypted session. The same release adds a WAL record that makes standby-first update order relevant.

Certificate verification cannot protect bytes that an implementation mistakenly accepts from outside the encrypted session. PostgreSQL's November update fixes that transition on both sides of a connection. The server and libpq now reject extraneous data after an SSL or GSS encryption handshake, preventing injected cleartext from being interpreted as protected session traffic.

The November 11 announcement covers 14.1, 13.5, 12.9, 11.14, 10.19 and 9.6.24. It identifies server-side CVE-2021-23214 and client-side CVE-2021-23222. Both affect the listed supported branches, while the project notes that it does not normally test unsupported versions.

I value explicit database security controls because they give access decisions a place to be inspected. These flaws show why the implementation of a connection transition also belongs in that assessment. A valid certificate and an encrypted channel do not establish that every byte reaching the SQL protocol actually passed through that channel.

The server accepted an injected prefix

The 14.1 release notes describe an attacker able to inject data into the TCP connection. Cleartext could be placed at the start of a session that the application considered encryption-protected. On the server, that could become fabricated SQL commands.

The authentication configuration limits the reported exploit. The server must not demand authentication data that prevents the injected commands from proceeding. Specifically, the announcement identifies trust authentication with a clientcert requirement, or cert authentication.

Those configurations are not equivalent to having no identity check. They can rely on the certificate and encrypted connection to establish the client's identity. The defect allows data outside the intended encrypted traffic to benefit from the resulting session state.

That is why describing the issue only as weak authentication would miss its mechanism. The handshake can complete with certificate verification while the implementation retains extra bytes from the wrong context. Rejecting the extraneous data enforces the transition between the unencrypted startup and protected session.

Jacob Champion reported both vulnerabilities. Tom Lane receives credit for the corresponding fixes in the release notes. The server correction and libpq correction apply to separate components, so updating a database server does not by itself replace every client library connecting to it.

A client can also accept fabricated responses

CVE-2021-23222 concerns the other direction. An attacker can inject false responses to the client's first few queries. The advisory states that this remains possible despite SSL certificate verification and encryption.

The disclosure also describes a more conditional route to extracting a password or other confidential data transmitted early in a session. That requires a way to make the intended server expose the data to the attacker. A server vulnerable to CVE-2021-23214 supplies one known implementation with that property.

The conditions matter. The vulnerable server still needs the trust-plus-client-certificate or cert configuration. To disclose a password, the client has to possess a password, which the announcement calls atypical for the affected authentication setup. The attacker additionally needs another way to retrieve the data, such as a valid unprivileged server login.

A general claim that every certificate-authenticated client leaks a password would therefore be inaccurate. The advisory establishes false-response injection and then separately explains the extra conditions for confidential-data extraction. Keeping those statements separate preserves the actual exposure description.

The operational consequence is that client-library inventory belongs with server updating. A service can keep using an older libpq after its database receives new binaries. The two advisories identify which side needs which correction.

Physical replication adds an update-order requirement

The release also fixes recovery after a primary crashes with an incomplete WAL record at a segment boundary. The primary may already have shipped a segment ending with the first part of that record. A standby can therefore retain those bytes before the primary finishes writing the rest.

Previously, crash recovery could back up to the beginning of the unfinished record and overwrite WAL. That is unsafe when the standby already holds the earlier segment. The standby then encounters an inconsistent next segment and cannot recover without intervention.

The fix avoids backing up across the segment boundary. It writes a new kind of WAL record at the start of the next segment to tell readers that the incomplete record will never be completed and must be ignored. That explanation gives the standby an unambiguous interpretation of the retained partial record.

The new record type makes update order relevant. PostgreSQL recommends updating standbys before the primary so they can understand the record if the primary crashes. This requirement follows from recovery compatibility, independently of the encryption fixes.

I find that explanation more useful than an unexplained sequencing rule. The updated primary can emit a record the standby needs to interpret. Having the receiving software ready first preserves the intended recovery path during the update.

Index repairs remain part of the release

Several additional fixes concern indexes that may already be incorrect. Parallel VACUUM could skip small indexes when a table also had at least two indexes above the parallel-scan size cutoff. The skipped indexes could retain references to removed heap entries and later return rows they should not.

Autovacuum does not use parallel vacuuming and is not affected by that case. The release recommends reindexing manually vacuumed tables with the relevant mix of index sizes. That qualification connects the repair to a specific maintenance history.

Concurrent index construction has separate fixes. One accounts for PREPARE TRANSACTION operations still in progress when CREATE INDEX CONCURRENTLY checks prepared transactions. Another addresses a race that can omit new-row index entries during concurrent builds or rebuilds.

The notes recommend rebuilding possibly affected indexes after updating. They also state that a 14.x database needs no dump and restore for 14.1. Those statements describe different parts of the update, with new binaries correcting execution and reindexing addressing retained object state.

November also closes the 9.6 maintenance branch with its final release, 9.6.24. An installation on that branch receives these fixes but has no continuing supported maintenance path within 9.6. Its next major-version decision remains separate from applying this final update.