Skip to main content
Vulnerability Database/CVE-2026-61819

CVE-2026-61819: pg_partman PostgreSQL Extension SQLI Vulnerability

CVE-2026-61819 is a SQL injection flaw in pg_partman PostgreSQL extension that allows privilege escalation to superuser level. This post explains its technical details, affected versions, and mitigation steps.

Published:

CVE-2026-61819 Overview

CVE-2026-61819 is a SQL injection vulnerability [CWE-89] in pg_partman, a PostgreSQL extension that manages partitioned tables by time or ID. Versions prior to 5.5.0 embed the p_parent_table parameter verbatim inside a SQL string literal used to call pg_jobmon.add_job() from exception handlers. A user with the partman_user role can create a parent-table name containing a single quote to break out of the literal and inject arbitrary SQL. When pg_partman_bgw executes the affected exception path, the injected SQL runs with the privileges configured in pg_partman_bgw.role, which defaults to PostgreSQL superuser.

Critical Impact

Successful exploitation yields database-wide compromise and operating-system command execution as the PostgreSQL service account. The malicious part_config row persists, allowing repeated escalation on every subsequent maintenance tick.

Affected Products

  • pg_partman PostgreSQL extension, all versions prior to 5.5.0
  • Deployments where pg_jobmon is installed alongside pg_partman
  • PostgreSQL instances where part_config.jobmon is set to true

Discovery Timeline

  • 2026-09-18 - CVE-2026-61819 published to the National Vulnerability Database (NVD)
  • 2026-09-23 - Last updated in NVD database

Technical Details for CVE-2026-61819

Vulnerability Analysis

The flaw resides in multiple pg_partman functions that invoke pg_jobmon.add_job() from within EXCEPTION blocks. These handlers build a dynamic SQL statement that concatenates the p_parent_table argument directly into a single-quoted string literal without escaping or parameter binding. Because p_parent_table corresponds to a user-controllable identifier stored in part_config, an attacker with partman_user privileges can persist a crafted value that carries an embedded single quote followed by attacker-supplied SQL.

Exploitation requires that the pg_partman_bgw background worker later trigger the vulnerable exception path during scheduled maintenance. When it does, the injected statement executes under the role identified by pg_partman_bgw.role. In default deployments this role is a PostgreSQL superuser, so the injected SQL can call COPY ... PROGRAM or create untrusted-language functions to achieve command execution as the PostgreSQL service account.

Root Cause

The root cause is improper neutralization of special elements used in an SQL command [CWE-89]. The vulnerable functions rely on string concatenation to construct calls to pg_jobmon.add_job(), treating the parent-table identifier as trusted data rather than untrusted input that must be quoted with quote_literal() or bound as a parameter.

Attack Vector

Exploitation is network-reachable but requires an authenticated database role with partman_user privileges and the ability to create or configure a parent table whose name contains a single quote. The attacker seeds the payload once by inserting the malicious identifier into part_config. On the next maintenance tick that triggers the affected exception handler under pg_partman_bgw, the injected SQL executes with elevated privileges. The persistence of the part_config row means the escalation reoccurs on subsequent ticks until the malicious row is removed.

text
// pg_partman version metadata change in the fix commit
 {
     "name": "pg_partman",
     "abstract": "Extension to manage partitioned tables by time or ID",
-    "version": "5.4.3",
+    "version": "5.5.0",
     "maintainer": [
         "Keith Fiske <keith@keithf4.com>"
     ],
// Source: https://github.com/pgpartman/pg_partman/commit/ba9405542acf24dd881845b935cab8b165854361

Detection Methods for CVE-2026-61819

Indicators of Compromise

  • Rows in part_config where parent_table contains a single quote or other SQL metacharacters.
  • Unexpected entries in pg_jobmon job history referencing malformed or truncated table identifiers.
  • PostgreSQL logs showing COPY ... PROGRAM, CREATE FUNCTION ... LANGUAGE 'c', or role changes executed by the pg_partman_bgw worker.

Detection Strategies

  • Query part_config and pg_class for parent-table names containing single quotes, backslashes, or comment sequences.
  • Enable log_statement = 'ddl' and review DDL executed under the pg_partman_bgw worker session for statements unrelated to partition maintenance.
  • Audit the effective value of pg_partman_bgw.role and flag configurations where the role holds SUPERUSER.

Monitoring Recommendations

  • Alert on new or modified part_config rows created by non-administrative roles.
  • Monitor operating-system process creation by the PostgreSQL service account for shell utilities, network tools, or scripting interpreters.
  • Forward PostgreSQL and host telemetry into a centralized data lake for correlation across database and operating-system layers.

How to Mitigate CVE-2026-61819

Immediate Actions Required

  • Upgrade pg_partman to version 5.5.0 or later on every PostgreSQL instance where the extension is installed.
  • Inventory all part_config rows and remove any entries whose parent_table value contains quote characters or other unexpected metacharacters.
  • Reduce the privileges of pg_partman_bgw.role from superuser to a least-privilege role limited to partition maintenance.

Patch Information

The fix is included in pg_partman 5.5.0. Review the GitHub Security Advisory GHSA-gv5h-j2cm-rhc3, the GitHub Release v5.5.0, and the remediation commit for full details.

Workarounds

  • Set part_config.jobmon to false for all rows to bypass the vulnerable pg_jobmon.add_job() code path until patching is complete.
  • Revoke partman_user role membership from any account that does not require partition administration.
  • Uninstall pg_jobmon where it is not required, since the injection path only executes when pg_jobmon is present.
bash
# Disable the vulnerable jobmon integration on all configured parent tables
psql -d your_database -c "UPDATE partman.part_config SET jobmon = false;"

# Verify pg_partman version after upgrade
psql -d your_database -c "SELECT extname, extversion FROM pg_extension WHERE extname = 'pg_partman';"

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.