Skip to content

refactor(tls): switch verification to VerifyConnection - #10478

Merged
mnencia merged 4 commits into
mainfrom
dev/10477
Apr 22, 2026
Merged

mnencia merged 4 commits into
mainfrom
dev/10477

Conversation

@sxd

@sxd sxd commented Apr 17, 2026 •

Copy link
Copy Markdown
Contributor

Go's VerifyPeerCertificate callback is skipped on resumed TLS 1.3 sessions (PSK / session tickets), while VerifyConnection runs on every completed handshake. Session resumption is not enabled anywhere in the codebase today (no ClientSessionCache is configured), so this has no observable effect, but it aligns the verification hook with the one the Go team documents as resumption-safe and satisfies the golangci-lint 2.11.4 check that flagged the combination.

Closes #10477

@sxd

sxd commented Apr 17, 2026

Copy link
Copy Markdown
Contributor Author

/test

@github-actions

Copy link
Copy Markdown
Contributor

@cnpg-bot cnpg-bot added backport-requested ◀️ This pull request should be backported to all supported releases release-1.25 release-1.28 labels Apr 17, 2026
@github-actions

Copy link
Copy Markdown
Contributor

❗ By default, the pull request is configured to backport to all release branches.

  • To stop backporting this pr, remove the label: backport-requested ◀️ or add the label 'do not backport'
  • To stop backporting this pr to a certain release branch, remove the specific branch label: release-x.y

@cnpg-bot cnpg-bot added the ok to merge 👌 This PR can be merged label Apr 17, 2026
@sxd
sxd marked this pull request as ready for review April 18, 2026 10:10
@sxd
sxd requested a review from a team April 18, 2026 10:10
@dosubot dosubot Bot added size:M This PR changes 30-99 lines, ignoring generated files. bug 🐛 Something isn't working labels Apr 18, 2026
@leonardoce leonardoce changed the title chore: add function to VerifyConnection for the TLS configuration fix: use VerifyConnection for the TLS configuration Apr 20, 2026
@leonardoce
leonardoce force-pushed the dev/10477 branch 2 times, most recently from 2c29584 to d15b111 Compare April 20, 2026 11:45
@leonardoce leonardoce changed the title fix: use VerifyConnection for the TLS configuration fix: TLS certificate validation covering session resumption Apr 20, 2026
@leonardoce

Copy link
Copy Markdown
Contributor

/test

@github-actions

Copy link
Copy Markdown
Contributor

@dosubot dosubot Bot added the lgtm This PR has been approved by a maintainer label Apr 21, 2026
@NiccoloFei
NiccoloFei force-pushed the dev/10477 branch 3 times, most recently from 6eac903 to 6a79f5b Compare April 21, 2026 14:41
@mnencia mnencia changed the title fix: TLS certificate validation covering session resumption refactor(tls): switch verification to VerifyConnection Apr 21, 2026
sxd and others added 3 commits April 22, 2026 09:46
The tls.Config{} was missing the VerifyConnection value to verify a connection
during the resume process, this could lead to skip the certificate verification
since the verification is applied only once, at the beginning and not during
the resume phase.

Closes #10477

Signed-off-by: Jonathan Gonzalez V. <[email protected]>
Add a missing length check in the VerifyConnection callback, consistent
with the existing guard in VerifyPeerCertificate, to prevent a panic
when conn.PeerCertificates is empty.

Signed-off-by: Leonardo Cecchi <[email protected]>
VerifyConnection is called unconditionally at the end of every
successful TLS handshake, including resumed sessions (TLS 1.3 session
tickets, TLS 1.2 session IDs).

VerifyPeerCertificate, on the other hand, is only invoked during full
handshakes, when the server sends a Certificate message. On session
resumption, the abbreviated handshake skips the Certificate exchange
entirely, meaning VerifyPeerCertificate is never called.

Since both callbacks performed identical certificate chain validation
via verifyCertificates, keeping VerifyPeerCertificate was redundant on
full handshakes and provided no coverage on resumed ones. Relying solely
on VerifyConnection ensures consistent validation across all connection
types.

Signed-off-by: Leonardo Cecchi <[email protected]>
@mnencia
mnencia merged commit 9309106 into main Apr 22, 2026
42 checks passed
@mnencia
mnencia deleted the dev/10477 branch April 22, 2026 08:31
cnpg-bot pushed a commit that referenced this pull request Apr 22, 2026
Go's `VerifyPeerCertificate` callback is skipped on resumed TLS 1.3
sessions (PSK / session tickets), while `VerifyConnection` runs on every
completed handshake. Session resumption is not enabled anywhere in the
codebase today (no `ClientSessionCache` is configured), so this has no
observable effect, but it aligns the verification hook with the one the
Go team documents as resumption-safe and satisfies the golangci-lint
2.11.4 check that flagged the combination.

