A recently discovered vulnerability in PostgreSQL, identified as CVE-2025-1094, could potentially allow an attacker to perform SQL injection attacks when specific usage conditions are met. This post will examine the details and implications of this vulnerability, as well as provide code snippets and links to the original references.
Vulnerability Details
The vulnerability exists in the PostgreSQL libpq functions, specifically PQescapeLiteral(), PQescapeIdentifier(), PQescapeString(), and PQescapeStringConn(). These functions are designed to neutralize user input before passing it into a database query, but improper neutralization of quoting syntax in these functions can be exploited by a malicious database input provider to achieve SQL injection. This requires the application to use the resulting output from these functions to construct input for psql, the PostgreSQL interactive terminal.
Moreover, improper neutralization of quoting syntax in PostgreSQL command line utility programs can also lead to SQL injection when the client_encoding is set to BIG5, and the server_encoding is one of EUC_TW or MULE_INTERNAL.
Affected versions include versions before PostgreSQL 17.3, 16.7, 15.11, 14.16, and 13.19.
Code Snippet
/*
* Vulnerable code example: Concatenating the escaped string directly into a SQL query (NOT RECOMMENDED)
*/
const char *escaped_literal = PQescapeLiteral(conn, user_input, user_input_len);
char sql_query[QUERY_BUFSIZE];
snprintf(sql_query, sizeof(sql_query), "SELECT * FROM table WHERE column = %s;", escaped_literal);
/*
* Secure code example: Using parameterized queries with PQexecParams()
*/
const char *paramValues[1] = { user_input };
int paramLengths[1] = { user_input_len };
int paramFormats[1] = { }; // text format
PGresult *res = PQexecParams(conn,
"SELECT * FROM table WHERE column = $1;",
1, // number of parameters
NULL, // types of parameters, NULL if unknown
paramValues, paramLengths, paramFormats,
); // result format = text
The above code snippet demonstrates a vulnerable code example where the escaped string is concatenated directly into a SQL query (not recommended), as well as a secure code example using parameterized queries with PQexecParams().
Links to Original References
- CVE-2025-1094: SQL Injection in PostgreSQL libpq Functions and Command Line Utility Programs
- PostgreSQL Security Alert: SQL Injection in libpq and CLI utility programs
- Official PostgreSQL Documentation
Mitigation and Recommendations
Users running affected versions of PostgreSQL are advised to update their installations to the latest versions, specifically version 17.3, 16.7, 15.11, 14.16, or 13.19, which contain patches addressing this vulnerability. Additionally, developers should consider using a secure coding approach, such as parameterized queries with the PQexecParams() function, to help protect against SQL injection attacks.
Timeline
Published on: 02/13/2025 13:15:09 UTC
Last modified on: 02/13/2025 22:15:11 UTC