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

CVE-2026-61818: PostgreSQL pg_partman SQL Injection Vulnerability

CVE-2026-61818 is a SQL injection flaw in PostgreSQL pg_partman extension affecting versions before 5.5.0. Attackers with partman_user access can execute arbitrary SQL with elevated privileges. This article covers technical details, affected versions, security impact, and mitigation strategies.

Published:

CVE-2026-61818 Overview

CVE-2026-61818 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 read part_config.time_encoder as unrestricted text and interpolate it without identifier quoting into a dynamically executed SELECT statement inside undo_partition(). Any role with partman_user access can store arbitrary SQL instead of a function name, and that SQL executes with the privileges of the caller that invokes undo_partition().

Critical Impact

A low-privileged partman_user role can inject SQL that runs with the privileges of a higher-privileged caller of undo_partition(), compromising database confidentiality, integrity, and availability.

Affected Products

  • pg_partman PostgreSQL extension, versions prior to 5.5.0
  • PostgreSQL databases loading pg_partman with partman_user roles defined
  • Environments that expose undo_partition() invocations to privileged callers

Discovery Timeline

  • 2026-09-18 - CVE-2026-61818 published to NVD
  • 2026-09-24 - Last updated in NVD database

Technical Details for CVE-2026-61818

Vulnerability Analysis

The flaw is a stored SQL injection in the undo_partition() function of pg_partman. The function retrieves the time_encoder value from the part_config metadata table and concatenates it directly into a dynamic SELECT statement without identifier quoting or validation. Because partman_user has write access to part_config, that role can replace a legitimate function name with attacker-controlled SQL.

When a more privileged role later invokes undo_partition(), the injected SQL executes under that caller's privileges. Unlike the related create-partition vulnerability, undo_partition() is not on the default background-worker path, so automatic superuser escalation is not guaranteed. However, any DBA or administrative role that manually runs undo_partition() becomes a vehicle for privilege abuse.

Root Cause

The root cause is unsafe construction of dynamic SQL. time_encoder is treated as free-form text rather than a validated identifier, and it is inserted into the executed query without quote_ident() or a whitelist check. This violates PostgreSQL guidance for handling identifiers in EXECUTE statements.

Attack Vector

Exploitation requires an authenticated role with partman_user privileges. The attacker updates the time_encoder column in part_config for a partition set with a crafted SQL payload. When a privileged operator subsequently calls undo_partition() against that partition set, the payload executes with the operator's rights, allowing data exfiltration, modification, or denial of service.

text
// Patch metadata from 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: GitHub Commit ba94055

text
-default_version = '5.4.3'
+default_version = '5.5.0'
 comment = 'Extension to manage partitioned tables by time or ID'
 relocatable = false
 superuser = false

The patch bumps pg_partman to version 5.5.0, which adds identifier quoting and validation of time_encoder before it is interpolated into dynamic SQL. See the GitHub Security Advisory GHSA-fm3m-9fh7-mqfc for full technical details.

Detection Methods for CVE-2026-61818

Indicators of Compromise

  • Non-function values, embedded whitespace, semicolons, or SQL keywords in part_config.time_encoder.
  • UPDATE statements against part_config originating from partman_user roles outside normal change windows.
  • PostgreSQL logs showing unexpected statements executed in the context of undo_partition() calls.

Detection Strategies

  • Query part_config and validate that every time_encoder value resolves to an existing function via pg_proc lookup.
  • Enable log_statement = 'mod' or pg_audit and alert on modifications to part_config performed by non-administrative roles.
  • Review installed pg_partman versions with SELECT extversion FROM pg_extension WHERE extname = 'pg_partman'; and flag any release earlier than 5.5.0.

Monitoring Recommendations

  • Ingest PostgreSQL audit and statement logs into a centralized analytics pipeline for correlation of part_config writes with subsequent undo_partition() invocations.
  • Track membership of the partman_user role and alert on unexpected grants.
  • Baseline the set of functions referenced by time_encoder and alert on any deviation.

How to Mitigate CVE-2026-61818

Immediate Actions Required

  • Upgrade pg_partman to version 5.5.0 or later on all PostgreSQL instances.
  • Audit current part_config.time_encoder values and reset any entry that is not a valid function name.
  • Restrict membership of partman_user to trusted service accounts only and revoke direct write access to part_config where possible.

Patch Information

The fix is delivered in pg_partman 5.5.0 via commit ba9405542acf24dd881845b935cab8b165854361. See the GitHub Release v5.5.0 and the GitHub Security Advisory GHSA-fm3m-9fh7-mqfc for release notes and patch details.

Workarounds

  • Revoke UPDATE privileges on part_config from partman_user until the upgrade is completed.
  • Avoid invoking undo_partition() from superuser or high-privilege sessions until patched.
  • Wrap operational calls to undo_partition() in SECURITY INVOKER procedures owned by low-privilege roles to limit blast radius.
bash
# Verify installed pg_partman version and upgrade
psql -d your_db -c "SELECT extname, extversion FROM pg_extension WHERE extname = 'pg_partman';"
psql -d your_db -c "ALTER EXTENSION pg_partman UPDATE TO '5.5.0';"
psql -d your_db -c "SELECT parent_table, time_encoder FROM partman.part_config WHERE time_encoder IS NOT NULL;"

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.