summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemi Collet <remi@remirepo.net>2024-06-05 07:13:59 +0200
committerRemi Collet <remi@php.net>2024-06-05 07:13:59 +0200
commitd3fb24595d6bcebd6bd29477bc59916f333f5233 (patch)
treee39edaa415db24248f0c030fc3d8af29bbba26fb
parentb3134164ac72768f850d259aefef6edf32775e95 (diff)
Fix filter bypass in filter_var FILTER_VALIDATE_URL
CVE-2024-5458
-rw-r--r--failed.txt11
-rw-r--r--php-cve-2024-5458.patch180
-rw-r--r--php74.spec14
3 files changed, 197 insertions, 8 deletions
diff --git a/failed.txt b/failed.txt
index 821fa60..6df67c8 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/el7x74/build.log:Tests failed : 0
-/var/lib/mock/el8a74/build.log:Tests failed : 0
-/var/lib/mock/el8x74/build.log:Tests failed : 0
+/var/lib/mock/el8a74/build.log:Tests failed : 3
+/var/lib/mock/el8x74/build.log:Tests failed : 3
/var/lib/mock/el9a74/build.log:Tests failed : 1
/var/lib/mock/el9x74/build.log:Tests failed : 1
/var/lib/mock/fc38x74/build.log:Tests failed : 1
@@ -14,7 +14,10 @@ $ grep -ar 'Tests failed' /var/lib/mock/*/build.log
/var/lib/mock/fc40x74/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--
++<?php
++
++function test(string $input) {
++ var_dump(filter_var($input, FILTER_VALIDATE_URL));
++}
++
++echo "--- These ones should fail ---\n";
++test("http://t[est@127.0.0.1");
++test("http://t[est@[::1]");
++test("http://t[est@[::1");
++test("http://t[est@::1]");
++test("http://php.net\\@aliyun.com/aaa.do");
++test("http://test[@2001:db8:3333:4444:5555:6666:1.2.3.4]");
++test("http://te[st@2001:db8:3333:4444:5555:6666:1.2.3.4]");
++test("http://te[st@2001:db8:3333:4444:5555:6666:1.2.3.4");
++
++echo "--- These ones should work ---\n";
++test("http://test@127.0.0.1");
++test("http://test@[2001:db8:3333:4444:5555:6666:1.2.3.4]");
++test("http://test@[::1]");
++
++?>
++--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 <remi@remirepo.net>
+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/php74.spec b/php74.spec
index 556daf3..228f522 100644
--- a/php74.spec
+++ b/php74.spec
@@ -25,9 +25,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
@@ -109,7 +109,7 @@
Summary: PHP scripting language for creating dynamic web sites
Name: php
Version: %{upver}%{?rcver:~%{rcver}}
-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
@@ -185,6 +185,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
@@ -1202,6 +1203,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 related to tzdata
%patch -P300 -p1 -b .datetests
@@ -2045,7 +2047,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.
=====================================================================
@@ -2221,6 +2223,10 @@ EOF
%changelog
+* Tue Jun 4 2024 Remi Collet <remi@remirepo.net> - 7.4.33-15
+- Fix filter bypass in filter_var FILTER_VALIDATE_URL
+ CVE-2024-5458
+
* Wed Apr 10 2024 Remi Collet <remi@remirepo.net> - 7.4.33-14
- Fix __Host-/__Secure- cookie bypass due to partial CVE-2022-31629 fix
CVE-2024-2756