CVE-2025-1094 in PostgreSQL: when an escape function can allow SQL injection

Published on 2026-10-27 by frfrand

We explain the SQL injection case in PostgreSQL escape functions, precise scope, fixed versions, and mitigations.

CVE-2025-1094 in PostgreSQL: when an escape function can allow SQL injection

The problem no one expected from a security function

In a database we usually trust the functions that prepare special characters for a query. But CVE-2025-1094, fixed in February 2025, showed that even those defenses need context. The problem affected certain escape functions of the libpq client library and PostgreSQL command-line tools. Under specific combinations of inputs and encodings, supposedly prepared text could end up altering a SQL statement.

What is SQL injection and why is it a concern?

SQL injection occurs when external data is interpreted as part of a command sent to the database. Depending on privileges, it can modify records, read information, or alter the behavior of a task. Not all SQL injection grants full control: results depend on what query is built and with which user it is executed.

What exactly did this CVE fix?

The official notice mentions PQescapeLiteral(), PQescapeIdentifier(), PQescapeString() and PQescapeStringConn() in certain situations where the input does not pass encoding validation. For libpq functions, the relevant scenario includes using their result when building inputs for psql, the interactive client. A case was also described in command-line utilities with encoding combinations BIG5 and EUC_TW or MULE_INTERNAL. It is not a defect that affects all parameterized PostgreSQL queries.

Who discovered it and how is a failure like this studied?

The case was documented and fixed through the PostgreSQL security process. To investigate vulnerabilities of this type, one compares how the same string is interpreted in the client, the parser, and the database, especially with invalid characters or unusual encodings. One should not attribute a specific technique or researcher without consulting the official credit of the record.

How can someone take advantage of it?

An attacker needs the application or a script to allow input that ends up in a vulnerable SQL construction. In the described scenario, poorly encoded text can escape the expected quoting rules as it passes through the involved tools. The key point is how the commands are constructed, not just the server version. Without that usage pattern, the presence of a historical version does not demonstrate exploitation.

Which versions were affected?

The vendor identifies branches prior to 17.3, 16.7, 15.11, 14.16 and 13.19 as affected in the February 2025 advisory. Today it is advisable to maintain a branch supported by the project or by a distributor that documents patches; do not install historical versions just because they were the first fix.

How do I know if my application is at risk?

1. Inventory PostgreSQL versions, libpq, tools such as psql and backend client libraries. 2. Identify scripts that concatenate SQL instructions or generate files for psql. 3. Check if user data is admitted in those flows and how encodings are validated. 4. Review database role permissions; never use a superuser account for normal tasks. 5. Confirm with package bulletins if you have backported patches.

How is it fixed?

Apply the relevant update on clients and server when appropriate. Prefer parameterized queries instead of concatenating SQL by hand; avoid building psql commands with untrusted input; and test import and migration processes after the patch. A web WAF does not necessarily see the internal data tasks that cause the exposure.

Quick questions

Does it affect Django? Django usually uses SQL parameters, but auxiliary scripts or custom integrations may use other paths. Investigate actual usage.

Is the database compromised? It cannot be deduced solely from an old version.

Is PostgreSQL 17.x always safe? No: it is necessary to know the subversion and patches.

Sources: Official PostgreSQL Bulletin CVE-2025-1094 · CVE Record.

Where to follow CVE alerts and receive guidance?

At ArduMaker CVE and support we publish updates and centralize inquiries about vulnerabilities, starting with WordPress and its related technologies. If your case involves another runtime or a database, specify component, version, operating system, and service exposure to contextualize it. The notice of a CVE does not prove that your server is compromised: evaluation requires inventory, configuration, and evidence.

Editorial note — October 2026: these corrected versions are the milestones of the original notice. When updating today, choose a branch with active support and check the manufacturer's current announcement.

Practical example: parameters instead of building SQL with text

Situation: a Python API queries PostgreSQL by email. A developer writes a query concatenating what arrives from the form. That is a dangerous anti-pattern, although CVE-2025-1094 refers specifically to escape/libpq functions and certain flows with psql.

Safe pattern with the psycopg driver:

email = request_data["email"]
cursor.execute(
    "SELECT id, nombre FROM clientes WHERE email = %s",
    (email,)
)
cliente = cursor.fetchone()

The driver treats the email as a value, not as SQL. To evaluate the actual CVE, also check the version of libpq and psql, not just SELECT version() on the server.

Before: scripts that interpolate strings to pass them to psql. After: parameters whenever possible, encoding review, client package updates, and minimum permissions for the SQL role.

Why does the example help? It teaches how to eliminate the usual class of concatenation errors, although it does not replace the specific patch for the escape flaw registered by PostgreSQL.

CVE-2025-1094 in PostgreSQL: when an escape function can allow SQL injection
  • PostgreSQL
  • CVE-2025-1094
  • SQL injection
  • Base de datos
  • Seguridad

On ArduMaker

  • PostgreSQL: Install PostgreSQL and manage databases, users and permissions without the command line.

Keep reading

All articles · VPS plans