CVE-2026-61781 – privilege escalation via SQL injection in create_partition_time

Description

create_partition_time() builds a dynamic SQL statement that interpolates the part_config.time_encoder value raw (%s, not %I) into an EXECUTE format('SELECT %s(%L)', …) call. The time_encoder column is plain text with no CHECK constraint and no INSERT/UPDATE trigger, so any role holding the documented partman_user grants (INSERT/UPDATE on partman.part_config) can store an arbitrary SQL string there rather than a function name. Because the value is spliced verbatim instead of being quoted as an identifier, a crafted multi-statement payload such as benign_encoder(now()); ALTER ROLE attacker SUPERUSER; SELECT benign_encoder is executed as written. When the pg_partman_bgw background worker later creates a new child partition for a text/uuid-keyed set, it runs this statement with the privileges of pg_partman_bgw.role, which defaults to postgres (a PostgreSQL superuser). The result is a reliable escalation from a low-privileged database user to PostgreSQL superuser, and from there to operating-system command execution as the postgres user (e.g. via COPY … TO PROGRAM). The poisoned part_config row persists across worker restarts, so an attacker who is stripped of superuser without the row being cleared is re-escalated on the next maintenance tick. The impact is most severe in untrusted multi-tenant deployments where several roles manage their own partition sets within a single database.


Vulnerability Information

  • Product / Framework: PostgreSQL pg_partman
  • Vendor Domain: www.postgresql.org
  • Vulnerability Type: SQL Injection
  • CVE Details: View Full CVE Details →