Closes #10477

Signed-off-by: Jonathan Gonzalez V. <[email protected]>
Signed-off-by: Leonardo Cecchi <[email protected]>
Signed-off-by: Marco Nenciarini <[email protected]>
Co-authored-by: Leonardo Cecchi <[email protected]>
Co-authored-by: Marco Nenciarini <[email protected]>
(cherry picked from commit 9309106)
cnpg-bot pushed a commit that referenced this pull request Apr 22, 2026
Go's `VerifyPeerCertificate` callback is skipped on resumed TLS 1.3
sessions (PSK / session tickets), while `VerifyConnection` runs on every
completed handshake. Session resumption is not enabled anywhere in the
codebase today (no `ClientSessionCache` is configured), so this has no
observable effect, but it aligns the verification hook with the one the
Go team documents as resumption-safe and satisfies the golangci-lint
2.11.4 check that flagged the combination.

Closes #10477

Signed-off-by: Jonathan Gonzalez V. <[email protected]>
Signed-off-by: Leonardo Cecchi <[email protected]>
Signed-off-by: Marco Nenciarini <[email protected]>
Co-authored-by: Leonardo Cecchi <[email protected]>
Co-authored-by: Marco Nenciarini <[email protected]>
(cherry picked from commit 9309106)
mnencia added a commit that referenced this pull request Apr 22, 2026
Go's `VerifyPeerCertificate` callback is skipped on resumed TLS 1.3
sessions (PSK / session tickets), while `VerifyConnection` runs on every
completed handshake. Session resumption is not enabled anywhere in the
codebase today (no `ClientSessionCache` is configured), so this has no
observable effect, but it aligns the verification hook with the one the
Go team documents as resumption-safe and satisfies the golangci-lint
2.11.4 check that flagged the combination.

Closes #10477

Signed-off-by: Jonathan Gonzalez V. <[email protected]>
Signed-off-by: Leonardo Cecchi <[email protected]>
Signed-off-by: Marco Nenciarini <[email protected]>
Co-authored-by: Leonardo Cecchi <[email protected]>
Co-authored-by: Marco Nenciarini <[email protected]>
(cherry picked from commit 9309106)
sdwilsh pushed a commit to sdwilsh/ansible-playbooks that referenced this pull request May 11, 2026
##### [\`v1.29.1\`](https://github.com/cloudnative-pg/cloudnative-pg/releases/tag/v1.29.1)

**Release date:** May 8, 2026

##### Security and Supply Chain

