Illustrative image generated with AI
PostgreSQL Logical Decoding Flaw Allows Code Execution as the `postgres` User
PostgreSQL CVE-2026-6471 lets REPLICATION users load arbitrary libraries via logical decoding to execute code as postgres. See affected versions and fix.
Text generated by artificial intelligence, published without human review. AI transparency
PostgreSQL has fixed CVE-2026-6471, a vulnerability in its logical decoding system that allows arbitrary shared libraries to be loaded onto the database server.
Exploitation does not require superuser access. However, the attacker must have a PostgreSQL account with the REPLICATION attribute, and the server must be configured with wal_level = logical.
Once the library is loaded, its code runs inside the backend process under the identity of the system account that manages PostgreSQL, normally postgres. The consequences can therefore include data theft or tampering, service disruption, privilege escalation, and persistence on the system.
The vulnerability, dubbed PostGREShell by researchers at Cyera, has a CVSS 3.1 score of 7.2 and is classified as missing authorization control (CWE-862). Vladimir Tokarev and Yu Kunpeng were credited by the PostgreSQL Global Development Group with reporting the issue. Tokarev published a technical analysis on September 1.
Which PostgreSQL Versions Need to Be Updated
The upstream releases that fix CVE-2026-6471, issued on August 13, are:
- PostgreSQL 18.6
- PostgreSQL 17.11
- PostgreSQL 16.15
- PostgreSQL 15.19
- PostgreSQL 14.24
Earlier versions in each of these five branches are vulnerable. The project advisory covers the supported series, from 14 through 18.
However, the flaw dates back to the introduction of logical decoding in PostgreSQL 9.4, in 2014. Series earlier than 14 are not covered by the current upstream advisory. Organizations using them should therefore plan a migration to a supported version rather than treating their omission from the list as evidence that they are secure.
Fixed packages are also available for Amazon RDS, Debian, SUSE, and Ubuntu. Ubuntu advisory USN-8653-1, published on August 20, 2026, provides the following versions:
| Ubuntu | Fixed package |
|---|---|
| 26.04 LTS | postgresql-18 18.6-0ubuntu0.26.04.1 |
| 24.04 LTS | postgresql-16 16.15-0ubuntu0.24.04.1 |
| 22.04 LTS | postgresql-14 14.24-0ubuntu0.22.04.1 |
Ubuntu requires PostgreSQL to be restarted after the standard security update. The package also fixes numerous other vulnerabilities, not just the logical decoding issue.
PostgreSQL 14 will also stop receiving fixes on November 12, 2026. Organizations still using this branch should include migration to a later release in their operational plans.
From the Plugin Name to dlopen(): How the Attack Works
Logical decoding translates changes recorded in the write-ahead log into a format that external systems can use. It is used, for example, in change data capture pipelines and by tools that transfer changes to other platforms.
When creating a replication slot, including through CREATE_REPLICATION_SLOT, the client can specify the output plugin to use. Before the fix, PostgreSQL did not adequately verify that a user with REPLICATION was authorized to load the requested library.
The plugin name was therefore passed to the dynamic-loading function. The replication protocol parser accepted directory separators, absolute paths, and traversal sequences such as ../ inside quoted names.
The result was a call to dlopen() on a file chosen by the attacker, provided that the file was accessible to the operating-system account running PostgreSQL. The library was loaded into the backend process, and its code acquired the privileges of the postgres user.
The standard restrictions applied by the SQL LOAD command to non-superusers did not cover this path. An existing protection could therefore be bypassed through the replication protocol.
The availability of the malicious library depends on the platform:
- on Windows, the path can point to an SMB share controlled by the attacker, without first copying the file to the server;
- on Linux and macOS, an equivalent network-based load requires NFS automounting to be enabled;
- in other scenarios, the attacker must already have a way to write the library to the server's disk.
In Cyera's tests, the loaded code directly modified the role catalog, turning the replication account into a PostgreSQL superuser. The researchers also created three forms of persistence capable of surviving a restart.
The Required Privilege Is Not Superuser, but It Remains Sensitive
The complete vector assigned to the flaw is CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H. It indicates a remotely exploitable attack with low complexity and no user interaction, but one that requires elevated privileges.
The PR:H classification may appear inconsistent with the fact that the account does not need to be an administrator. In reality, it describes a specific prerequisite: the REPLICATION attribute must already have been granted.
This privilege is often assigned to technical accounts used by standby servers, backup solutions, CDC platforms, and monitoring systems. The compromise of one of these credentials can therefore lead to code execution on the operating system.
No public proof-of-concept was found in the repositories examined as of September 4. At the same time, CVE-2026-6471 was not listed in CISA's Known Exploited Vulnerabilities catalog and had no associated KEV due date.
There is therefore no public evidence of active exploitation. The impact remains significant, especially where service accounts are shared, poorly monitored, or authorized to connect from broad networks.
The Patch Adds an Output Plugin Allowlist
The fix adds the following server parameter:
output_plugin_libraries
The default value authorizes two libraries:
pgoutput, test_decoding
After the update, third-party plugins such as wal2json and decoderbufs must be explicitly added to the allowlist. Otherwise, slots that use them will be unable to start logical decoding successfully.
Before installing the patch, administrators can identify the plugins already associated with slots by running:
SELECT DISTINCT plugin
FROM pg_replication_slots
WHERE plugin IS NOT NULL;
The query returns plugins that have been used successfully at least once. It does not necessarily detect every configured integration that has not yet been activated.
After updating PostgreSQL, every legitimate plugin not included in the default value must be added to output_plugin_libraries. The configuration can then be reloaded with:
pg_ctl reload
or:
SELECT pg_reload_conf();
Changing the parameter alone does not require a restart. Any more restrictive distribution-specific instructions, such as the restart required by the Ubuntu update, still apply.
PostgreSQL chose an allowlist rather than simply extending the rules for LOAD. The latter approach would have required all external plugins to be installed under $libdir/plugins, disrupting many existing configurations.
An operational limitation also remains unresolved. pg_createsubscriber creates slots with pgoutput without checking the new parameter: --dry-run may succeed, while the actual operation can fail if the allowlist excludes the plugin. As of September 4, a patch reported by Hayato Kuroda of Fujitsu was still under review.
When migrating from PostgreSQL 17 or a later release, the new cluster's allowlist must also be configured before running:
pg_upgrade --check
Otherwise, the check may fail when existing slots depend on unauthorized plugins.
Immediate Checks, Mitigations, and Indicators to Look For
If the patch cannot be applied immediately, administrators should revoke REPLICATION from accounts without a documented need for it and restrict the addresses authorized for replication connections in pg_hba.conf.
It is also advisable to block outbound SMB traffic on port 445 and NFS traffic on port 2049 from database servers when these protocols are not required. autofs should be disabled on systems that do not use it.
After the update, attempts to load plugins excluded from the allowlist produce a log error containing:
may not be used as an output plugin
The message may indicate a legitimate configuration that has not yet been updated, but it may also signal an attempt to load an unauthorized library. It should therefore be correlated with the account, source address, and requested filename.
The investigation should also cover:
- accounts with the
REPLICATIONattribute; - slots listed in
pg_replication_slots; - plugins associated with those slots;
- unexpected changes to the role catalog;
- new persistence mechanisms created by the database service account;
- anomalous SMB or NFS connections originating from the PostgreSQL server.
Installing a fixed release remains the priority. The allowlist reduces exposure without requiring a complete reorganization of plugins, but it requires an accurate inventory to prevent disruptions to replication and change data capture pipelines.
Sources
This article is an original reworking based on the sources below.
CVEs covered in this article
- CVE-2026-14662HIGH8.8Integer wraparound in PostgreSQL tsvector and tsquery data type functions allows an unprivileged database user to cause the server to undersize an allocation and write out-of-bounds, via crafted large inputs. This may execute arbitrary code as the operating system user running the database. These
- CVE-2026-14664HIGH8.8Heap buffer overflow in PostgreSQL regexp allows the query author to execute arbitrary code as the operating system user running the database, via text that would not pass encoding validation. This shares heritage with CVE-2026-2006, but this case involved unanticipated data growth when round-tripp
- CVE-2026-6464HIGH8.1Untrusted data inclusion in PostgreSQL psql COPY may allow a server administrator to elicit execution of data lines as psql commands, via error injection. If the "COPY FROM STDIN" or "\copy FROM STDIN" command fails before the server indicates that it awaits input rows, psql processes the in-line d
- CVE-2026-6471HIGH7.2Missing authorization in PostgreSQL logical decoding allows a non-superuser holding REPLICATION privilege to dlopen any file visible to the operating system account running the server, via the choice of logical decoding plugin. This in turn runs arbitrary code as that account. Versions before Post
- CVE-2026-14663MEDIUM6.5Cleartext storage in PostgreSQL pgcrypto disabled ciphers allows a user to recover cleartext, via direct observation of the faulty ciphertext. The OpenSSL version and OpenSSL configuration determine the disabled ciphers. If the application accepts encrypted data as input, decryption will succeed e
- CVE-2026-6470MEDIUM4.3Missing authorization in PostgreSQL DDL commands allows an object creator to achieve denial of service against ALTER and DROP of the type, via creating a dependency on the type. Many DDL operations did check the privilege, but assigning a range subtype and referencing the type from an SQL expressio
- CVE-2026-14666MEDIUM4.2Incomplete tracking in PostgreSQL of changes to role membership, role attributes, and database ownership allows a query to continue using cached row-level security policies after those changes require a different policy, via plan reuse. Stale policies continue until some other event invalidates the
- CVE-2026-6469LOW3.8Incorrect ownership assignment in PostgreSQL ALTER TABLE ALTER TYPE command reassigns ownership of dependent statistics objects to the current user. This wrongly allows the table owner to run DROP STATISTICS and ALTER STATISTICS via this improper ownership. It wrongly denies those commands to the
