diff --git a/backport-CVE-2020-7071-Fix-bug-77423.patch b/backport-CVE-2020-7071-Fix-bug-77423.patch new file mode 100644 index 0000000000000000000000000000000000000000..5b822e4a3a8d9e7cc57a33f4eb892b22267d39e4 --- /dev/null +++ b/backport-CVE-2020-7071-Fix-bug-77423.patch @@ -0,0 +1,197 @@ +From 5174de7cd33c3d4fa591c9c93859ff9989b07e8c Mon Sep 17 00:00:00 2001 +From: "Christoph M. Becker" +Date: Wed, 13 May 2020 09:36:52 +0200 +Subject: [PATCH] Fix #77423: parse_url() will deliver a wrong host to user + +To avoid that `parse_url()` returns an erroneous host, which would be +valid for `FILTER_VALIDATE_URL`, we make sure that only userinfo which +is valid according to RFC 3986 is treated as such. + +For consistency with the existing url parsing code, we use ctype +functions, although that is not necessarily correct. +--- + ext/standard/tests/strings/url_t.phpt | 6 ++-- + ext/standard/tests/url/bug77423.phpt | 30 +++++++++++++++++++ + .../tests/url/parse_url_basic_001.phpt | 6 ++-- + .../tests/url/parse_url_basic_003.phpt | 2 +- + .../tests/url/parse_url_basic_005.phpt | 2 +- + .../tests/url/parse_url_unterminated.phpt | 6 ++-- + ext/standard/url.c | 24 +++++++++++++-- + 7 files changed, 60 insertions(+), 16 deletions(-) + create mode 100644 ext/standard/tests/url/bug77423.phpt + +diff --git a/ext/standard/tests/strings/url_t.phpt b/ext/standard/tests/strings/url_t.phpt +index caa93cb9cf01..dc13018b14a0 100644 +--- a/ext/standard/tests/strings/url_t.phpt ++++ b/ext/standard/tests/strings/url_t.phpt +@@ -589,15 +589,13 @@ $sample_urls = array ( + string(16) "some_page_ref123" + } + +---> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(7) { ++--> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(6) { + ["scheme"]=> + string(4) "http" + ["host"]=> +- string(11) "www.php.net" ++ string(26) "secret@hideout@www.php.net" + ["port"]=> + int(80) +- ["user"]=> +- string(14) "secret@hideout" + ["path"]=> + string(10) "/index.php" + ["query"]=> +diff --git a/ext/standard/tests/url/bug77423.phpt b/ext/standard/tests/url/bug77423.phpt +new file mode 100644 +index 000000000000..be03fe95e24e +--- /dev/null ++++ b/ext/standard/tests/url/bug77423.phpt +@@ -0,0 +1,30 @@ ++--TEST-- ++Bug #77423 (parse_url() will deliver a wrong host to user) ++--FILE-- ++ ++--EXPECT-- ++bool(false) ++array(3) { ++ ["scheme"]=> ++ string(4) "http" ++ ["host"]=> ++ string(19) "php.net\@aliyun.com" ++ ["path"]=> ++ string(7) "/aaa.do" ++} ++bool(false) ++array(2) { ++ ["scheme"]=> ++ string(5) "https" ++ ["host"]=> ++ string(26) "example.com\uFF03@bing.com" ++} +diff --git a/ext/standard/tests/url/parse_url_basic_001.phpt b/ext/standard/tests/url/parse_url_basic_001.phpt +index f3abd703b263..89b1b7b3d683 100644 +--- a/ext/standard/tests/url/parse_url_basic_001.phpt ++++ b/ext/standard/tests/url/parse_url_basic_001.phpt +@@ -514,15 +514,13 @@ echo "Done"; + string(16) "some_page_ref123" + } + +---> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(7) { ++--> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(6) { + ["scheme"]=> + string(4) "http" + ["host"]=> +- string(11) "www.php.net" ++ string(26) "secret@hideout@www.php.net" + ["port"]=> + int(80) +- ["user"]=> +- string(14) "secret@hideout" + ["path"]=> + string(10) "/index.php" + ["query"]=> +diff --git a/ext/standard/tests/url/parse_url_basic_003.phpt b/ext/standard/tests/url/parse_url_basic_003.phpt +index 1eb64d6a1b1c..da35b927821a 100644 +--- a/ext/standard/tests/url/parse_url_basic_003.phpt ++++ b/ext/standard/tests/url/parse_url_basic_003.phpt +@@ -62,7 +62,7 @@ echo "Done"; + --> http://secret:@www.php.net/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(11) "www.php.net" + --> http://:hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(11) "www.php.net" + --> http://secret:hideout@www.php.net/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(11) "www.php.net" +---> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(11) "www.php.net" ++--> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(26) "secret@hideout@www.php.net" + --> http://secret:hid:out@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(11) "www.php.net" + --> nntp://news.php.net : string(12) "news.php.net" + --> ftp://ftp.gnu.org/gnu/glic/glibc.tar.gz : string(11) "ftp.gnu.org" +diff --git a/ext/standard/tests/url/parse_url_basic_005.phpt b/ext/standard/tests/url/parse_url_basic_005.phpt +index dfbe7e7971e4..731a4adb3149 100644 +--- a/ext/standard/tests/url/parse_url_basic_005.phpt ++++ b/ext/standard/tests/url/parse_url_basic_005.phpt +@@ -62,7 +62,7 @@ echo "Done"; + --> http://secret:@www.php.net/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(6) "secret" + --> http://:hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(0) "" + --> http://secret:hideout@www.php.net/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(6) "secret" +---> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(14) "secret@hideout" ++--> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : NULL + --> http://secret:hid:out@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(6) "secret" + --> nntp://news.php.net : NULL + --> ftp://ftp.gnu.org/gnu/glic/glibc.tar.gz : NULL +diff --git a/ext/standard/tests/url/parse_url_unterminated.phpt b/ext/standard/tests/url/parse_url_unterminated.phpt +index 7c9150a513d9..f859fc7d407f 100644 +--- a/ext/standard/tests/url/parse_url_unterminated.phpt ++++ b/ext/standard/tests/url/parse_url_unterminated.phpt +@@ -522,15 +522,13 @@ echo "Done"; + string(16) "some_page_ref123" + } + +---> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(7) { ++--> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(6) { + ["scheme"]=> + string(4) "http" + ["host"]=> +- string(11) "www.php.net" ++ string(26) "secret@hideout@www.php.net" + ["port"]=> + int(80) +- ["user"]=> +- string(14) "secret@hideout" + ["path"]=> + string(10) "/index.php" + ["query"]=> +diff --git a/ext/standard/url.c b/ext/standard/url.c +index a33091a86b75..113e0100243a 100644 +--- a/ext/standard/url.c ++++ b/ext/standard/url.c +@@ -92,6 +92,22 @@ static const char *binary_strcspn(const char *s, const char *e, const char *char + return e; + } + ++static int is_userinfo_valid(const char *str, size_t len) ++{ ++ const char *valid = "-._~!$&'()*+,;=:"; ++ const char *p = str; ++ while (p - str < len) { ++ if (isalpha(*p) || isdigit(*p) || strchr(valid, *p)) { ++ p++; ++ } else if (*p == '%' && p - str <= len - 3 && isdigit(*(p+1)) && isxdigit(*(p+2))) { ++ p += 3; ++ } else { ++ return 0; ++ } ++ } ++ return 1; ++} ++ + /* {{{ php_url_parse */ + PHPAPI php_url *php_url_parse_ex(char const *str, size_t length) + { +@@ -233,13 +249,17 @@ PHPAPI php_url *php_url_parse_ex2(char const *str, size_t length, zend_bool *has + ret->pass = zend_string_init(pp, (p-pp), 0); + php_replace_controlchars_ex(ZSTR_VAL(ret->pass), ZSTR_LEN(ret->pass)); + } else { +- ret->user = zend_string_init(s, (p-s), 0); +- php_replace_controlchars_ex(ZSTR_VAL(ret->user), ZSTR_LEN(ret->user)); ++ if (!is_userinfo_valid(s, p-s)) { ++ goto check_port; ++ } ++ ret->user = zend_string_init(s, (p-s), 0); ++ php_replace_controlchars_ex(ZSTR_VAL(ret->user), ZSTR_LEN(ret->user)); + } + + s = p + 1; + } + ++check_port: + /* check for port */ + if (s < ue && *s == '[' && *(e-1) == ']') { + /* Short circuit portscan, diff --git a/php.spec b/php.spec index b385c4a1670deb80e70c32187a0a329942ffe402..b30d4ddef3efb06d360d69332b32d6bdc9e6015f 100644 --- a/php.spec +++ b/php.spec @@ -27,9 +27,9 @@ Name: php Version: %{upver}%{?rcver:~%{rcver}} -Release: 1 +Release: 2 Summary: PHP scripting language for creating dynamic web sites -License: PHP and Zend and BSD and MIT and ASL 1.0 and NCSA +License: PHP and Zend-2.0 and BSD and MIT and ASL 1.0 and NCSA URL: http://www.php.net/ Source0: http://www.php.net/distributions/php-%{upver}%{?rcver}.tar.xz Source1: php.conf @@ -48,15 +48,16 @@ Source50: 10-opcache.ini Source51: opcache-default.blacklist Source52: 20-ffi.ini -Patch0001: php-7.4.0-httpd.patch -Patch0002: php-7.2.0-includedir.patch -Patch0003: php-8.0.0-embed.patch -Patch0004: php-7.4.0-libdb.patch -Patch0005: php-8.0.0-systzdata-v19.patch -Patch0006: php-7.4.0-phpize.patch -Patch0007: php-7.4.0-ldap_r.patch -Patch0008: php-8.0.0-phpinfo.patch -Patch0009: php-7.4.0-datetests.patch +Patch0: php-7.4.0-httpd.patch +Patch1: php-7.2.0-includedir.patch +Patch2: php-8.0.0-embed.patch +Patch3: php-7.4.0-libdb.patch +Patch4: php-8.0.0-systzdata-v19.patch +Patch5: php-7.4.0-phpize.patch +Patch6: php-7.4.0-ldap_r.patch +Patch7: php-8.0.0-phpinfo.patch +Patch8: php-7.4.0-datetests.patch +Patch9: backport-CVE-2020-7071-Fix-bug-77423.patch BuildRequires: bzip2-devel, curl-devel >= 7.9, httpd-devel >= 2.0.46-1, pam-devel, httpd-filesystem, nginx-filesystem BuildRequires: libstdc++-devel, openssl-devel, sqlite-devel >= 3.6.0, zlib-devel, smtpdaemon, libedit-devel @@ -1095,6 +1096,9 @@ systemctl try-restart php-fpm.service >/dev/null 2>&1 || : %changelog +* Fri Jan 29 2021 panxiaohe - 8.0.0-2 +- Fix CVE-2020-7071 + * Thu Dec 31 2020 panxiaohe - 8.0.0-1 - Update to 8.0.0