From 3a212752512f00930129e5bd096f9a00c8098afe Mon Sep 17 00:00:00 2001 From: pkgagent Date: Fri, 31 Jul 2026 18:04:52 +0800 Subject: [PATCH] Fix CVE-2026-17543: SQL injection in ext-pgsql via E'...' backslash breakout --- php-8.3.31-CVE-2026-17543.patch | 216 ++++++++++++++++++++++++++++++++ php.spec | 7 +- 2 files changed, 222 insertions(+), 1 deletion(-) create mode 100644 php-8.3.31-CVE-2026-17543.patch diff --git a/php-8.3.31-CVE-2026-17543.patch b/php-8.3.31-CVE-2026-17543.patch new file mode 100644 index 0000000..e123e4b --- /dev/null +++ b/php-8.3.31-CVE-2026-17543.patch @@ -0,0 +1,216 @@ +From ab048bd83b578119cf81b456526d50498421d617 Mon Sep 17 00:00:00 2001 +From: Ilija Tovilo +Date: Mon, 27 Jul 2026 16:49:38 +0200 +Subject: [PATCH] Fix SQL injection in ext-pgsql via E'...' backslash breakout + +php_pgsql_add_quotes() quotes the string with E'...', but PQescapeStringConn() +does not escape \ unless standard_conforming_strings is off. +PQescapeStringConn() is meant to be used with '', so do that instead. + +Fixes GHSA-7qpv-r5mr-78m4 +--- + ext/pgsql/pgsql.c | 3 +- + ext/pgsql/tests/10pg_convert_9.phpt | 18 +++++- + ext/pgsql/tests/10pg_convert_json_array.phpt | 4 +- + ext/pgsql/tests/12pg_insert_9.phpt | 2 +- + ext/pgsql/tests/14pg_update_9.phpt | 2 +- + ext/pgsql/tests/GHSA-7qpv-r5mr-78m4.phpt | 58 ++++++++++++++++++++ + ext/pgsql/tests/bug64609.phpt | 2 +- + ext/pgsql/tests/bug68638.phpt | 2 +- + 8 files changed, 81 insertions(+), 10 deletions(-) + create mode 100644 ext/pgsql/tests/GHSA-7qpv-r5mr-78m4.phpt +diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c +index 96a3cc7e..115c6997 100644 +--- a/ext/pgsql/pgsql.c ++++ b/ext/pgsql/pgsql.c +@@ -4561,7 +4561,7 @@ static int php_pgsql_convert_match(const zend_string *str, const char *regex , s + */ + static zend_string *php_pgsql_add_quotes(zend_string *src) + { +- return zend_string_concat3("E'", strlen("E'"), ZSTR_VAL(src), ZSTR_LEN(src), "'", strlen("'")); ++ return zend_string_concat3("'", strlen("'"), ZSTR_VAL(src), ZSTR_LEN(src), "'", strlen("'")); + } + /* }}} */ + +@@ -4838,7 +4838,6 @@ PHP_PGSQL_API zend_result php_pgsql_convert(PGconn *pg_link, const zend_string * + zend_string *str; + /* PostgreSQL ignores \0 */ + str = zend_string_alloc(Z_STRLEN_P(val) * 2, 0); +- /* better to use PGSQLescapeLiteral since PGescapeStringConn does not handle special \ */ + ZSTR_LEN(str) = PQescapeStringConn(pg_link, ZSTR_VAL(str), + Z_STRVAL_P(val), Z_STRLEN_P(val), &escape_err); + if (escape_err) { +diff --git a/ext/pgsql/tests/10pg_convert_9.phpt b/ext/pgsql/tests/10pg_convert_9.phpt +index f4bfaf5e..fb36e580 100644 +--- a/ext/pgsql/tests/10pg_convert_9.phpt ++++ b/ext/pgsql/tests/10pg_convert_9.phpt +@@ -21,6 +21,8 @@ + + var_dump($converted); + ++var_dump(pg_convert($db, $table_name, ['str' => "\\' OR 1=1"])); ++ + /* Invalid values */ + try { + $converted = pg_convert($db, $table_name, [5 => 'AAA']); +@@ -48,18 +50,30 @@ + } catch (\TypeError $e) { + echo $e->getMessage(), \PHP_EOL; + } ++ ++/* standard_conforming_strings = 1 */ ++pg_query($db, "SET standard_conforming_strings = 1"); ++var_dump(pg_convert($db, $table_name, ['str' => "\\' OR 1=1"])); + ?> + --EXPECT-- + array(3) { + [""num""]=> + string(4) "1234" + [""str""]=> +- string(6) "E'AAA'" ++ string(5) "'AAA'" + [""bin""]=> +- string(12) "E'\\x424242'" ++ string(11) "'\\x424242'" ++} ++array(1) { ++ [""str""]=> ++ string(13) "'\\'' OR 1=1'" + } + Array of values must be an associative array with string keys + Array of values must be an associative array with string keys + Values must be of type string|int|float|bool|null, array given + Values must be of type string|int|float|bool|null, stdClass given + Values must be of type string|int|float|bool|null, PgSql\Connection given ++array(1) { ++ [""str""]=> ++ string(12) "'\'' OR 1=1'" ++} +diff --git a/ext/pgsql/tests/10pg_convert_json_array.phpt b/ext/pgsql/tests/10pg_convert_json_array.phpt +index 918765db..5353e04d 100644 +--- a/ext/pgsql/tests/10pg_convert_json_array.phpt ++++ b/ext/pgsql/tests/10pg_convert_json_array.phpt +@@ -32,8 +32,8 @@ + --EXPECT-- + array(2) { + [""textary""]=> +- string(51) "E'{"meeting", "lunch", "training", "presentation"}'" ++ string(50) "'{"meeting", "lunch", "training", "presentation"}'" + [""jsn""]=> +- string(22) "E'{"f1":1,"f2":"foo"}'" ++ string(21) "'{"f1":1,"f2":"foo"}'" + } + OK +diff --git a/ext/pgsql/tests/12pg_insert_9.phpt b/ext/pgsql/tests/12pg_insert_9.phpt +index 892494fe..699426c8 100644 +--- a/ext/pgsql/tests/12pg_insert_9.phpt ++++ b/ext/pgsql/tests/12pg_insert_9.phpt +@@ -54,7 +54,7 @@ + echo "Ok\n"; + ?> + --EXPECTF-- +-INSERT INTO "php_pgsql_test" ("num","str","bin") VALUES (1234,E'AAA',E'\\x424242'); ++INSERT INTO "php_pgsql_test" ("num","str","bin") VALUES (1234,'AAA','\\x424242'); + INSERT INTO "php_pgsql_test" ("num","str","bin") VALUES ('1234','AAA','BBB'); + object(PgSql\Result)#%d (0) { + } +diff --git a/ext/pgsql/tests/14pg_update_9.phpt b/ext/pgsql/tests/14pg_update_9.phpt +index d34f0521..64493075 100644 +--- a/ext/pgsql/tests/14pg_update_9.phpt ++++ b/ext/pgsql/tests/14pg_update_9.phpt +@@ -26,6 +26,6 @@ + echo "Ok\n"; + ?> + --EXPECT-- +-UPDATE "php_pgsql_test" SET "num"=1234,"str"=E'ABC',"bin"=E'\\x58595a' WHERE "num"=1234; ++UPDATE "php_pgsql_test" SET "num"=1234,"str"='ABC',"bin"='\\x58595a' WHERE "num"=1234; + UPDATE "php_pgsql_test" SET "num"='1234',"str"='ABC',"bin"='XYZ' WHERE "num"='1234'; + Ok +diff --git a/ext/pgsql/tests/GHSA-7qpv-r5mr-78m4.phpt b/ext/pgsql/tests/GHSA-7qpv-r5mr-78m4.phpt +new file mode 100644 +index 00000000..88b37a84 +--- /dev/null ++++ b/ext/pgsql/tests/GHSA-7qpv-r5mr-78m4.phpt +@@ -0,0 +1,58 @@ ++--TEST-- ++GHSA-7qpv-r5mr-78m4: SQL injection via E'...' backslash breakout ++--CREDITS-- ++expatch.llc ++--EXTENSIONS-- ++pgsql ++--SKIPIF-- ++ ++--FILE-- ++ "zzz' OR 1=1 --"]; ++echo pg_select($db, 'ghsa_7qpv_r5mr_78m4', $params, PGSQL_DML_STRING) . "\n"; ++printf("returned: %d\n\n", count(pg_select($db, 'ghsa_7qpv_r5mr_78m4', $params))); ++ ++$params = ['name' => "zzz\\' OR 1=1 --"]; ++echo pg_select($db, 'ghsa_7qpv_r5mr_78m4', $params, PGSQL_DML_STRING) . "\n"; ++printf("returned: %d\n\n", count(pg_select($db, 'ghsa_7qpv_r5mr_78m4', $params))); ++ ++$params = ['name' => "john\\', true) --", 'admin' => 'false']; ++echo pg_insert($db, 'ghsa_7qpv_r5mr_78m4', $params, PGSQL_DML_STRING) . "\n"; ++pg_insert($db, 'ghsa_7qpv_r5mr_78m4', $params); ++var_dump(pg_select($db, 'ghsa_7qpv_r5mr_78m4', ['id' => 3])[0]['admin']); ++echo "\n"; ++ ++$params = ['name' => "jake\\', true) --", 'admin' => 'f']; ++echo pg_insert($db, 'ghsa_7qpv_r5mr_78m4', $params, PGSQL_DML_ESCAPE|PGSQL_DML_STRING) . "\n"; ++pg_insert($db, 'ghsa_7qpv_r5mr_78m4', $params, PGSQL_DML_EXEC|PGSQL_DML_ESCAPE); ++var_dump(pg_select($db, 'ghsa_7qpv_r5mr_78m4', ['id' => 4])[0]['admin']); ++ ++?> ++--EXPECT-- ++SELECT * FROM "ghsa_7qpv_r5mr_78m4" WHERE "name"='zzz'' OR 1=1 --'; ++returned: 0 ++ ++SELECT * FROM "ghsa_7qpv_r5mr_78m4" WHERE "name"='zzz\'' OR 1=1 --'; ++returned: 0 ++ ++INSERT INTO "ghsa_7qpv_r5mr_78m4" ("name","admin") VALUES ('john\'', true) --','f'); ++string(1) "f" ++ ++INSERT INTO "ghsa_7qpv_r5mr_78m4" ("name","admin") VALUES ('jake\'', true) --','f'); ++string(1) "f" ++--CLEAN-- ++ +diff --git a/ext/pgsql/tests/bug64609.phpt b/ext/pgsql/tests/bug64609.phpt +index ebf878db..ba27091e 100644 +--- a/ext/pgsql/tests/bug64609.phpt ++++ b/ext/pgsql/tests/bug64609.phpt +@@ -28,5 +28,5 @@ + --EXPECT-- + array(1) { + [""a""]=> +- string(5) "E'ok'" ++ string(4) "'ok'" + } +diff --git a/ext/pgsql/tests/bug68638.phpt b/ext/pgsql/tests/bug68638.phpt +index d95fa1e4..2a1025ca 100644 +--- a/ext/pgsql/tests/bug68638.phpt ++++ b/ext/pgsql/tests/bug68638.phpt +@@ -34,7 +34,7 @@ + + ?> + --EXPECT-- +-string(52) "UPDATE "test_68638" SET "value"=E'inf' WHERE "id"=1;" ++string(51) "UPDATE "test_68638" SET "value"='inf' WHERE "id"=1;" + array(2) { + ["id"]=> + string(1) "1" diff --git a/php.spec b/php.spec index a38f509..229f58d 100644 --- a/php.spec +++ b/php.spec @@ -30,7 +30,7 @@ Summary: PHP scripting language for creating dynamic web sites Name: php Version: %{upver} -Release: 1%{?dist} +Release: 2%{?dist} License: PHP and Zend and BSD and MIT and ASL 1.0 and NCSA and Boost URL: http://www.php.net/ @@ -62,6 +62,7 @@ Patch3009: php-7.4.0-datetests.patch Patch3010: php-8.3.0-openssl-ec-param.patch Patch3011: php-8.3.7-argon2.patch Patch3012: php-8.3.3-parser.patch +Patch0001: php-8.3.31-CVE-2026-17543.patch BuildRequires: pkgconfig(libcurl) >= 7.29.0 BuildRequires: httpd-devel >= 2.0.46-1, pam-devel, httpd-filesystem, nginx-filesystem @@ -1271,6 +1272,10 @@ systemctl try-restart php-fpm.service >/dev/null 2>&1 || : %changelog +* Fri Jul 31 2026 PkgAgent Robot - 8.3.31-2 +- [Type] security +- [DESC] Fix CVE-2026-17543: SQL injection in ext-pgsql via E'...' backslash breakout + * Wed May 13 2026 PkgAgent Robot - 8.3.31-1 - [Type] security - [DESC] update to Version 8.3.31 to fix CVE-2025-14179 -- Gitee