Fluxtail
Database security

PostgreSQL CVE-2026-6460: Type Confusion and the Running Fix

Understand PostgreSQL CVE-2026-6460, required object-creation access, fixed versions and checks that distinguish running patches from recovery logs.

By Fluxtail Engineering

PostgreSQL is an open-source database that applications use to store and query data. It supports transactions, data-integrity controls and custom data types. That last capability matters to CVE-2026-6460: a flaw in how the database tracks values when type definitions change. PostgreSQL’s overview explains these capabilities.

Security researcher Mehmet Ince published an account dated November 9, 2026 describing how he turned this type confusion into code execution. His example involved a composite type—a value containing several named fields. After a field’s type changed, an old value could be read using the new layout. The same stored bytes could then be treated as something different, including a memory address. Ince describes the underlying primitive as 22 years old. That historical characterization and the demonstrated exploit come from his original research.

The PostgreSQL advisory confirms a core-server vulnerability that lets an object creator execute code as the operating-system account running PostgreSQL. Exploitation requires database access with sufficient object-creation privileges; this is not an unauthenticated attack merely because a database port is reachable. Successful exploitation could expose or alter data and disrupt service. It does not automatically give the attacker operating-system root privileges.

PostgreSQL published fixes on November 12 for the affected release branches listed below. The advisory establishes the vulnerability and fixes, but does not establish attacks in the wild or identify compromised customers. A managed service’s exposure and patch completion require evidence from that provider and the actual deployment.

CVE-2026-6460 fixed versions

The November 12 release announcement includes these fixes:

PostgreSQL branch Affected upstream releases First fixed release
18 Before 18.7 18.7
17 Before 17.12 17.12
16 Before 16.16 16.16
15 Before 15.20 15.20
14 Before 14.25 14.25

These are upstream release numbers. A distribution or database provider may supply a backported fix under a different package or build identifier. Match that build to its security advisory rather than guessing from the version string alone.

An older branch’s absence from this table does not establish safety. The release announcement also identifies 14.25 as PostgreSQL 14’s final release. Apply the applicable fix and plan migration away from an unsupported branch. The same announcement covers other vulnerabilities and additional update requirements, so read its updating guidance before scheduling maintenance.

How to verify your PostgreSQL servers

These checks apply to operators of potentially affected self-managed and managed deployments. They help separate three questions: which accounts have relevant access, which servers are running a fix, and whether applications recovered after maintenance. They do not determine whether exploitation occurred.

Inventory endpoints and object-creation access

List application database endpoints, direct administrative endpoints, replicas and failover targets. Include databases used by migration jobs and development tools when they share production infrastructure.

Review which accounts can create database objects, including access inherited through role membership. Include migration and tenant accounts rather than checking only the main application login. Avoid testing exposure by running exploit SQL or changing type definitions.

Use one worksheet row per server you can identify:

Endpoint Actual server identity Observed server version Package or provider advisory Applicable fix Verification time, UTC Remaining uncertainty
Application endpoint Record connected address and provider/node identifier Record query result Record installed build and advisory Record matching fixed release or backport Record check time Note unverified replicas or proxy routing

Keep passwords and credential-bearing connection strings out of the worksheet.

Check the connected server

Run this read-only SQL through an existing authorized database connection:

SELECT version() AS server_build,
       inet_server_addr() AS accepted_address,
       inet_server_port() AS accepted_port,
       current_database() AS database_name;

SHOW server_version_num;

These functions report the connected server’s build, the address and port where it accepted the connection, and the current database. Address and port are NULL for a Unix-domain socket connection. server_version_num provides a machine-readable version value. See the official system-information reference.

Compare the result with the applicable fixed release or documented backport. A local client version identifies the client. An installed-package record identifies files on disk. Neither alone establishes which server build is handling the connection.

One connection also does not inventory every replica or server behind a proxy. Use your deployment inventory or provider’s node information to cover each target. After maintenance, open a fresh connection and repeat the check. Record any server that remains unverified instead of marking the entire deployment complete.

Correlate restart and application recovery records

Use existing database and application logs to establish what happened around the maintenance window. The following is a synthetic UTC timeline, written to illustrate interpretation rather than reproduce PostgreSQL’s exact log format:

2026-11-13T07:20:00Z host=db-a service=postgresql event=shutdown_complete
2026-11-13T07:20:03Z host=api-a service=checkout-api event=db_connection_failed
2026-11-13T07:20:11Z host=db-a service=postgresql event=ready_for_connections
2026-11-13T07:20:14Z host=api-a service=checkout-api event=db_connection_restored

This sequence places a connection failure between shutdown and readiness, followed by an application reconnect. It does not show which binary started or prove that every application recovered. Pair the timeline with the server-version worksheet and your normal application health checks.

For records already collected in Fluxtail, open the database stream and select a bounded interval, such as 07:15–07:30 UTC. Filter by the database host and service, then inspect message text around shutdown and readiness. Repeat in the application stream for connection failures and recovery. Fluxtail’s log management supports streams and host, service and message filters. First inspect actual rows to confirm those fields survived collection; the synthetic event names above are not prescribed search syntax.

If reconnect failures persist, investigate their specific errors. Connection-limit failures need a separate check of pools and deployment overlap; see Postgres too many connections. For building a bounded timeline across sources, see how to read logs.

Keep patch evidence separate from compromise findings

Record the running-server check and recovery observations separately. A fixed server version answers a patch question. Readiness and reconnect records answer narrower availability questions.

Neither a successful update nor an empty log search proves that exploitation never occurred. Missing records may reflect collection gaps, retention or activity that was never logged. If you find unexplained database changes or host activity, preserve the available evidence and investigate it separately. Do not treat an ordinary restart or connection error as a CVE-specific detection.