From 7a06ca4a3f915bd7445b58bf1c321a79a7a21501 Mon Sep 17 00:00:00 2001 From: fuanan <2385803914@qq.com> Date: Wed, 29 Sep 2021 15:36:29 +0800 Subject: [PATCH] refix CVE-2020-7071 and fix CVE-2021-21705 --- backport-0001-CVE-2020-7071.patch | 211 +++++++++++++++++++++++++++++ backport-0001-CVE-2021-21705.patch | 58 ++++++++ backport-0002-CVE-2020-7071.patch | 36 +++++ backport-0002-CVE-2021-21705.patch | 28 ++++ php.spec | 9 +- 5 files changed, 341 insertions(+), 1 deletion(-) create mode 100644 backport-0001-CVE-2020-7071.patch create mode 100644 backport-0001-CVE-2021-21705.patch create mode 100644 backport-0002-CVE-2020-7071.patch create mode 100644 backport-0002-CVE-2021-21705.patch diff --git a/backport-0001-CVE-2020-7071.patch b/backport-0001-CVE-2020-7071.patch new file mode 100644 index 0000000..f7d4190 --- /dev/null +++ b/backport-0001-CVE-2020-7071.patch @@ -0,0 +1,211 @@ +From 4a89e726bd4d0571991dc22a9a1ad4509e8fe347 Mon Sep 17 00:00:00 2001 +From: "Christoph M. Becker" +Date: Tue, 19 Jan 2021 11:23:25 +0100 +Subject: [PATCH] Alternative fix for bug 77423 + +That bug report originally was about `parse_url()` misbehaving, but the +security aspect was actually only regarding `FILTER_VALIDATE_URL`. +Since the changes to `parse_url_ex()` apparently affect userland code +which is relying on the sloppy URL parsing[1], this alternative +restores the old parsing behavior, but ensures that the userinfo is +checked for correctness for `FILTER_VALIDATE_URL`. + +[1] +--- + ext/filter/logical_filters.c | 23 +++++++++++++++++++ + .../tests/url => filter/tests}/bug77423.phpt | 15 ------------ + ext/standard/tests/strings/url_t.phpt | 6 +++-- + .../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 | 6 +---- + 8 files changed, 38 insertions(+), 28 deletions(-) + rename ext/{standard/tests/url => filter/tests}/bug77423.phpt (53%) + +diff --git a/ext/filter/logical_filters.c b/ext/filter/logical_filters.c +index 076d2479461f..1cf345dbb58a 100644 +--- a/ext/filter/logical_filters.c ++++ b/ext/filter/logical_filters.c +@@ -532,6 +532,22 @@ void php_filter_validate_domain(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ + } + /* }}} */ + ++static int is_userinfo_valid(zend_string *str) ++{ ++ const char *valid = "-._~!$&'()*+,;=:"; ++ const char *p = ZSTR_VAL(str); ++ while (p - ZSTR_VAL(str) < ZSTR_LEN(str)) { ++ if (isalpha(*p) || isdigit(*p) || strchr(valid, *p)) { ++ p++; ++ } else if (*p == '%' && p - ZSTR_VAL(str) <= ZSTR_LEN(str) - 3 && isdigit(*(p+1)) && isxdigit(*(p+2))) { ++ p += 3; ++ } else { ++ return 0; ++ } ++ } ++ return 1; ++} ++ + void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ + { + php_url *url; +@@ -592,6 +608,13 @@ void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ + php_url_free(url); + RETURN_VALIDATION_FAILED + } ++ ++ if (url->user != NULL && !is_userinfo_valid(url->user)) { ++ php_url_free(url); ++ RETURN_VALIDATION_FAILED ++ ++ } ++ + php_url_free(url); + } + /* }}} */ +diff --git a/ext/standard/tests/url/bug77423.phpt b/ext/filter/tests/bug77423.phpt +similarity index 53% +rename from ext/standard/tests/url/bug77423.phpt +rename to ext/filter/tests/bug77423.phpt +index be03fe95e24e..761c7c359a92 100644 +--- a/ext/standard/tests/url/bug77423.phpt ++++ b/ext/filter/tests/bug77423.phpt +@@ -8,23 +8,8 @@ $urls = array( + ); + foreach ($urls as $url) { + var_dump(filter_var($url, FILTER_VALIDATE_URL)); +- var_dump(parse_url($url)); + } + ?> + --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/strings/url_t.phpt b/ext/standard/tests/strings/url_t.phpt +index f564f59f0632..79ff3bc4a8e3 100644 +--- a/ext/standard/tests/strings/url_t.phpt ++++ b/ext/standard/tests/strings/url_t.phpt +@@ -575,13 +575,15 @@ $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(6) { ++--> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(7) { + ["scheme"]=> + string(4) "http" + ["host"]=> +- string(26) "secret@hideout@www.php.net" ++ string(11) "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_001.phpt b/ext/standard/tests/url/parse_url_basic_001.phpt +index 57014f08391a..7ffd001856c8 100644 +--- a/ext/standard/tests/url/parse_url_basic_001.phpt ++++ b/ext/standard/tests/url/parse_url_basic_001.phpt +@@ -506,13 +506,15 @@ 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(6) { ++--> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(7) { + ["scheme"]=> + string(4) "http" + ["host"]=> +- string(26) "secret@hideout@www.php.net" ++ string(11) "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 e7cd24c9698c..8b0e7eb87500 100644 +--- a/ext/standard/tests/url/parse_url_basic_003.phpt ++++ b/ext/standard/tests/url/parse_url_basic_003.phpt +@@ -68,7 +68,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(26) "secret@hideout@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: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 8617d37059ec..a5ca381a691f 100644 +--- a/ext/standard/tests/url/parse_url_basic_005.phpt ++++ b/ext/standard/tests/url/parse_url_basic_005.phpt +@@ -68,7 +68,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 : NULL ++--> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(14) "secret@hideout" + --> 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 1377cb7735f0..8f46eb3dbedf 100644 +--- a/ext/standard/tests/url/parse_url_unterminated.phpt ++++ b/ext/standard/tests/url/parse_url_unterminated.phpt +@@ -508,13 +508,15 @@ 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(6) { ++--> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(7) { + ["scheme"]=> + string(4) "http" + ["host"]=> +- string(26) "secret@hideout@www.php.net" ++ string(11) "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 157d61466e69..9743a00166b1 100644 +--- a/ext/standard/url.c ++++ b/ext/standard/url.c +@@ -260,9 +260,6 @@ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length) + ret->pass = estrndup(pp, (p-pp)); + php_replace_controlchars_ex(ret->pass, (p-pp)); + } else { +- if (!is_userinfo_valid(s, p-s)) { +- goto check_port; +- } + ret->user = estrndup(s, (p-s)); + php_replace_controlchars_ex(ret->user, (p-s)); + +@@ -271,7 +268,6 @@ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length) + s = p + 1; + } + +-check_port: + /* check for port */ + if (s < ue && *s == '[' && *(e-1) == ']') { + /* Short circuit portscan, diff --git a/backport-0001-CVE-2021-21705.patch b/backport-0001-CVE-2021-21705.patch new file mode 100644 index 0000000..acf35ba --- /dev/null +++ b/backport-0001-CVE-2021-21705.patch @@ -0,0 +1,58 @@ +From a5538c62293fa782fcc382d0635cfc0c8b9190e3 Mon Sep 17 00:00:00 2001 +From: "Christoph M. Becker" +Date: Mon, 14 Jun 2021 13:22:27 +0200 +Subject: [PATCH] Fix #81122: SSRF bypass in FILTER_VALIDATE_URL + +We need to ensure that the password detected by parse_url() is actually +a valid password; we can re-use is_userinfo_valid() for that. +--- + ext/filter/logical_filters.c | 4 +++- + ext/filter/tests/bug81122.phpt | 21 +++++++++++++++++++++ + 2 files changed, 24 insertions(+), 1 deletion(-) + create mode 100644 ext/filter/tests/bug81122.phpt + +diff --git a/ext/filter/logical_filters.c b/ext/filter/logical_filters.c +index 1cf345dbb58a..3f314fefa0e1 100644 +--- a/ext/filter/logical_filters.c ++++ b/ext/filter/logical_filters.c +@@ -609,7 +609,9 @@ void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ + RETURN_VALIDATION_FAILED + } + +- if (url->user != NULL && !is_userinfo_valid(url->user)) { ++ if (url->user != NULL && !is_userinfo_valid(url->user) ++ || url->pass != NULL && !is_userinfo_valid(url->pass) ++ ) { + php_url_free(url); + RETURN_VALIDATION_FAILED + +diff --git a/ext/filter/tests/bug81122.phpt b/ext/filter/tests/bug81122.phpt +new file mode 100644 +index 000000000000..d89d4114a547 +--- /dev/null ++++ b/ext/filter/tests/bug81122.phpt +@@ -0,0 +1,21 @@ ++--TEST-- ++Bug #81122 (SSRF bypass in FILTER_VALIDATE_URL) ++--SKIPIF-- ++ ++--FILE-- ++ ++--EXPECT-- ++bool(false) ++bool(false) ++bool(false) +-- +2.27.0 + diff --git a/backport-0002-CVE-2020-7071.patch b/backport-0002-CVE-2020-7071.patch new file mode 100644 index 0000000..aedffc0 --- /dev/null +++ b/backport-0002-CVE-2020-7071.patch @@ -0,0 +1,36 @@ +From 9c673083cd46ee2a954a62156acbe4b6e657c048 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Wed, 27 Jan 2021 00:13:43 -0800 +Subject: [PATCH] Rm unneeded function + +--- + ext/standard/url.c | 16 ---------------- + 1 file changed, 16 deletions(-) + +diff --git a/ext/standard/url.c b/ext/standard/url.c +index 9743a00166b1..0b3d97a76691 100644 +--- a/ext/standard/url.c ++++ b/ext/standard/url.c +@@ -102,22 +102,6 @@ PHPAPI php_url *php_url_parse(char const *str) + return php_url_parse_ex(str, strlen(str)); + } + +-static int is_userinfo_valid(const char *str, size_t len) +-{ +- char *valid = "-._~!$&'()*+,;=:"; +- 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) diff --git a/backport-0002-CVE-2021-21705.patch b/backport-0002-CVE-2021-21705.patch new file mode 100644 index 0000000..1f98d1e --- /dev/null +++ b/backport-0002-CVE-2021-21705.patch @@ -0,0 +1,28 @@ +From 7bab67c2d0d3c30b1176d5bcf6f20b0e1c50c589 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev +Date: Sun, 27 Jun 2021 21:57:58 -0700 +Subject: [PATCH] Fix warning + +(cherry picked from commit 190013787bbc424c240413d914e3a038f974ccef) +--- + ext/filter/logical_filters.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/ext/filter/logical_filters.c b/ext/filter/logical_filters.c +index 721da45d532d..1ffc467b43c1 100644 +--- a/ext/filter/logical_filters.c ++++ b/ext/filter/logical_filters.c +@@ -632,8 +632,8 @@ void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ + RETURN_VALIDATION_FAILED + } + +- if (url->user != NULL && !is_userinfo_valid(url->user) +- || url->pass != NULL && !is_userinfo_valid(url->pass) ++ if ((url->user != NULL && !is_userinfo_valid(url->user)) ++ || (url->pass != NULL && !is_userinfo_valid(url->pass)) + ) { + php_url_free(url); + RETURN_VALIDATION_FAILED +-- +2.27.0 + diff --git a/php.spec b/php.spec index 373978d..9e3d103 100644 --- a/php.spec +++ b/php.spec @@ -28,7 +28,7 @@ Name: php Version: %{upver}%{?rcver:~%{rcver}} -Release: 13 +Release: 14 Summary: PHP scripting language for creating dynamic web sites License: PHP and Zend and BSD and MIT and ASL 1.0 and NCSA LGPL-2.1+ and Apache-2.0 and Artistic-1.0-Perl URL: http://www.php.net/ @@ -104,6 +104,10 @@ Patch6030: backport-CVE-2020-7060-Fix-bug-79037-global-buffer-overflow-in-mb Patch6031: backport-Fix-bug-78079-openssl_encrypt_ccm.phpt-fails-with-op.patch Patch6032: backport-CVE-2020-7069-Fix-bug-79601-Wrong-ciphertext-tag-in-AES-CCM-encryp.patch Patch6033: backport-CVE-2020-7070-Do-not-decode-cookie-names-anymore.patch +Patch6034: backport-0001-CVE-2020-7071.patch +Patch6035: backport-0002-CVE-2020-7071.patch +Patch6036: backport-0001-CVE-2021-21705.patch +Patch6037: backport-0002-CVE-2021-21705.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 @@ -1165,6 +1169,9 @@ systemctl try-restart php-fpm.service >/dev/null 2>&1 || : %changelog +* Wed Sep 29 2021 fuanan - 7.2.10-14 +- refix CVE-2020-7071 and fix CVE-2021-21705 + * Wed Feb 3 2021 yangzhuangzhuang - 7.2.10-13 - Fix CVE-2020-7069 CVE-2020-7070 -- Gitee