From 3114644fa8259712359df5e5b49c83beabbf4705 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Wed, 5 Jun 2024 07:13:07 +0200 Subject: Fix filter bypass in filter_var FILTER_VALIDATE_URL CVE-2024-5458 --- failed.txt | 11 +-- php-cve-2024-5458.patch | 180 ++++++++++++++++++++++++++++++++++++++++++++++++ php.spec | 14 ++-- 3 files changed, 197 insertions(+), 8 deletions(-) create mode 100644 php-cve-2024-5458.patch diff --git a/failed.txt b/failed.txt index aec1258..94864ad 100644 --- a/failed.txt +++ b/failed.txt @@ -1,10 +1,10 @@ -===== 7.4.33-14 (2024-04-11) +===== 7.4.33-15 (2024-06-06) $ grep -ar 'Tests failed' /var/lib/mock/*/build.log /var/lib/mock/scl74el7x/build.log:Tests failed : 0 -/var/lib/mock/scl74el8a/build.log:Tests failed : 0 -/var/lib/mock/scl74el8x/build.log:Tests failed : 0 +/var/lib/mock/scl74el8a/build.log:Tests failed : 3 +/var/lib/mock/scl74el8x/build.log:Tests failed : 3 /var/lib/mock/scl74el9a/build.log:Tests failed : 1 /var/lib/mock/scl74el9x/build.log:Tests failed : 1 /var/lib/mock/scl74fc38x/build.log:Tests failed : 1 @@ -14,7 +14,10 @@ $ grep -ar 'Tests failed' /var/lib/mock/*/build.log /var/lib/mock/scl80fc40x/build.log:Tests failed : 2 -fc38, fc39, el9: +el8: + 3 openssl_error_string() tests [ext/openssl/tests/openssl_error_string_basic.phpt] + 3 openssl_open() tests [ext/openssl/tests/openssl_open_basic.phpt] +fc38, fc39, el8, el9: 3 openssl_private_decrypt() tests [ext/openssl/tests/openssl_private_decrypt_basic.phpt] fc40: 3 openssl_x509_parse() tests [ext/openssl/tests/openssl_x509_parse_basic.phpt] diff --git a/php-cve-2024-5458.patch b/php-cve-2024-5458.patch new file mode 100644 index 0000000..64a1a78 --- /dev/null +++ b/php-cve-2024-5458.patch @@ -0,0 +1,180 @@ +From 08be64e40197fc12dca5f802d16748d9c3cb4cb4 Mon Sep 17 00:00:00 2001 +From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> +Date: Wed, 22 May 2024 22:25:02 +0200 +Subject: [PATCH 1/2] Fix GHSA-w8qr-v226-r27w + +We should not early-out with success status if we found an ipv6 +hostname, we should keep checking the rest of the conditions. +Because integrating the if-check of the ipv6 hostname in the +"Validate domain" if-check made the code hard to read, I extracted the +condition out to a separate function. This also required to make +a few pointers const in order to have some clean code. + +(cherry picked from commit 4066610b47e22c24cbee91be434a94357056a479) +--- + ext/filter/logical_filters.c | 35 ++++++++++--------- + ext/filter/tests/ghsa-w8qr-v226-r27w.phpt | 41 +++++++++++++++++++++++ + 2 files changed, 61 insertions(+), 15 deletions(-) + create mode 100644 ext/filter/tests/ghsa-w8qr-v226-r27w.phpt + +diff --git a/ext/filter/logical_filters.c b/ext/filter/logical_filters.c +index e5e87c01568..9c86ad072cc 100644 +--- a/ext/filter/logical_filters.c ++++ b/ext/filter/logical_filters.c +@@ -91,7 +91,7 @@ + #define FORMAT_IPV4 4 + #define FORMAT_IPV6 6 + +-static int _php_filter_validate_ipv6(char *str, size_t str_len, int ip[8]); ++static int _php_filter_validate_ipv6(const char *str, size_t str_len, int ip[8]); + + static int php_filter_parse_int(const char *str, size_t str_len, zend_long *ret) { /* {{{ */ + zend_long ctx_value; +@@ -571,6 +571,14 @@ static int is_userinfo_valid(zend_string *str) + return 1; + } + ++static zend_bool php_filter_is_valid_ipv6_hostname(const char *s, size_t l) ++{ ++ const char *e = s + l; ++ const char *t = e - 1; ++ ++ return *s == '[' && *t == ']' && _php_filter_validate_ipv6(s + 1, l - 2, NULL); ++} ++ + void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ + { + php_url *url; +@@ -596,7 +604,7 @@ void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ + + if (url->scheme != NULL && + (zend_string_equals_literal_ci(url->scheme, "http") || zend_string_equals_literal_ci(url->scheme, "https"))) { +- char *e, *s, *t; ++ const char *s; + size_t l; + + if (url->host == NULL) { +@@ -605,17 +613,14 @@ void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ + + s = ZSTR_VAL(url->host); + l = ZSTR_LEN(url->host); +- e = s + l; +- t = e - 1; +- +- /* An IPv6 enclosed by square brackets is a valid hostname */ +- if (*s == '[' && *t == ']' && _php_filter_validate_ipv6((s + 1), l - 2, NULL)) { +- php_url_free(url); +- return; +- } + +- // Validate domain +- if (!_php_filter_validate_domain(ZSTR_VAL(url->host), l, FILTER_FLAG_HOSTNAME)) { ++ if ( ++ /* An IPv6 enclosed by square brackets is a valid hostname.*/ ++ !php_filter_is_valid_ipv6_hostname(s, l) && ++ /* Validate domain. ++ * This includes a loose check for an IPv4 address. */ ++ !_php_filter_validate_domain(ZSTR_VAL(url->host), l, FILTER_FLAG_HOSTNAME) ++ ) { + php_url_free(url); + RETURN_VALIDATION_FAILED + } +@@ -749,15 +754,15 @@ static int _php_filter_validate_ipv4(char *str, size_t str_len, int *ip) /* {{{ + } + /* }}} */ + +-static int _php_filter_validate_ipv6(char *str, size_t str_len, int ip[8]) /* {{{ */ ++static int _php_filter_validate_ipv6(const char *str, size_t str_len, int ip[8]) /* {{{ */ + { + int compressed_pos = -1; + int blocks = 0; + int num, n, i; + char *ipv4; +- char *end; ++ const char *end; + int ip4elm[4]; +- char *s = str; ++ const char *s = str; + + if (!memchr(str, ':', str_len)) { + return 0; +diff --git a/ext/filter/tests/ghsa-w8qr-v226-r27w.phpt b/ext/filter/tests/ghsa-w8qr-v226-r27w.phpt +new file mode 100644 +index 00000000000..0092408ee5a +--- /dev/null ++++ b/ext/filter/tests/ghsa-w8qr-v226-r27w.phpt +@@ -0,0 +1,41 @@ ++--TEST-- ++GHSA-w8qr-v226-r27w ++--EXTENSIONS-- ++filter ++--FILE-- ++ ++--EXPECT-- ++--- These ones should fail --- ++bool(false) ++bool(false) ++bool(false) ++bool(false) ++bool(false) ++bool(false) ++bool(false) ++bool(false) ++--- These ones should work --- ++string(21) "http://test@127.0.0.1" ++string(50) "http://test@[2001:db8:3333:4444:5555:6666:1.2.3.4]" ++string(17) "http://test@[::1]" +-- +2.45.1 + +From ec1d5e6468479e64acc7fb8cb955f053b64ea9a0 Mon Sep 17 00:00:00 2001 +From: Remi Collet +Date: Tue, 4 Jun 2024 16:48:08 +0200 +Subject: [PATCH 2/2] NEWS + +(cherry picked from commit a1ff81b786bd519597e770795be114f5171f0648) +--- + NEWS | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/NEWS b/NEWS +index 8058eff0256..34ad33cf5c4 100644 +--- a/NEWS ++++ b/NEWS +@@ -1,6 +1,12 @@ + PHP NEWS + ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + ++Backported from 8.1.29 ++ ++- Filter: ++ . Fixed bug GHSA-w8qr-v226-r27w (Filter bypass in filter_var FILTER_VALIDATE_URL). ++ (CVE-2024-5458) (nielsdos) ++ + Backported from 8.1.28 + + - Standard: +-- +2.45.1 + diff --git a/php.spec b/php.spec index 0d36dd4..0ee4e0e 100644 --- a/php.spec +++ b/php.spec @@ -50,9 +50,9 @@ %global mysql_sock %(mysql_config --socket 2>/dev/null || echo /var/lib/mysql/mysql.sock) %ifarch aarch64 -%global oraclever 19.19 +%global oraclever 19.22 %global oraclelib 19.1 -%global oracledir 19.19 +%global oracledir 19.22 %else %global oraclever 21.13 %global oraclelib 21.1 @@ -117,7 +117,7 @@ Summary: PHP scripting language for creating dynamic web sites Name: %{?scl_prefix}php Version: %{upver}%{?rcver:~%{rcver}}%{?gh_date:.%{gh_date}} -Release: 14%{?dist} +Release: 15%{?dist} # All files licensed under PHP version 3.01, except # Zend is licensed under Zend # TSRM is licensed under BSD @@ -194,6 +194,7 @@ Patch205: php-cve-2023-3823.patch Patch206: php-cve-2023-3824.patch Patch207: php-cve-2024-2756.patch Patch208: php-cve-2024-3096.patch +Patch209: php-cve-2024-5458.patch # Fixes for tests (300+) # Factory is droped from system tzdata @@ -991,6 +992,7 @@ rm ext/openssl/tests/p12_with_extra_certs.p12 %patch -P206 -p1 -b .cve3824 %patch -P207 -p1 -b .cve2756 %patch -P208 -p1 -b .cve3096 +%patch -P209 -p1 -b .cve5458 # Fixes for tests %patch -P300 -p1 -b .datetests @@ -1716,7 +1718,7 @@ cat << EOF WARNING : PHP 7.4 have reached its "End of Life" in November 2022. Even, if this package includes some of - the important security fixes, backported from 8.0, the + the important security fixes, backported from 8.1, the UPGRADE to a maintained version is very strongly RECOMMENDED. ===================================================================== @@ -1882,6 +1884,10 @@ EOF %changelog +* Tue Jun 4 2024 Remi Collet - 7.4.33-15 +- Fix filter bypass in filter_var FILTER_VALIDATE_URL + CVE-2024-5458 + * Wed Apr 10 2024 Remi Collet - 7.4.33-14 - Fix __Host-/__Secure- cookie bypass due to partial CVE-2022-31629 fix CVE-2024-2756 -- cgit