- **`CVE-2026-44477` / `GHSA-423p-g724-fr39`: metrics exporter privilege escalation**: the metrics exporter no longer authenticates as the `postgres` superuser. It now uses a dedicated `cnpg_metrics_exporter` role with `pg_monitor` privileges only, closing a chain that let a low-privilege database user gain PostgreSQL superuser. ([`GHSA-423p-g724-fr39`](GHSA-423p-g724-fr39)) <!-- 1.29 1.28 1.25 -->

  Upgrade impact: custom monitoring queries that read user-owned tables, or use `target_databases: '*'` against databases where `PUBLIC CONNECT` has been revoked, need explicit `GRANT` statements to `cnpg_metrics_exporter`. See ["Custom query privileges and safety"](../monitoring.md#custom-query-privileges-and-safety) and ["Manually creating the metrics exporter role"](../monitoring.md#manually-creating-the-metrics-exporter-role) in the monitoring documentation.

  For replica clusters, upgrade the source primary cluster before any replica clusters that consume from it. The `cnpg_metrics_exporter` role is created on the source primary and replicates downstream; a replica cluster upgraded first will scrape against a missing role until the source primary upgrades. The manual-recovery section linked above also covers replica clusters.

- **Schema-qualified catalog references in default monitoring queries**: hardened the shipped monitoring configuration and documentation samples by qualifying every `pg_catalog` object explicitly. Unqualified references resolve through `search_path`, which a database user can manipulate to shadow built-in objects. ([#10576](cloudnative-pg/cloudnative-pg#10576)) <!-- 1.29 1.28 1.25 -->

- **Discoverable SBOM and provenance attestations**: SBOM and SLSA provenance attached to operator container images now follow the OCI 1.1 Referrers spec, so standard registry tooling and supply-chain scanners can discover them automatically. ([#10601](cloudnative-pg/cloudnative-pg#10601)) <!-- 1.29 1.28 1.25 -->

- **CVE remediation in `github.com/jackc/pgx/v5`**: bumped to v5.9.2 to pick up upstream fixes for `CVE-2026-33816` (memory-safety in `pgproto3`) and `GHSA-j88v-2chj-qfwx` (SQL injection via simple-protocol dollar-quoted string handling). ([#10437](cloudnative-pg/cloudnative-pg#10437), [#10499](cloudnative-pg/cloudnative-pg#10499))

- **CVE remediation in the Go runtime**: built with Go 1.26.3 to pick up upstream fixes in `crypto/x509`, `crypto/tls`, `net/http`, and `net` (CVE-2026-32280, CVE-2026-32281, CVE-2026-33810, CVE-2026-33814, CVE-2026-33811, CVE-2026-39825). ([#10463](cloudnative-pg/cloudnative-pg#10463), [#10647](cloudnative-pg/cloudnative-pg#10647)) <!-- 1.29 1.28 1.25 -->

- **Build pipeline hardening**: the Go 1.26.3 bump also addresses CVE-2026-42501 (`cmd/go` module-checksum validation), reducing supply-chain exposure during release builds. The affected code paths are not reachable from the running operator. ([#10647](cloudnative-pg/cloudnative-pg#10647)) <!-- 1.29 1.28 1.25 -->

##### Changes

- Switched TLS peer verification from `VerifyPeerCertificate` to `VerifyConnection`, which runs on every completed handshake (the former is skipped on resumed TLS 1.3 sessions). Session resumption is not enabled in CloudNativePG today, so this has no observable effect, but it future-proofs verification if session caching is introduced later. ([#10478](cloudnative-pg/cloudnative-pg#10478)) <!-- 1.29 1.28 1.25 -->

##### Fixes

- Fixed a failover window where the former primary kept its primary label. If it returned during failover (for example, after a transient network partition), the `-rw` service kept routing to it, replicas could reconnect, and committed writes were lost to `pg_rewind`. The old primary is now labeled `unhealthy` to isolate it from service traffic during failover. ([#10409](cloudnative-pg/cloudnative-pg#10409)) <!-- 1.29 1.28 1.25 -->

- Fixed failover not being triggered when the node hosting the primary becomes unreachable. The operator now reads the pod's `Ready` condition (flipped to `False` by the node controller when the kubelet stops reporting) instead of `ContainersReady`, which stays stale as `True` in that scenario. Combined with the spurious-failover guard ([#10445](cloudnative-pg/cloudnative-pg#10445)), failover triggers only when Kubernetes itself marks the pod not Ready. ([#10448](cloudnative-pg/cloudnative-pg#10448)) <!-- 1.29 1.28 1.25 -->

- Fixed spurious failovers caused by transient failures on the primary's HTTP status endpoint. ([#10445](cloudnative-pg/cloudnative-pg#10445)) <!-- 1.29 1.28 1.25 -->

- Fixed escaping of backslashes and control characters in PostgreSQL configuration values. Previously, such characters in parameters like `log_line_prefix` could corrupt the configuration file or be silently stripped at runtime. ([#10515](cloudnative-pg/cloudnative-pg#10515)) <!-- 1.29 1.28 1.25 -->

- Fixed `restore_command` construction to shell-quote each argument. Values such as a `destinationPath` containing whitespace (for example, `s3://my bucket/wal`) were word-split by the POSIX shell and passed to the WAL restore tool as separate arguments. ([#10518](cloudnative-pg/cloudnative-pg#10518)) <!-- 1.29 1.28 1.25 -->

- Tightened `recoveryTarget` validation in the admission webhook: `targetXID` must now be a non-negative 32-bit integer, and `targetName` must be shorter than 64 bytes and free of ASCII control characters. Malformed values are rejected at admission instead of failing later during PostgreSQL recovery. ([#10565](cloudnative-pg/cloudnative-pg#10565)) <!-- 1.29 1.28 1.25 -->

- Fixed snapshot restores failing when leftover `pgsql_tmp*` directories were present in the data directory. ([#10447](cloudnative-pg/cloudnative-pg#10447)) <!-- 1.29 1.28 1.25 -->

- Fixed a deadlock occurring when PVC storage size and resource requests are changed simultaneously. ([#10427](cloudnative-pg/cloudnative-pg#10427)) <!-- 1.29 1.28 1.25 -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport-requested ◀️ This pull request should be backported to all supported releases bug 🐛 Something isn't working lgtm This PR has been approved by a maintainer ok to merge 👌 This PR can be merged release-1.28 size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: tls.Config should use VerifyConnection

5 participants