Skip to main content

CloudNativePG CVE-2026-44477

| EUVDEUVD-2026-32930 CRITICAL
Execution with Unnecessary Privileges (CWE-250)
2026-05-11 https://github.com/cloudnative-pg/cloudnative-pg GHSA-423p-g724-fr39
9.4
CVSS 4.0 · Vendor: https://github.com/cloudnative-pg/cloudnative-pg
View

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain

  1. Access
    Obtain non-superuser role on scraped DB
  2. Delivery
    Create shadow object matching unqualified identifier
  3. Exploit
    Wait for scrape interval (≤30s)
  4. Execution
    Exporter evaluates shadow under session_user=postgres
  5. Persist
    RESET ROLE recovers superuser
  6. Impact
    COPY TO PROGRAM spawns OS shell in primary pod

Vulnerability Assessment

Weakness
CWE
ASVS 5.0
V8 - Authorization Unnecessary privilege execution
Exploitation Conditions

Path 2 (stock deployment) requires only that the attacker authenticate as a non-superuser PostgreSQL role that owns a user database in a scraped CNPG cluster - the default app role created by bootstrap.initdb satisfies this - and that default monitoring is enabled (the operator default). No custom configuration is needed and no user interaction is required; exploitation completes on the next scrape, with a worst-case window of 30 seconds. Path 1 additionally requires that an operator has supplied at least one custom metric query containing an unqualified relation, function, operator, cast, or RLS-touched object. Limiting factors: the attacker must already hold a PostgreSQL role that can plant an object on the exporter's search_path (typically database ownership, or membership in pg_database_owner, or CREATE on a reachable schema; on PostgreSQL <15 the default public CREATE-to-PUBLIC grant lowers this bar to any authenticated role in a scraped database). Network access to the PostgreSQL protocol is required to plant the shadow object, though chained SQL injection in an app fronting the cluster is sufficient. On PostgreSQL 15+ with non-default public permissions, the attacker must own the database or hold an explicit CREATE grant.

Impact

This is a real, high-priority issue rather than an inflated CVSS score. The CVSS 4.0 vector AV:N/AC:L/AT:N/PR:L/UI:N with VC:H/VI:H/VA:H and scope change indicators (SC:H/SI:H/SA:H) reflects that a low-privileged DB role - including the default app role provisioned by bootstrap.initdb - escalates to PostgreSQL superuser and OS-level command execution within a single scrape interval (≤30s). PR:L is accurate: an authenticated database role with ownership of a user database is required, not network-anonymous access; however, this prerequisite is trivially met in any application backed by CNPG because a chained SQL injection in the front-end app suffices to act as that role. No EPSS score, KEV listing, or POC was provided, so there is no public exploit identified at time of analysis, but Path 2 affects stock deployments with no custom configuration required, dramatically increasing the realistic attack surface. The CVSS network attack vector is somewhat optimistic given the entry point is the PostgreSQL protocol (typically not internet-exposed), but in multi-tenant Kubernetes platforms or apps with SQLi, the chain is fully reachable.

Exploit ScenarioDerived

On a stock CNPG cluster (Path 2), an attacker who controls the default app role - for example via SQL injection in the application backed by CNPG - connects to the user database and creates a function named current_database() in a schema they own that is on the search_path. Within one scrape interval (≤30s), the metrics exporter evaluates the pg_extensions query from default-monitoring.yaml, resolves the unqualified current_database() call to the attacker's shadow function under session_user = postgres, which executes RESET ROLE followed by COPY ... TO PROGRAM 'sh -c <payload>' to spawn an OS-level shell as the postgres user inside the primary pod. No public exploit identified at time of analysis, though the chain is fully documented in the GHSA advisory.

Act Now Prioritize within 24-48h. Why: CRITICAL severity.
Patch available 0.0% exploitation probability (EPSS)

Get an e-mail when this CVE is exploited, patched or re-scored. Free account.

Alert me

AnalysisAIv2 – May 28, 2026

Privilege escalation and OS command execution in CloudNativePG (CNPG) versions prior to 1.28.3 and 1.29.1 allow low-privileged PostgreSQL roles to gain superuser access and execute arbitrary commands inside the primary database pod. The metrics exporter connects as the postgres superuser and only demotes via SET ROLE, leaving session_user as superuser; an attacker who owns a database (including the default app role) can shadow unqualified identifiers like current_database() referenced in the stock default-monitoring.yaml, triggering the chain on the next scrape (≤30s). No public exploit identified at time of analysis, but the vulnerability is highly impactful (CVSS 9.4) and affects default deployments without custom metrics.

Earlier versions of this analysis (1)
v1 May 11, 2026 - 16:17

