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.
// 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
-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.
# 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.
