!50 refix CVE-2020-7071 and fix CVE-2021-21705

From: @fly_fzc
Reviewed-by: @overweight
Signed-off-by: @overweight
This commit is contained in:
openeuler-ci-bot 2021-09-29 09:36:42 +00:00 committed by Gitee
commit c075eb653b
5 changed files with 341 additions and 1 deletions

View File

@ -0,0 +1,211 @@
From 4a89e726bd4d0571991dc22a9a1ad4509e8fe347 Mon Sep 17 00:00:00 2001
From: "Christoph M. Becker" <cmbecker69@gmx.de>
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] <https://github.com/php/php-src/commit/5174de7cd33c3d4fa591c9c93859ff9989b07e8c#commitcomment-45967652>
---
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 @@ parse_host:
ret->pass = zend_string_init(pp, (p-pp), 0);
php_replace_controlchars_ex(ZSTR_VAL(ret->pass), ZSTR_LEN(ret->pass));
} else {
- 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));
}
@@ -271,7 +268,6 @@ parse_host:
s = p + 1;
}
-check_port:
/* check for port */
if (s < ue && *s == '[' && *(e-1) == ']') {
/* Short circuit portscan,

View File

@ -0,0 +1,58 @@
From a5538c62293fa782fcc382d0635cfc0c8b9190e3 Mon Sep 17 00:00:00 2001
From: "Christoph M. Becker" <cmbecker69@gmx.de>
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--
+<?php
+if (!extension_loaded('filter')) die("skip filter extension not available");
+?>
+--FILE--
+<?php
+$urls = [
+ "https://example.com:\\@test.com/",
+ "https://user:\\epass@test.com",
+ "https://user:\\@test.com",
+];
+foreach ($urls as $url) {
+ var_dump(filter_var($url, FILTER_VALIDATE_URL));
+}
+?>
+--EXPECT--
+bool(false)
+bool(false)
+bool(false)
--
2.27.0

View File

@ -0,0 +1,36 @@
From 9c673083cd46ee2a954a62156acbe4b6e657c048 Mon Sep 17 00:00:00 2001
From: Stanislav Malyshev <stas@php.net>
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 @@ static const char *binary_strcspn(const char *s, const char *e
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)
{

View File

@ -0,0 +1,28 @@
From 7bab67c2d0d3c30b1176d5bcf6f20b0e1c50c589 Mon Sep 17 00:00:00 2001
From: Stanislav Malyshev <stas@php.net>
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

View File

@ -27,7 +27,7 @@
Name: php
Version: %{upver}%{?rcver:~%{rcver}}
Release: 3
Release: 4
Summary: PHP scripting language for creating dynamic web sites
License: PHP and Zend-2.0 and BSD and MIT and ASL 1.0 and NCSA
URL: http://www.php.net/
@ -59,6 +59,10 @@ Patch7: php-8.0.0-phpinfo.patch
Patch8: php-7.4.0-datetests.patch
Patch9: backport-CVE-2020-7071-Fix-bug-77423.patch
Patch10: CVE-2021-21702.patch
Patch11: backport-0001-CVE-2020-7071.patch
Patch12: backport-0002-CVE-2020-7071.patch
Patch13: backport-0001-CVE-2021-21705.patch
Patch14: 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
@ -1097,6 +1101,9 @@ systemctl try-restart php-fpm.service >/dev/null 2>&1 || :
%changelog
* Wed Sep 29 2021 fuanan <fuanan3@huawei.com> - 8.0.0-4
- refix CVE-2020-7071 and fix CVE-2021-21705
* Tue Jun 1 2021 guoxiaoqi <guoxiaoqi2@huawei.com> - 8.0.0-3
- Fix CVE-2021-21702