fix(deps): update module github.com/cloudnative-pg/cloudnative-pg to v1.29.1 [security]#902
Open
renovate[bot] wants to merge 1 commit into
Conversation
…v1.29.1 [security] | datasource | package | from | to | | ---------- | ---------------------------------------- | ------- | ------- | | go | github.com/cloudnative-pg/cloudnative-pg | v1.29.0 | v1.29.1 | Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Contributor
Author
ℹ️ Artifact update noticeFile name: go.modIn order to perform the update(s) described in the table above, Renovate ran the
Details:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
v1.29.0→v1.29.1Warning
Some dependencies could not be looked up. Check the Dependency Dashboard for more information.
CloudNativePG's metrics exporter allows privilege escalation to PostgreSQL superuser and OS RCE
CVE-2026-44477 / GHSA-423p-g724-fr39
More information
Details
Impact
The CloudNativePG metrics exporter opens its PostgreSQL connection as the
postgressuperuser via the pod-local Unix socket, then demotes the session withSET ROLE pg_monitor.SET ROLEchanges onlycurrent_user;session_userremainspostgres. That residual superuser identity is the foothold for the rest of the chain.Any SQL expression evaluated inside the scrape session can invoke
RESET ROLEto recover real superuser privileges, then useCOPY ... TO PROGRAMto spawn an OS-level subprocess as thepostgresuser inside the primary pod. TheREAD ONLYtransaction flag does not block this; it gates writes to database state, not external processes.Two exploitation paths follow from this root cause.
Path 1: custom metric queries with unqualified identifiers (all supported releases)
A database user who owns a schema on the
search_pathof any scraped database can plant a shadow object whose name matches an unqualified identifier in a custom metric query. When the exporter next evaluates that query, the shadow expression executes inside thesession_user = postgresscrape session, giving the attacker PostgreSQL superuser privileges and OS command execution inside the primary pod within one scrape interval (≤30 s). Exploitability requires a custom metric query that contains an unqualified relation or function reference.Although
search_pathshadowing of unqualified identifiers is the most direct case, the underlying bug is that any expression evaluated inside the scrape session is a superuser code path. Other exploitable shapes include user-defined functions, operators or casts resolved during the scrape, joins or subqueries against user-owned tables and views, and index expressions or RLS policies on read-touched objects.Path 2: stock
default-monitoring.yaml(all supported releases, no custom metrics required)The
pg_extensionsmetric shipped indefault-monitoring.yamlused an unqualifiedcurrent_database()call and ran against every user database (target_databases: '*'). Any non-superuser who owns a user database (including the defaultapprole created bybootstrap.initdb) could shadowcurrent_database()and trigger the full escalation chain against a stock CNPG deployment on the first scrape after the shadow was planted.Combined impact
The chain yields privilege escalation from a low-privileged database role (e.g. the default
approle) to PostgreSQL superuser, plus arbitrary OS command execution as thepostgresuser inside the primary pod, all within one scrape interval. A web application SQL injection vulnerability in an app backed by a CNPG cluster is therefore sufficient to pivot to database-pod RCE.Who is impacted
Patches
Three separate patches address the vulnerability.
Patch 1: PR #10576 "schema-qualify catalog references in default monitoring queries and documentation samples"
Schema-qualifies all unqualified
pg_catalogfunction and view references in the shippeddefault-monitoring.yamland in documentation examples. This closes Path 2 in operator-shipped configuration and removes the unqualified-identifier attack surface from all operator-shipped metric queries. Operators who clone or copydefault-monitoring.yamlinto custom monitoringConfigMaps, or have copy-pasted unqualified queries elsewhere, must re-qualify those queries themselves.Backported to all currently supported releases:
Patch 2: "dedicated
cnpg_metrics_exporterrole withpg_ident.confpeer mapping"Introduces a dedicated
cnpg_metrics_exporterPostgreSQL role (grantedpg_monitor, no superuser privileges) and maps it inpg_ident.confvia peer authentication on the local Unix socket, following the same pattern already used forcnpg_pooler_pgbouncer. The metrics exporter connects as this role instead ofpostgres, sosession_useris never a superuser andRESET ROLEhas no escalation effect. This eliminates the root cause entirely.Demoting the session at the SQL level (via
SET SESSION AUTHORIZATION pg_monitor) is not sufficient: the privilege check forSET SESSION AUTHORIZATIONis whether the authenticated user is a superuser, not the currentsession_user. With the connection still authenticated aspostgres, any SQL in the session can runRESET SESSION AUTHORIZATIONand recover the original superuser identity. This is the same recovery primitive asRESET ROLE, one layer up. Only changing the authenticated user closes the loop.With this change in place, the original chain breaks at every step:
RESET ROLEandRESET SESSION AUTHORIZATIONcannot recover superuser, andCOPY ... TO PROGRAMrequires a privilegepg_monitordoes not grant. As defense in depth, the monitoring transaction also prependspg_catalogto the connection'ssearch_path, so unqualified catalog identifiers cannot resolve to user-planted shadow objects.This patch changes the connection identity but not how queries are evaluated. Custom metric queries within
pg_monitor's scope (catalog reads,pg_stat_*views, settings) continue to work without modification. Queries that previously relied on superuser-level access (reading user-owned tables not granted tocnpg_metrics_exporter, or superuser-only catalogs such aspg_authidorpg_subscription) will fail and need explicitGRANTstatements tocnpg_metrics_exporter.The role is created and maintained with
PASSWORD NULL; any password set out-of-band is cleared on the next reconcile, so the role cannot be authenticated by password regardless of operator pre-creation.For replica clusters, upgrade the source primary cluster before any replica clusters that consume from it. The
cnpg_metrics_exporterrole 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 or the role is created manually (see the monitoring documentation).The patch will be backported to all currently supported releases:
Workarounds
If upgrading immediately is not possible:
Schema-qualify all identifiers in custom metric queries. Use explicit
pg_catalog.prefixes for all catalog functions and views (e.g.pg_catalog.current_database(),pg_catalog.now()). This is a partial mitigation: it closes thesearch_path-shadowing shape in operator- and user-supplied metric bodies, but other expression shapes (user-defined functions, operators or casts; joins or subqueries on user-owned tables and views; RLS policies on read-touched objects) remain superuser code paths until Patch 2 lands.Restrict database ownership. Ensure only fully trusted roles own user databases in scraped clusters. The exploit requires the ability to plant an object on the metrics exporter's
search_pathin a scraped database, typically by owning the database (and thereforepublicviapg_database_owner) or by holdingCREATEon a schema already reachable throughsearch_path.PG <15 caveat:
publicgrantsCREATEtoPUBLICby default before PostgreSQL 15, so any authenticated role in a scraped database can plant a shadow object regardless of ownership.Limit the scope of
target_databases: '*'queries. Avoidtarget_databases: '*'unless every database in the cluster, and every role that owns one, is fully trusted. Where possible, restricttarget_databasesto specific, known-safe databases.Do not expose metric query SQL to untrusted users. Multi-tenant platforms that allow customers to supply or influence custom metric query bodies should treat this as a critical trust boundary until the architectural fix is released.
References
cnpg_metrics_exporterrole withpg_ident.confpeer mapping"Severity
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:HReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Release Notes
cloudnative-pg/cloudnative-pg (github.com/cloudnative-pg/cloudnative-pg)
v1.29.1Compare Source
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 thepostgressuperuser. It now uses a dedicatedcnpg_metrics_exporterrole withpg_monitorprivileges only, closing a chain that let a low-privilege database user gain PostgreSQL superuser. (GHSA-423p-g724-fr39)Upgrade impact: custom monitoring queries that read user-owned tables, or use
target_databases: '*'against databases wherePUBLIC CONNECThas been revoked, need explicitGRANTstatements tocnpg_metrics_exporter. See "Custom query privileges and safety" and "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_exporterrole 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_catalogobject explicitly. Unqualified references resolve throughsearch_path, which a database user can manipulate to shadow built-in objects. (#10576)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)
CVE remediation in
github.com/jackc/pgx/v5: bumped to v5.9.2 to pick up upstream fixes forCVE-2026-33816(memory-safety inpgproto3) andGHSA-j88v-2chj-qfwx(SQL injection via simple-protocol dollar-quoted string handling). (#10437, #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, andnet(CVE-2026-32280, CVE-2026-32281, CVE-2026-33810, CVE-2026-33814, CVE-2026-33811, CVE-2026-39825). (#10463, #10647)Build pipeline hardening: the Go 1.26.3 bump also addresses CVE-2026-42501 (
cmd/gomodule-checksum validation), reducing supply-chain exposure during release builds. The affected code paths are not reachable from the running operator. (#10647)Changes
VerifyPeerCertificatetoVerifyConnection, 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)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
-rwservice kept routing to it, replicas could reconnect, and committed writes were lost topg_rewind. The old primary is now labeledunhealthyto isolate it from service traffic during failover. (#10409)Fixed failover not being triggered when the node hosting the primary becomes unreachable. The operator now reads the pod's
Readycondition (flipped toFalseby the node controller when the kubelet stops reporting) instead ofContainersReady, which stays stale asTruein that scenario. Combined with the spurious-failover guard (#10445), failover triggers only when Kubernetes itself marks the pod not Ready. (#10448)Fixed spurious failovers caused by transient failures on the primary's HTTP status endpoint. (#10445)
Fixed escaping of backslashes and control characters in PostgreSQL configuration values. Previously, such characters in parameters like
log_line_prefixcould corrupt the configuration file or be silently stripped at runtime. (#10515)Fixed
restore_commandconstruction to shell-quote each argument. Values such as adestinationPathcontaining 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)Tightened
recoveryTargetvalidation in the admission webhook:targetXIDmust now be a non-negative 32-bit integer, andtargetNamemust 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)Fixed snapshot restores failing when leftover
pgsql_tmp*directories were present in the data directory. (#10447)Fixed a deadlock occurring when PVC storage size and resource requests are changed simultaneously. (#10427)
Configuration
📅 Schedule: (UTC)
🚦 Automerge: Enabled.
♻ Rebasing: Never, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.