Skip to content

GHSA-7qpv-r5mr-78m4 on CTRL-OS 26.05

Aliases: GHSA-7qpv-r5mr-78m4, CVE-2026-17543

Packages: php

Status: Plausible

Advisory Information

php_pgsql_convert() is used to convert and escape user-provided parameters in pg_insert(), pg_update(), pg_select(), and pg_delete(). It does so using PQescapeStringConn() and then wraps the result in an escape string constant, E'...' (via php_pgsql_add_quotes()).

https://github.com/php/php-src/blob/cbc0489126a7682796aad1e5fb4e51de74af162c/ext/pgsql/pgsql.c#L4751-L4757

With standard_conforming_strings = on (the default since PostgreSQL 9.1), PQescapeStringConn() does not correctly escape values for the escape string constant E'...', as it does not escape \ under this configuration. When PQescapeStringConn() escapes ' as '', an attacker can trivially terminate the string by escaping the first single quote.

$result = pg_select($db, 'user', ['name' => "zzz\\' OR 1=1 --"]);
// SELECT * FROM "user" WHERE "name"='zzz\'' OR 1=1 --';
var_dump($result); // returned all rows

Note that the doubled \\ is a PHP escape sequence and that the \ appears only once in the parameter. Also note that pg_select() escapes the ' by doubling it but does not escape the \. Consequently, the first of the two ' characters is escaped (meaning that it represents a literal '), while the second terminates the string. Everything after that is interpreted as part of the query.

The solution changes php_pgsql_convert() to wrap parameters in non-escaping string constants instead.

Updates

2026-07-30 18:10 CEST

Metadata changes:

  • Status for package php: “Plausible

(Amended on: 2026-07-30 18:11 CEST)

2026-07-30 17:57 CEST

Metadata changes:

  • Status for package php: “New