CVE-2026-6471 lets a PostgreSQL replication account run code as the system user
Present since PostgreSQL 9.4 in 2014, CVE-2026-6471 (CVSS 7.2) lets an account holding the REPLICATION attribute load an arbitrary library through logical decoding and run code as the server’s operating-system user. Fixed on August 13, 2026 via the output_plugin_libraries parameter: update and make sure your output plugins are explicitly allowlisted.
2014. PostgreSQL 9.4 introduces logical decoding — and, with it, the flaw later tracked as CVE-2026-6471 twelve years on. August 13, 2026. The PostgreSQL project ships fixes in 18.6, 17.11, 16.15, 15.19 and 14.24, with a new output_plugin_libraries parameter. September 1, 2026. Cyera Research publishes PostGREShell, the detailed write-up that names the flaw. Why it matters: a REPLICATION account — the kind held by backups, replicas and CDC pipelines — can run arbitrary code as the server’s operating-system user. The fix is available now, but it ships a hardening-by-default change that can silently stop replication if you do not re-allow your plugins.
A loading path that was never checked
CVE-2026-6471 is an arbitrary-library load through logical decoding. The plugin name supplied in a CREATE_REPLICATION_SLOT command is passed straight to the function that loads the library — bypassing the path restriction that would confine a non-superuser to an administrator-controlled directory. The replication protocol’s parser accepts almost any character inside a double-quoted plugin name, including path separators and ../ traversal: a full filesystem path reaches the loader as typed.
The result is a dlopen of any file visible to the OS account running the server. The loaded code runs inside the database backend process, under the postgres user — that is, with operating-system privileges, not those of a mere SQL role.
Exploitation boils down to two prerequisites: an account carrying the REPLICATION attribute, and a server running with wal_level = logical. Those are exactly the accounts held by backup tools, standby servers, change-data-capture (CDC) pipelines and monitoring systems.
Who is affected: everyone who replicates
The CVSS 3.1 vector rates the flaw 7.2 (AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H), with Privileges Required: High — a scoring choice Cyera disputes, arguing that the REPLICATION attribute is in practice a low-privilege backup credential handed out widely across organizations. SUSE reproduces that same assessment.
The flaw has existed since logical decoding arrived in PostgreSQL 9.4 in 2014. All versions before 18.6, 17.11, 16.15, 15.19 and 14.24 are affected. Installs using third-party output plugins — wal2json and decoderbufs among them — face a side effect: after updating, logical decoding is refused until an administrator adds the library to the allowlist. The fix adds output_plugin_libraries, which by default permits only pgoutput, test_decoding.
The reach of exploitation
On Windows, the server resolves a network path over SMB and fetches the library from an attacker-controlled machine, writing nothing to the target. On Linux and macOS, the same result requires NFS automounting to be enabled; everywhere else the attacker needs an existing way to write a file to the server’s disk. In every case the payload runs as the postgres user.
Cyera validated the severity with a test plugin that rewrites the role catalog directly to turn the replication account into a PostgreSQL superuser, then sets up three persistence mechanisms that survive a server restart. A mere replication right thus becomes full control of the instance, without ever leaving the replication protocol.
The managed-database angle matters as much. Providers such as Amazon RDS, Google Cloud SQL and Azure Database roll these fixes into their managed service, but the customer still owns the output_plugin_libraries allowlist and, more importantly, the replication accounts they handed out to CDC connectors, backup jobs and BI tools. A managed instance does not remove the exposure — it relocates it into configuration. The practical check is the same: enumerate every account carrying REPLICATION, confirm each output plugin in use is allowlisted, and treat any refusal message in the logs as an incident signal rather than a nuisance.
The project explicitly declined to apply the existing LOAD restriction to the replication path: imposing it retroactively would have forced all third-party plugins under $libdir/plugins, breaking existing deployments. The fix therefore prefers an explicit allowlist over path confinement.
Patch and reconfigure
Updating alone is not enough: the fix hardens by default, and that hardening can break your replicas if you have not planned for it. The playbook runs in three steps.
-- 1. List the plugins your replication slots actually use
SELECT DISTINCT plugin FROM pg_replication_slots WHERE plugin IS NOT NULL;
-- 2. Allowlist each third-party plugin in postgresql.conf, then reload
-- output_plugin_libraries = 'pgoutput, test_decoding, wal2json' # 3. Reload the server configuration
psql -c "SELECT pg_reload_conf();" After updating, any refused load appears in the logs as ERROR: library "…" may not be used as an output plugin, with a hint naming the setting. Apply 18.6, 17.11, 16.15, 15.19 or 14.24 depending on your branch, then make sure every third-party decoding plugin is listed in output_plugin_libraries — otherwise your replication pipelines will stop silently at the next restart.
Checking whether you were already compromised
Beyond the patch, look for traces of exploitation that may already have occurred. Cyera describes a proof-of-concept plugin that rewrites the role catalog to promote the replication account to superuser and installs three persistence mechanisms — a pattern DBAs can search for directly. Compare the list of superusers against your inventory, and inspect recently created roles and any pg_replication_slots entries that do not match your known pipelines.
-- Superuser roles: compare against your inventory
SELECT rolname, rolsuper, rolcreaterole, rolcreatedb
FROM pg_roles WHERE rolsuper ORDER BY rolname;
-- Unexpected replication slots
SELECT slot_name, plugin, database, active FROM pg_replication_slots; Any library loaded outside the allowlist also leaves an explicit trace: ERROR: library "…" may not be used as an output plugin. On already-patched instances, such a message in the logs is a sign of an attempt — or of successful exploitation before the update.
If any of those checks turn up an unexpected role or slot, do not simply delete it: the attacker may have left further persistence, and removing the visible artifact without understanding the entry path invites a repeat. Capture the role’s grants, the slot’s plugin, and the server’s log entries around the creation time, then follow your standard database-incident playbook — which, for a replication-role escalation, should include rotating the postgres OS account and auditing every CDC connector.
Logical decoding, the workhorse of CDC
To see why CVE-2026-6471 goes beyond plain replicas, you have to measure what logical decoding feeds. Introduced in PostgreSQL 9.4, it turns transaction logs (WAL) into a structured stream of events — inserts, updates, deletes — consumed by tools such as Debezium, pglogical or wal2json to power change-data-capture pipelines, search indexes, data warehouses and caching layers.
The operational consequence: REPLICATION accounts are not a rare exception reserved for a few DBAs, but service credentials deployed at scale, often living in config files, secret managers or connectors. That is exactly what makes the CVSS rating misleading: a “high privilege” in PostgreSQL schema terms is, in practice, a widely distributed low-level secret. Every CDC pipeline is therefore a potential exploitation path, and the update must be accompanied by a full inventory of those accounts.
Verdict
If you run logical replication or a CDC pipeline, update to the fixed version of your branch, then explicitly allow your output plugins in output_plugin_libraries before reloading — the flaw has been open since 2014, and exploitation only asks for an already-compromised REPLICATION account.
If you do not use logical decoding, the update is still required: the flaw is exploitable as soon as wal_level = logical is set, and an administrator can flip that parameter without you noticing.
Either way, treat REPLICATION accounts as sensitive secrets rather than low-level credentials: it is the gap between the CVSS rating and operational reality that makes CVE-2026-6471 dangerous.
References
- NVD — CVE-2026-6471
- PostgreSQL — CVE-2026-6471 security page
- PostgreSQL — 18.6, 17.11, 16.15, 15.19, 14.24 release announcement
- Cyera Research — PostGREShell: the database powering much of the internet had an open door for 12 years
- The Hacker News — PostgreSQL Fixes 12-Year-Old Logical Decoding Flaw Enabling Replication-Role Code Execution