!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:
commit
c075eb653b
211
backport-0001-CVE-2020-7071.patch
Normal file
211
backport-0001-CVE-2020-7071.patch
Normal 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,
|
||||
58
backport-0001-CVE-2021-21705.patch
Normal file
58
backport-0001-CVE-2021-21705.patch
Normal 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
|
||||
|
||||
36
backport-0002-CVE-2020-7071.patch
Normal file
36
backport-0002-CVE-2020-7071.patch
Normal 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)
|
||||
{
|
||||
28
backport-0002-CVE-2021-21705.patch
Normal file
28
backport-0002-CVE-2021-21705.patch
Normal 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
|
||||
|
||||
9
php.spec
9
php.spec
@ -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
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user