Privilege escalation in CloudNativePG metrics exporter allows low-privileged database users to obtain PostgreSQL superuser privileges and execute arbitrary OS commands inside primary pods. The metrics exporter authenticates as the postgres superuser then demotes with SET ROLE, leaving session_user as postgres-a residual superuser identity exploitable via RESET ROLE. Stock deployments using default-monitoring.yaml are vulnerable through the pg_extensions metric's unqualified current_database() call against all user databases, enabling any database owner (including the default 'app' role) to plant shadow functions and trigger code execution within 30 seconds. Patches available in v1.28.3 and v1.29.1 introduce a dedicated cnpg_metrics_exporter role with peer authentication, eliminating the superuser session entirely. No public exploit identified at time of analysis, but the attack path is fully detailed in the vendor advisory.

RemediationAI

Vendor-released patch: upgrade to CloudNativePG v1.28.3 or v1.29.1 (https://github.com/cloudnative-pg/cloudnative-pg/releases/tag/v1.28.3 and https://github.com/cloudnative-pg/cloudnative-pg/releases/tag/v1.29.1), which include Patch 1 (PR #10576, schema-qualifying all catalog references in default-monitoring.yaml and documentation) and the upcoming Patch 2 introducing a dedicated non-superuser cnpg_metrics_exporter role with pg_ident.conf peer mapping that eliminates the root cause. For replica clusters, upgrade the source primary before the replica or the replica will scrape against a missing role. If immediate upgrade is impossible, schema-qualify every identifier in custom metric queries with explicit pg_catalog. prefixes (partial mitigation - closes only the search_path shadowing shape, not UDFs, operators, casts, or RLS expressions); restrict database ownership in scraped clusters to fully trusted roles (note PG <15 grants CREATE on public to PUBLIC by default, weakening this control); avoid target_databases: '*' unless every database and owning role is trusted, restricting to specific known-safe databases instead; and on multi-tenant platforms, treat the ability to influence metric query bodies as a critical trust boundary and revoke that capability from untrusted users. Operators who copied default-monitoring.yaml into custom ConfigMaps must re-qualify those copies manually - the upgrade does not rewrite user-managed manifests.

Affected VersionsENISA

cloudnative-pg < 1.28.3
cloudnative-pg 1.29.0, < 1.29.1

Affected Packages

go github.com/cloudnative-pg/cloudnative-pg fix: 1.28.3, 1.29.1
euvd cloudnative_pg fix: 1.28.3, 1.29.1

Source: OSV (Open Source Vulnerabilities)

Affects your stack

Affects 2 packages in go, euvd

Checking this CVE against your own stacks and servers is part of the Basic plan and up.

Technical ContextAI · show details

CloudNativePG is a Kubernetes operator (pkg:go/github.com_cloudnative-pg_cloudnative-pg) that manages PostgreSQL clusters. The root cause maps to CWE-250 (Execution with Unnecessary Privileges): the metrics exporter authenticates over the pod-local Unix socket as the postgres superuser and uses SET ROLE pg_monitor to drop privileges, but SET ROLE only mutates current_user while session_user retains the superuser identity. Because RESET ROLE (and RESET SESSION AUTHORIZATION) restore the authenticated identity, any SQL evaluated inside a scrape session is a superuser code path. PostgreSQL's search_path resolution allows user-owned schemas (or public pre-PG 15, where CREATE is granted to PUBLIC by default) to shadow unqualified catalog references such as current_database(). Once superuser is recovered, COPY ... TO PROGRAM spawns OS subprocesses as the postgres UID inside the primary pod, even within a READ ONLY transaction (READ ONLY gates database writes, not external process execution).

Know when PostgreSQL gets its next vulnerability

  • Watch products and get an email when something new is published
  • Check this CVE against your own stack and servers
  • Exploit and PoC references, threat intelligence from 22 sources

No credit card · 7-day full trial

Severity by source

Vendor (https://github.com/cloudnative-pg/cloudnative-pg) PRIMARY 9.4 CRITICAL
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H
SUSE CRITICAL
Red Hat 8.8 HIGH

Primary rating from Vendor (https://github.com/cloudnative-pg/cloudnative-pg).

CVSS VectorVendor: https://github.com/cloudnative-pg/cloudnative-pg

Attack Vector
Network
Attack Complexity
Low
Attack Requirements
None
Privileges Required
Low
User Interaction
None
Vulnerable system: Confidentiality
High
Vulnerable system: Integrity
High
Vulnerable system: Availability
High
Subsequent system: Confidentiality
High
Subsequent system: Integrity
High
Subsequent system: Availability
High

Lifecycle Timeline

3
Analysis Updated
May 28, 2026 - 17:28 vuln.today
v2 - CVSS changed
CVSS changed
May 28, 2026 - 17:22 NVD
9.4 (CRITICAL)
CVE Published
May 11, 2026 - 15:59 nvd
CRITICAL

DescriptionCVE.org

Impact

The CloudNativePG metrics exporter opens its PostgreSQL connection as the postgres superuser via the pod-local Unix socket, then demotes the session with SET ROLE pg_monitor. SET ROLE changes only current_user; session_user remains postgres. That residual superuser identity is the foothold for the rest of the chain.

Any SQL expression evaluated inside the scrape session can invoke RESET ROLE to recover real superuser privileges, then use COPY ... TO PROGRAM to spawn an OS-level subprocess as the postgres user inside the primary pod. The READ ONLY transaction 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_path of 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 the session_user = postgres scrape 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_path shadowing 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_extensions metric shipped in default-monitoring.yaml used an unqualified current_database() call and ran against every user database (target_databases: '*'). Any non-superuser who owns a user database (including the default app role created by bootstrap.initdb) could shadow current_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 app role) to PostgreSQL superuser, plus arbitrary OS command execution as the postgres user 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
  • All deployments on any supported release with default monitoring enabled are affected by Path 2.
  • All deployments on any supported release that use custom metric queries containing unqualified catalog references are affected by Path 1.
  • Multi-tenant platforms that allow customers to supply or influence custom metric query bodies are at the highest risk for Path 1.

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_catalog function and view references in the shipped default-monitoring.yaml and 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 copy default-monitoring.yaml into custom monitoring ConfigMaps, or have copy-pasted unqualified queries elsewhere, must re-qualify those queries themselves.

Backported to all currently supported releases:

  • v1.29.x (x ≥ 1)
  • v1.28.x (x ≥ 3)
Patch 2: "dedicated cnpg_metrics_exporter role with pg_ident.conf peer mapping"

Introduces a dedicated cnpg_metrics_exporter PostgreSQL role (granted pg_monitor, no superuser privileges) and maps it in pg_ident.conf via peer authentication on the local Unix socket, following the same pattern already used for cnpg_pooler_pgbouncer. The metrics exporter connects as this role instead of postgres, so session_user is never a superuser and RESET ROLE has 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 for SET SESSION AUTHORIZATION is whether the *authenticated* user is a superuser, not the current session_user. With the connection still authenticated as postgres, any SQL in the session can run RESET SESSION AUTHORIZATION and recover the original superuser identity. This is the same recovery primitive as RESET 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 ROLE and RESET SESSION AUTHORIZATION cannot recover superuser, and COPY ... TO PROGRAM requires a privilege pg_monitor does not grant. As defense in depth, the monitoring transaction also prepends pg_catalog to the connection's search_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 to cnpg_metrics_exporter, or superuser-only catalogs such as pg_authid or pg_subscription) will fail and need explicit GRANT statements to cnpg_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_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 or the role is created manually (see the monitoring documentation).

The patch will be backported to all currently supported releases:

  • v1.29.x (x ≥ 1)
  • v1.28.x (x ≥ 3)

Workarounds

If upgrading immediately is not possible:

  1. 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 the search_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.
  2. 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_path in a scraped database, typically by owning the database (and therefore public via pg_database_owner) or by holding CREATE on a schema already reachable through search_path.

*PG <15 caveat:* public grants CREATE to PUBLIC by default before PostgreSQL 15, so any authenticated role in a scraped database can plant a shadow object regardless of ownership.

  1. Limit the scope of target_databases: '*' queries. Avoid target_databases: '*' unless every database in the cluster, and every role that owns one, is fully trusted. Where possible, restrict target_databases to specific, known-safe databases.
  2. 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

  • Fix (Patch 1): PR #10576 "schema-qualify catalog references in default monitoring queries and documentation samples"
  • Fix (Patch 2): "dedicated cnpg_metrics_exporter role with pg_ident.conf peer mapping"
  • Reported by: Mehmet Ince

Executive ViewAI

Why It Matters

CloudNativePG versions before 1.28.3 and 1.29.1 contain a critical privilege escalation vulnerability allowing low-privileged database users to gain superuser access and execute arbitrary commands within containerized PostgreSQL deployments. Default configurations are vulnerable, with the built-in metrics exporter triggering exploitation automatically every 30 seconds or less. Any organization using CloudNativePG faces immediate risk of complete database compromise and lateral movement into Kubernetes infrastructure.

Business Impact: Severe
Compensating Controls

Apply vendor patch.

Threat Intelligence Overview

EPSS Score
0.0%
Top 88% exploitable
Threat Intel
1
1 source
Data Quality
7 sources
Confidence: High
EUVD NVD CVE.org EPSS GHSA Vendor GitHub VulDB

How this decision was reached

The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.

SignalValue
Severity CRITICAL
CISA KEV No
Public POC No
EPSS 0.0%
Patch available Yes
Active threat No
Deciding rule
CRITICAL severity
What every action level means
Emergency Immediate action required. Criteria: CRITICAL + in CISA KEV (actively exploited) without patch, OR CRITICAL + EPSS > 30% without patch, OR CRITICAL + active threat signals without patch.
Act Now Prioritize within 24-48h. Criteria: in KEV with patch available, OR CRITICAL + public POC, OR HIGH + EPSS > 10%, OR CRITICAL + active threat, OR any CRITICAL severity.
This Week Schedule remediation this week. Criteria: HIGH severity (CVSS 7.0-8.9). Patch within normal change window.
This Month Plan within 30 days. Criteria: MEDIUM severity (CVSS 4.0-6.9), lower exploitation probability. Include in regular patch cycle.
Monitor Track and reassess. Criteria: LOW severity (CVSS 0.1-3.9), minimal exploitation risk. No immediate action needed.

SSVC AssessmentENISA

SSVC Decision· derived
Scheduled
Exploitation· derived
None
System Exposure· derived
Open
Automatable· derived
No
Human Impact
Very High

Priority Score

47
Low Medium High Critical
KEV: 0
EPSS: 0
CVSS: +47
PoC: 0
Weaponized: 0
Threat intel: 0
Gov advisory: 0

Attack Technique

SQL injection exploits the way applications construct database queries by mixing user input directly into SQL statements.

OS command injection occurs when an application passes unsanitized user input directly into system shell commands.

Privilege escalation occurs when an attacker leverages flaws in access control mechanisms to gain permissions beyond what they were originally granted.

CVE-2025-1094 HIGH POC
8.1 Feb 13

PostgreSQL libpq functions PQescapeLiteral(), PQescapeIdentifier(), PQescapeString(), and PQescapeStringConn() improperl

CVE-2024-55964 CRITICAL POC
9.8 Mar 26

An issue was discovered in Appsmith before 1.52. Rated critical severity (CVSS 9.8), this vulnerability is remotely expl

CVE-2013-1899 MEDIUM POC
6.5 Apr 04

Argument injection vulnerability in PostgreSQL 9.2.x before 9.2.4, 9.1.x before 9.1.9, and 9.0.x before 9.0.13 allows re

CVE-2026-20253 CRITICAL POC
9.8 Jun 10

Unauthenticated arbitrary file write in Splunk Enterprise (below 10.2.4 and 10.0.7) and Splunk Cloud Platform (below 10.

CVE-2026-9586 CRITICAL POC
9.3 Jul 17

Unauthenticated SQL injection in Sangoma Switchvox SMB Edition 8.3 (build 104997) lets remote attackers execute arbitrar

CVE-2017-7546 CRITICAL
9.8 Aug 16

PostgreSQL versions before 9.2.22, 9.3.18, 9.4.13, 9.5.8 and 9.6.4 are vulnerable to incorrect authentication flaw allow

CVE-2015-1352 MEDIUM POC
5.0 Mar 30

The build_tablename function in pgsql.c in the PostgreSQL (aka pgsql) extension in PHP through 5.6.7 does not validate t

CVE-2024-10553 CRITICAL POC
9.8 Mar 20

A vulnerability in the h2oai/h2o-3 REST API versions 3.46.0.4 allows unauthenticated remote attackers to execute arbitra

CVE-2019-9193 HIGH POC
7.2 Apr 01

In PostgreSQL 9.3 through 11.2, the "COPY TO/FROM PROGRAM" function allows superusers and users in the 'pg_execute_serve

CVE-2026-40887 CRITICAL POC
9.1 Apr 14

Unauthenticated SQL injection in Vendure Shop API allows remote attackers to execute arbitrary SQL commands against the

CVE-2022-24760 CRITICAL POC
10.0 Mar 12

Parse Server is an open source http web server backend. Rated critical severity (CVSS 10.0), this vulnerability is remot

CVE-2025-56157 CRITICAL POC
9.8 Dec 18

Hard-coded default PostgreSQL credentials shipped in the docker-compose.yaml of langgenius Dify through version 1.5.1 al

Vendor StatusVendor

SUSE

Severity: Critical
Product Status
SUSE Linux Enterprise Server 16.1 Affected
SUSE Linux Enterprise Server for SAP applications 16.1 Affected
SUSE Linux Enterprise Module for Package Hub 15 SP5 Affected
SUSE Linux Enterprise Module for Package Hub 15 SP6 Affected
openSUSE Leap 15.5 Affected

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy