CVE-2020-14350 Overview
CVE-2020-14350 is a privilege escalation vulnerability in PostgreSQL caused by unsafe use of search_path in extension installation scripts. An attacker with sufficient database privileges can create objects in a schema that gets resolved during extension installation or update. When an administrator runs CREATE EXTENSION or ALTER EXTENSION ... UPDATE, the attacker's malicious objects execute with the administrator's privileges. The flaw affects PostgreSQL versions before 12.4, 11.9, 10.14, 9.6.19, and 9.5.23. The vulnerability is categorized as Untrusted Search Path [CWE-426].
Critical Impact
A low-privileged database user can escalate to superuser by hijacking extension installation scripts, leading to full database compromise.
Affected Products
- PostgreSQL versions before 12.4, 11.9, 10.14, 9.6.19, and 9.5.23
- Debian Linux 9, openSUSE Leap 15.1 and 15.2
- Canonical Ubuntu Linux 16.04 ESM, 18.04 LTS, and 20.04 LTS
Discovery Timeline
- 2020-08-24 - CVE-2020-14350 published to NVD
- 2024-11-21 - Last updated in NVD database
Technical Details for CVE-2020-14350
Vulnerability Analysis
PostgreSQL extensions are installed using SQL scripts that create functions, operators, and other database objects. These scripts run with the privileges of the user invoking CREATE EXTENSION or ALTER EXTENSION ... UPDATE, which is typically a superuser. The vulnerability stems from extension scripts referencing objects without fully qualifying their schema. PostgreSQL resolves these references using the current search_path, which can include schemas writable by lower-privileged users.
An attacker with CREATE privilege on any schema in the search_path can pre-create functions, operators, or types with names that match those referenced by an extension script. When the administrator installs or updates the extension, PostgreSQL resolves the unqualified references to the attacker-controlled objects. The attacker's code then executes in the security context of the installing superuser.
Root Cause
The root cause is improper schema qualification in installation scripts shipped with several built-in PostgreSQL extensions. Object references in .sql extension scripts relied on search_path resolution rather than explicit schema names. Combined with PostgreSQL's default search_path of "$user", public, this allowed shadowing of legitimate objects by attacker-controlled equivalents in schemas the attacker could write to.
Attack Vector
Exploitation requires local authenticated access to the database with privileges to create objects in a schema referenced by search_path. The attacker creates malicious functions or operators that mimic those used internally by the targeted extension. The attacker then waits for or socially engineers an administrator into running CREATE EXTENSION or ALTER EXTENSION ... UPDATE. When the administrator executes the installation, the attacker's objects are invoked with superuser privileges, granting arbitrary SQL execution and full database takeover.
No public proof-of-concept exploit code is available for this issue. Technical details are described in the Red Hat Bug Report #1865746 and the PostgreSQL community advisory.
Detection Methods for CVE-2020-14350
Indicators of Compromise
- Unexpected functions, operators, or types created in public or other writable schemas by non-administrative users prior to extension installation
- Audit log entries showing CREATE FUNCTION or CREATE OPERATOR activity by low-privileged users followed by superuser CREATE EXTENSION or ALTER EXTENSION operations
- New superuser roles, altered pg_authid entries, or unexplained changes to security-relevant catalog tables after an extension install or update
Detection Strategies
- Enable pgaudit or PostgreSQL statement logging and review CREATE EXTENSION and ALTER EXTENSION ... UPDATE events for the surrounding object-creation activity by other roles
- Inspect the contents of public and user-writable schemas for functions whose names collide with internal extension routines
- Compare PostgreSQL package versions against the fixed releases (12.4, 11.9, 10.14, 9.6.19, 9.5.23) using vulnerability management tooling
Monitoring Recommendations
- Forward PostgreSQL audit logs to a centralized analytics platform and alert on extension lifecycle commands executed by superuser accounts
- Monitor catalog tables pg_proc, pg_operator, and pg_extension for unexpected modifications correlated with privileged sessions
- Track package inventory across Debian, Ubuntu, and openSUSE hosts to identify PostgreSQL installations still running unpatched versions
How to Mitigate CVE-2020-14350
Immediate Actions Required
- Upgrade PostgreSQL to version 12.4, 11.9, 10.14, 9.6.19, 9.5.23, or later as appropriate for the deployed major version
- Apply distribution-specific updates from Ubuntu USN-4472-1, Debian LTS, Gentoo GLSA 202008-13, and the openSUSE security announcements
- Audit existing databases for suspicious user-created objects in schemas reachable via the default search_path
Patch Information
The PostgreSQL project addressed CVE-2020-14350 by updating affected extension installation scripts to fully qualify schema references and by hardening search_path handling during extension operations. Fixed versions are 12.4, 11.9, 10.14, 9.6.19, and 9.5.23. Vendor advisories include the NetApp Security Advisory ntap-20200918-0002 and the Red Hat Bug Report #1865746.
Workarounds
- Revoke CREATE privilege on the public schema from PUBLIC using REVOKE CREATE ON SCHEMA public FROM PUBLIC to prevent unprivileged users from planting malicious objects
- Set a restrictive search_path for superuser sessions before installing extensions, for example SET search_path = pg_catalog, pg_temp followed by the extension command
- Restrict CREATE EXTENSION and ALTER EXTENSION operations to trusted administrative sessions on hosts where no untrusted database users exist
# Configuration example: harden PostgreSQL against search_path hijacking
REVOKE CREATE ON SCHEMA public FROM PUBLIC;
ALTER DATABASE mydb SET search_path = "$user", pg_catalog;
-- Before installing or updating an extension as superuser:
SET search_path = pg_catalog, pg_temp;
CREATE EXTENSION myextension;
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

