Skip to main content
CVE Vulnerability Database

CVE-2026-2004: PostgreSQL intarray Extension RCE Flaw

CVE-2026-2004 is a remote code execution vulnerability in PostgreSQL's intarray extension that allows attackers to execute arbitrary code as the database user. This article covers technical details, affected versions, and mitigation.

Updated:

CVE-2026-2004 Overview

CVE-2026-2004 is an input validation flaw in the PostgreSQL intarray extension's selectivity estimator function. The function fails to validate the type of input it receives, allowing an authenticated database user who can create objects to execute arbitrary code as the operating system user running the PostgreSQL service. The flaw is tracked under CWE-1287: Improper Validation of Specified Type of Input. PostgreSQL versions prior to 18.2, 17.8, 16.12, 15.16, and 14.21 are affected.

Critical Impact

An authenticated object creator can achieve code execution as the PostgreSQL operating system account, leading to full compromise of the database host and any data it stores.

Affected Products

  • PostgreSQL versions before 18.2
  • PostgreSQL versions before 17.8, 16.12, and 15.16
  • PostgreSQL versions before 14.21 (with the intarray extension enabled)

Discovery Timeline

  • 2026-02-12 - CVE-2026-2004 published to NVD
  • 2026-02-20 - Last updated in NVD database

Technical Details for CVE-2026-2004

Vulnerability Analysis

The intarray contrib extension provides functions, operators, and index support for working with arrays of integers in PostgreSQL. Selectivity estimator functions are used by the query planner to estimate the number of rows that will match a given operator expression. PostgreSQL invokes these estimators automatically during query planning, including when planning queries that touch user-created objects.

The vulnerable estimator function in intarray does not verify that the inputs passed by the planner match the expected SQL types. An object creator can construct an operator, index, or expression that causes the estimator to be invoked with crafted arguments. Mishandling those arguments causes the function to dereference attacker-controlled values, which in PostgreSQL's C-level execution model translates into arbitrary code execution inside the backend process.

Because backends run as the operating system account that owns the PostgreSQL service (commonly postgres), successful exploitation gives the attacker that account's privileges on the database host, including read and write access to all cluster data files.

Root Cause

The root cause is missing input type validation [CWE-1287] in the intarray selectivity estimator. The function trusts that callers supply arguments of the declared type rather than re-validating them at entry, which is unsafe when an object creator can influence how the estimator is invoked.

Attack Vector

Exploitation requires network reachability to the PostgreSQL instance and an authenticated role with permission to create objects (such as tables, operators, or expression indexes) within a database where intarray is installed. The attacker defines an object whose planning triggers the vulnerable estimator with type-confused inputs, and the resulting code runs in the backend process as the PostgreSQL OS user.

No verified public proof-of-concept exploit is currently available. Refer to the PostgreSQL Security Advisory CVE-2026-2004 for vendor-supplied technical details.

Detection Methods for CVE-2026-2004

Indicators of Compromise

  • Unexpected child processes spawned by the postgres backend process, particularly shells or scripting interpreters.
  • New or modified files under the PostgreSQL data directory or the home directory of the postgres OS account.
  • Outbound network connections originating from the database server to untrusted hosts.
  • Recent creation of operators, expression indexes, or custom types referencing intarray functions by non-administrative roles.

Detection Strategies

  • Audit PostgreSQL server logs for CREATE OPERATOR, CREATE INDEX, and CREATE TYPE statements issued by non-privileged roles in databases where intarray is installed.
  • Enable the pgaudit extension to capture DDL events and function definitions performed by object creators.
  • Monitor execution of \dx intarray and queries against pg_extension to inventory where the extension is enabled.

Monitoring Recommendations

  • Alert on process lineage where postgres spawns non-database binaries such as sh, bash, python, or curl.
  • Track file integrity on the PostgreSQL binary directory and data directory to detect tampering.
  • Forward database and host telemetry to a centralized analytics platform for correlation across query activity and host-level behavior.

How to Mitigate CVE-2026-2004

Immediate Actions Required

  • Upgrade PostgreSQL to version 18.2, 17.8, 16.12, 15.16, or 14.21 or later, matching your current major version.
  • Inventory all databases for the intarray extension and prioritize upgrades on instances where it is installed.
  • Review and reduce the set of roles that hold CREATE privileges on databases and schemas exposed to untrusted users.
  • Rotate credentials for any database role suspected of being used to test or exploit the flaw.

Patch Information

The PostgreSQL Global Development Group released fixed builds in versions 18.2, 17.8, 16.12, 15.16, and 14.21. Refer to the PostgreSQL Security Advisory CVE-2026-2004 for the full list of supported branches and download links. Apply the patch using your distribution's package manager or by upgrading from official PostgreSQL packages, then restart the database service.

Workarounds

  • If patching cannot be performed immediately, drop the intarray extension with DROP EXTENSION intarray in databases where it is not required.
  • Revoke object creation privileges from untrusted roles, including REVOKE CREATE ON SCHEMA public FROM PUBLIC on shared schemas.
  • Restrict network access to the PostgreSQL port using firewall rules or host-based authentication entries in pg_hba.conf.
bash
# Configuration example
# Identify databases with intarray installed
psql -At -c "SELECT datname FROM pg_database WHERE datallowconn;" \
  | while read db; do
      psql -d "$db" -At -c \
        "SELECT current_database() WHERE EXISTS (SELECT 1 FROM pg_extension WHERE extname='intarray');"
    done

# Remove the extension where it is not needed
psql -d <database> -c "DROP EXTENSION IF EXISTS intarray;"

# Reduce object creation privileges on shared schemas
psql -d <database> -c "REVOKE CREATE ON SCHEMA public FROM PUBLIC;"

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.