The CloudNativePG project announced versions 1.29.1 and 1.28.3 to fix CVE-2026-44477, the first CVE assigned against the operator, rated critical (CVSS v4 9.4 per the project's announcement; other databases list different scores). The affected range is every version before 1.28.3, and 1.29.0. If you run PostgreSQL on Kubernetes through this operator, upgrading is the action item. This post covers the more durable lesson: why the design pattern behind the bug is common, and how to check for it in your own monitoring.
We are working from the project's announcement and advisory databases. Some exploitation details circulating in third-party write-ups are secondhand, and we flag them as such below.
What went wrong
Per the advisories, the operator's metrics exporter opens its PostgreSQL connection as the postgres superuser over the pod-local Unix socket, then immediately demotes the session with SET ROLE pg_monitor so the monitoring queries run with limited privileges.
That looks reasonable, and it's a common shortcut: the exporter needs a connection that always works, including during bootstrap, so it uses the most privileged identity available and drops down. The weakness is that SET ROLE is a reversible demotion. The session's authenticated user is still the superuser; the active role is merely changed. Anything that can execute SQL inside that session can, in principle, switch back.
The attack surface here is that monitoring queries are not only the built-in ones. Operators can define custom queries, and database objects such as functions or views in the schemas those queries touch are controlled by whoever created them. Third-party analyses describe two paths: a low-privileged database role causing SQL to run during a scrape that resets the role, and schema shadowing, where an unqualified identifier in a monitoring query resolves to an attacker-controlled object. From superuser, COPY ... TO PROGRAM reaches operating system commands in the Postgres container. Treat these mechanics as plausible rather than confirmed; the fix itself is consistent with them, since the release reportedly schema-qualifies built-in monitoring queries with pg_catalog.
The structural lesson is independent of the details: a connection that authenticates as a superuser and relies on SET ROLE for containment is only as safe as every query that will ever run on it.
Checking and upgrading
First find out what you run. For an operator installed through Helm:
kubectl get deployment -n cnpg-system cnpg-controller-manager \
-o jsonpath='{.spec.template.spec.containers[0].image}'Then check each cluster's instance manager version, since the exporter runs inside the instance manager in the pod, not in the operator Deployment:
kubectl get clusters.postgresql.cnpg.io -A \
-o custom-columns=NS:.metadata.namespace,NAME:.metadata.name,IMG:.status.image
kubectl cnpg status <cluster-name> -n <namespace>Upgrade the operator to 1.28.3 or 1.29.1 or later. Instance managers are updated as pods roll, which means the fix reaches running clusters through an in-place or rolling update depending on your configuration. Plan for that restart window; for primaries, do it through the supported switchover path rather than deleting pods by hand. Confirm afterwards that every pod reports the patched instance manager.
If you cannot upgrade immediately, reduce exposure while you wait:
- Remove or review custom monitoring queries (the
monitoringconfig maps and secrets) so nothing user-influenced runs on the exporter connection. - Restrict who can create objects, especially functions and operators, in schemas the monitoring queries read. Revoking
CREATEonpublicfrom application roles is a sound default regardless:
REVOKE CREATE ON SCHEMA public FROM PUBLIC;- Tighten
NetworkPolicyso only your Prometheus scrape path can reach the metrics port.
Auditing your own monitoring setup
The CVE is specific to one operator, but the pattern shows up everywhere. A short checklist for any exporter or agent you run against a database:
- What identity does it authenticate as? Prefer a dedicated login role with
pg_monitormembership from the start, not a superuser that demotes itself. - Is containment reversible?
SET ROLEandSET SESSION AUTHORIZATIONcan generally be undone by a session that began with higher privilege. A real boundary is a separate login. - Are all queries schema-qualified? Unqualified names resolve through
search_path, which an attacker can influence in some configurations. Qualify withpg_catalog.or pinsearch_pathfor the role. - Who can add queries? Custom metric definitions are code that runs with the exporter's authority. Review them like code, not like configuration.
- Can the database host reach out?
COPY ... TO PROGRAMis the usual stepping stone from SQL to a shell. If no application needs it, only superusers can use it by default, so the real question is keeping superuser sessions unreachable from untrusted SQL.
Several of these map to older principles: least privilege, separation of identities, and not letting data cross into the control path. They are easy to forget in glue components like exporters because nobody thinks of them as part of the security perimeter.
What we recommend
Upgrade CloudNativePG now and verify instance manager versions per cluster, not just the operator. Then spend an hour on the checklist above for the other monitoring components in your estate; Postgres exporters, backup agents, and migration tools often share the same shortcut. A critical CVE in a well-maintained project is a useful prompt to look at the components nobody has reviewed. If you'd like a second pair of eyes on a Kubernetes-hosted PostgreSQL setup, webhani can help with a focused review.