A PostgreSQL backup account can now run code on your server. Patch CVE-2026-6471.

Postgres shipped a fix on August 13 for a bug that had been sitting in the code since 2014. CVE-2026-6471 lets any account with the REPLICATION attribute, the kind of low-privilege account your backup tool or read replica uses, load an arbitrary shared library into the database process and run code as the operating system user that owns Postgres. The official advisory describes it plainly: logical decoding can dlopen an arbitrary file, chosen by the replication client, with no authorization check. Cyera Research, which reported it alongside Yu Kunpeng, calls it PostGREShell.
The mechanics are worth understanding, because they explain the fix. When a replication client opens a logical decoding slot it names an output plugin, and Postgres loads that plugin as compiled code inside its own process. For an ordinary SQL LOAD, Postgres restricts non-superusers to a controlled plugins directory. The replication path skipped that check, so the plugin name could be any path on disk. On Windows it gets worse: the loader accepts a UNC path, so an attacker points it at a DLL on their own SMB share and never has to drop a file on the target first.
Here is the part that got lost in some of the coverage. The official CVSS is 7.2, high but not critical, and the reason sits right there in the vector: PR:H. You need an account that already holds REPLICATION. This is not an unauthenticated hole facing the open internet. So why care? Because in real systems those accounts are everywhere and nobody treats them as dangerous. Every streaming replica, every backup job, every change-data-capture pipeline, every monitoring agent that tails the write-ahead log runs as a REPLICATION role. They are operational plumbing, and plumbing tends to carry weak, long-lived, widely copied credentials.
During cloud security reviews we keep finding the same shape: a replication user whose password lives in three env files and a Terraform variable, reused across staging and prod, reachable from more of the network than anyone intended. On its own that reads like a low-severity finding, an over-privileged service account. This CVE turns that exact account into remote code execution on the database host. The lesson is not really about Postgres. It is that "low-privilege" service credentials stay low-privilege only until someone finds a primitive that upgrades them.
The fix is a new server parameter, output_plugin_libraries, added by Jacob Champion. It is an allowlist. By default it permits only the two plugins that ship with Postgres, pgoutput and test_decoding, so a replication client can no longer name an arbitrary library. If you use a third-party decoder like decoderbufs (Debezium users, this means you), you have to add it back explicitly after upgrading or logical replication breaks. On version 17 and up, pg_upgrade --check refuses to proceed if the new cluster's allowlist does not cover the plugins your existing slots use. That is a useful guardrail and a migration gotcha to plan for.
What to do this week
- Patch to 18.6, 17.11, 16.15, 15.19 or 14.24. Older branches are past end of life and will not get this fix, so if you are on 13 or earlier, treat it as one more reason to move.
- Audit who holds REPLICATION. Make it a real inventory, not a guess. Any human account with the attribute should probably lose it, and every service account that keeps it needs a rotated, unique secret.
- Block outbound SMB and NFS from your database hosts. The Windows remote-DLL path depends on the database reaching an attacker's file share. Your Postgres box has no reason to open outbound SMB connections, so drop them at the firewall.
- If you set output_plugin_libraries by hand, list exactly the decoders you use and nothing else.
One thing worth checking, and one worth ignoring. Cyera's threat hunt turned up 114 malicious Postgres plugins on VirusTotal: trojans, miners, reverse shells. That is a reminder that plugin loading is a popular target, but none of those samples have been tied to exploitation of this specific CVE, so do not read it as proof you were hit. Worth ignoring: the "twelve years unpatched" framing. The flaw was real for a long time, but exploiting it still needs a REPLICATION account, and if you kept those locked down you were never as exposed as the headline suggests.
We spend a fair amount of time where database hardening meets network policy, from PHP and Docker stacks on AWS to the Cloudflare and firewall rules that decide what a compromised box can even reach. The pattern that catches teams out is almost always an over-trusted internal account plus egress nobody locked down. If a forgotten replication credential with a shared password sounds like something sitting in your infrastructure, let's talk.