Someone handed the valet a car key but the valet can now also unlock the house, the safe, and the garage
CVE-2026-6471, nicknamed PostGREShell, is a missing-authorization flaw in PostgreSQL's logical decoding subsystem that has existed since 2014. Any database user holding the REPLICATION privilege — commonly granted to backup tools (pgBackRest, Barman), CDC pipelines (Debezium), monitoring agents, and read-replica configurations — can specify an arbitrary shared library as a logical decoding output plugin. PostgreSQL's server process calls dlopen() on that path without verifying it is a legitimate plugin, executing the library's init code as the postgres OS user. The result is full remote code execution on the database host. Affected versions span all supported branches: PostgreSQL 14.x < 14.24, 15.x < 15.19, 16.x < 16.15, 17.x < 17.11, and 18.x < 18.6.
The vendor rates this HIGH / 7.2 with PR:H (high privileges required), and that score is directionally correct — the REPLICATION privilege is a real gate. However, in enterprise deployments, REPLICATION credentials proliferate across service accounts for backups, streaming replicas, and event-driven architectures. Those credentials are the softest target in most PostgreSQL estates. When you factor in that PostgreSQL almost always sits on a production data tier — hosting PII, financial records, or regulated data — the blast radius of a single successful exploit is severe: full data exfiltration plus persistent backdoor. The vendor's 7.2 is fair but slightly conservative for organizations running PostgreSQL as their primary OLTP engine.
4 steps from start to impact.
Obtain REPLICATION credentials
REPLICATION privilege. Common sources include compromised CI/CD secrets, exposed .pgpass files, credential stuffing against service accounts, or insider access. Backup and CDC tooling accounts are prime targets because they are rarely rotated and often use password-based authentication.- Valid credentials for a REPLICATION-privileged role
- Network access to the PostgreSQL port (default 5432)
- REPLICATION is PR:H — not every database user has it
- Well-run shops store replication creds in vaults (HashiCorp Vault, AWS Secrets Manager) with rotation
- Network segmentation typically limits 5432 to application and ops subnets
pg_log with log_connections = on. Anomalous source IPs connecting with replication roles can be flagged by SIEM correlation.Stage a malicious shared library on the target host
.so file on the PostgreSQL server's filesystem. This can be achieved by uploading via COPY TO (if the role also has table access), exploiting a writable NFS/SMB share, or leveraging an existing library already present on the system (e.g., a UDF library or system .so with useful gadgets). The file must be readable by the postgres OS user.- Write access to some filesystem path visible to the postgres OS user, OR knowledge of a useful existing .so
- Many hardened deployments run PostgreSQL in containers or with read-only root filesystems
- SELinux/AppArmor policies can block dlopen of files outside PostgreSQL's lib directory
- Cloud-managed PostgreSQL (RDS, Cloud SQL, Azure Database) does not expose the OS filesystem at all
auditd rules on dlopen syscalls from the postgres process.Create a logical replication slot with the malicious plugin
SELECT pg_create_logical_replication_slot('pwned', '/path/to/evil.so'); via the replication protocol or a standard SQL connection. PostgreSQL calls dlopen() on the specified path, executing the library's _PG_output_plugin_init() function — or any constructor — as the postgres OS user. No further interaction is needed.- Successful steps 1 and 2
- PostgreSQL
wal_levelset tological(required for logical decoding)
wal_level = logicalis not the default on vanilla installs; it must be explicitly configured- Some deployments restrict
CREATE_REPLICATION_SLOTviapg_hba.confreplication entries
log_replication_commands = on. Unexpected slot names or plugin paths are high-fidelity IOCs.Achieve persistent OS-level access and data exfiltration
postgres user, the attacker can read all database files directly, install a persistent backdoor (cron job, modified postgresql.conf to load a malicious shared_preload_libraries), dump credentials, and pivot laterally. On a production data tier, this means full access to every row in every database on that cluster.- Successful step 3
- EDR on the database host should detect anomalous child processes from postgres
- Network monitoring can detect unexpected egress from database subnets
postgres process. Database audit logging (pgAudit) for anomalous superuser activity after privilege escalation.The supporting signals.
| In-the-Wild Status | Exploitation attempts detected per security monitoring reports, but no confirmed large-scale campaigns. Not yet on CISA KEV. |
|---|---|
| Proof of Concept | No public PoC found on GitHub or Exploit-DB as of 2026-09-05. The exploitation technique is straightforward for anyone who understands dlopen() and logical replication — weaponization is trivial once understood. |
| EPSS | 0.00285 (~70th percentile) — low predicted exploitation probability, likely because PR:H limits automated scanning viability. |
| KEV Status | Not listed as of 2026-09-05. |
| CVSS Vector | CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H — network-reachable, low complexity, but high privilege required. Scope unchanged means impact stays on the vulnerable component (the database host). |
| Affected Versions | All PostgreSQL branches from 9.4 (2014) through 18.5, spanning a 12-year window. Supported affected branches: 14.x, 15.x, 16.x, 17.x, 18.x. |
| Fixed Versions | 14.24, 15.19, 16.15, 17.11, 18.6 — all released 2026-08-13. Distro backports: RHEL/CentOS, Ubuntu, Debian, SUSE all have updates available. |
| Exposure Data | Shodan indexes ~1.3 million PostgreSQL instances on port 5432 globally. Most enterprise deployments are internal-only, but cloud misconfigurations regularly expose databases. EU alone: ~185K exposed instances (Shodan). |
| Disclosure Date | 2026-08-13 — coordinated disclosure with patch release. |
| Reporter | Discovered by Cyera research team. |
noisgate verdict.
PostgreSQL is canonically a production data-tier component; successful exploitation yields OS-level RCE and full data access on the cluster, making the role multiplier on production databases the single most decisive factor sustaining the HIGH verdict. The PR:H requirement (REPLICATION privilege) provides genuine friction that prevents escalation to CRITICAL, but replication credentials are widely distributed across backup and CDC service accounts in enterprise estates, keeping severity firmly in the HIGH band.
Why this verdict
- PR:H is real but soft friction. The REPLICATION privilege is a genuine gate — not every database user has it. However, in practice, backup tools (pgBackRest, Barman), CDC pipelines (Debezium, Kafka Connect), and streaming replicas all require REPLICATION-privileged service accounts. These credentials are the most commonly shared and least frequently rotated secrets in a PostgreSQL estate.
- Role multiplier: production database engine. PostgreSQL is explicitly a high-value-role component. The majority of PostgreSQL installations serve production workloads holding PII, financial, or regulated data. RCE on the database host = mass data egress from that cluster. This floors the verdict at HIGH regardless of friction.
- 12-year attack surface amplifies exposure. Every supported PostgreSQL branch back to 14.x (and unsupported branches back to 9.4) is vulnerable. Organizations running any unpatched version since 2014 are affected, making the population enormous.
- No public PoC tempers urgency — but barely. The absence of a GitHub PoC and low EPSS (0.00285) reduce the immediacy of mass exploitation. However, the technique is conceptually simple (call
pg_create_logical_replication_slotwith a crafted library path), and skilled adversaries do not need a public PoC.
Why not higher?
A CRITICAL rating would require either active KEV listing, a public weaponized exploit enabling mass automated exploitation, or unauthenticated access. This CVE requires high privileges (REPLICATION), the target database must have wal_level = logical configured, and the attacker needs a way to stage a malicious .so on the host filesystem. Cloud-managed PostgreSQL (RDS, Cloud SQL, Azure Database for PostgreSQL) is not exploitable because users have no OS filesystem access, which eliminates a large fraction of the global PostgreSQL population from the vulnerable pool.
Why not lower?
Downgrading to MEDIUM would ignore that PostgreSQL is a canonical production data-tier component where successful exploitation yields OS-level RCE and full cluster data access. The REPLICATION privilege, while PR:H, is routinely granted to multiple service accounts per cluster. The 12-year vulnerability window means virtually every on-premises PostgreSQL installation is affected. Exploitation attempts have already been detected in the wild.
What to do — in priority order.
- Audit and restrict REPLICATION privilege grants immediately — Run
SELECT rolname FROM pg_roles WHERE rolreplication = true;on every cluster. Revoke REPLICATION from any role that does not strictly require it. This directly eliminates the attack prerequisite. Deploy within 30 days per the noisgate mitigation SLA for HIGH. - Set
output_plugin_librarieson patched versions — The patch introduces a new GUCoutput_plugin_librariesthat whitelists permitted logical decoding plugins. After upgrading, configure this parameter to restrict dlopen targets to only your approved plugins (e.g.,pgoutput,wal2json). This is defense-in-depth even after patching. - Restrict replication connections in pg_hba.conf — Ensure
pg_hba.confreplication entries usehostssl(nothost), restrict source CIDR to specific replica/backup IPs only, and require certificate-based authentication instead of password. This limits who can even attempt the exploit. - Enable SELinux/AppArmor confinement for postgres — Configure mandatory access control policies to prevent the postgres process from calling
dlopen()on files outside/usr/lib/postgresql/*/lib/. This blocks step 2 of the attack path even if the attacker has REPLICATION credentials. - Enable replication command logging — Set
log_replication_commands = onand forward logs to SIEM. Alert onCREATE_REPLICATION_SLOTcommands with non-standard plugin names. This provides high-fidelity detection of exploitation attempts.
- Network firewalling alone — if the attacker has compromised an application server in the same subnet (the most common attacker position for database attacks), firewall rules between the app tier and database tier will not help.
- Cloud-managed PostgreSQL WAF/proxy — services like RDS, Cloud SQL, and Azure Database for PostgreSQL are not vulnerable because users cannot access the OS filesystem. Do not waste cycles patching managed services; focus on self-hosted instances.
- Row-level security (RLS) — RLS controls SQL-level data access. This CVE bypasses SQL entirely by executing OS-level code via dlopen, making RLS irrelevant.
Crowdsourced verification payload.
Run this script on each PostgreSQL host as any user who can connect to the database (e.g., postgres). Invoke with: bash check_cve_2026_6471.sh. Requires psql in PATH and the ability to connect to the local PostgreSQL instance (peer auth or password via .pgpass/PGPASSWORD).
#!/usr/bin/env bash
# check_cve_2026_6471.sh — Detect CVE-2026-6471 (PostGREShell)
# Checks PostgreSQL server version against patched releases.
# Exit codes: 1=VULNERABLE, 0=PATCHED, 2=UNKNOWN
set -euo pipefail
VERSION=$(psql -tAc "SHOW server_version;" 2>/dev/null || echo "")
if [ -z "$VERSION" ]; then
echo "UNKNOWN — could not connect to PostgreSQL"
exit 2
fi
MAJOR=$(echo "$VERSION" | cut -d. -f1)
MINOR=$(echo "$VERSION" | cut -d. -f2)
echo "Detected PostgreSQL version: $VERSION"
# Check against fixed versions: 14.24, 15.19, 16.15, 17.11, 18.6
case "$MAJOR" in
14) FIXED_MINOR=24 ;;
15) FIXED_MINOR=19 ;;
16) FIXED_MINOR=15 ;;
17) FIXED_MINOR=11 ;;
18) FIXED_MINOR=6 ;;
19) echo "PATCHED — PostgreSQL $VERSION (19.x includes the fix)"; exit 0 ;;
*)
if [ "$MAJOR" -lt 14 ]; then
echo "VULNERABLE — PostgreSQL $VERSION is end-of-life and affected"
exit 1
fi
echo "UNKNOWN — unrecognized major version $MAJOR"
exit 2
;;
esac
if [ "$MINOR" -ge "$FIXED_MINOR" ]; then
echo "PATCHED — PostgreSQL $VERSION (fixed in $MAJOR.$FIXED_MINOR)"
exit 0
else
echo "VULNERABLE — PostgreSQL $VERSION (update to $MAJOR.$FIXED_MINOR+)"
# Bonus: check for replication users as risk indicator
REPL_USERS=$(psql -tAc "SELECT count(*) FROM pg_roles WHERE rolreplication = true;" 2>/dev/null || echo "?")
echo " Replication-privileged roles on this cluster: $REPL_USERS"
WAL_LEVEL=$(psql -tAc "SHOW wal_level;" 2>/dev/null || echo "?")
echo " wal_level: $WAL_LEVEL (logical = exploitable, replica/minimal = reduced risk)"
exit 1
fiIf you remember one thing.
wal_level = logical and active REPLICATION-privileged roles as highest priority. Per the noisgate mitigation SLA for HIGH, deploy compensating controls (revoke unnecessary REPLICATION grants, lock down pg_hba.conf replication entries to specific IPs with cert auth) within 30 days. Per the noisgate remediation SLA, complete patching to 14.24 / 15.19 / 16.15 / 17.11 / 18.6 within 180 days, prioritizing production OLTP clusters and any instance holding regulated data. If you detect exploitation attempts in replication command logs, escalate to incident response immediately — the absence of a public PoC does not mean sophisticated adversaries aren't already leveraging this 12-year-old attack surface.Sources
- PostgreSQL Official Advisory — CVE-2026-6471
- PostgreSQL 18.6, 17.11, 16.15, 15.19, 14.24 Release Announcement
- SecurityAffairs — PostGREShell 12-Year-Old PostgreSQL Vulnerability
- SUSE Security — CVE-2026-6471
- TheHackerWire — CVE-2026-6471 High Vulnerability
- News4Hackers — Critical PostgreSQL Vulnerability Exploited
- DevGuard — ALPINE-CVE-2026-6471
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.