From 0611be4e82887cee0de6c4cbae320d34eec946ca Mon Sep 17 00:00:00 2001 From: Derick Rethans Date: Fri, 9 Sep 2022 16:54:03 +0100 Subject: [PATCH 1/3] Fix #81727: Don't mangle HTTP variable names that clash with ones that have a specific semantic meaning. --- NEWS | 6 ++++++ ext/standard/tests/bug81727.phpt | 15 +++++++++++++++ main/php_variables.c | 14 ++++++++++++++ 3 files changed, 35 insertions(+) create mode 100644 ext/standard/tests/bug81727.phpt diff --git a/NEWS b/NEWS index b751768478a..714797a8dd7 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,11 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +29 Sep 2022, PHP 7.4.31 + +- Core: + . Fixed bug #81727: Don't mangle HTTP variable names that clash with ones + that have a specific semantic meaning. (Derick) + 09 Jun 2022, PHP 7.4.30 - mysqlnd: diff --git a/ext/standard/tests/bug81727.phpt b/ext/standard/tests/bug81727.phpt new file mode 100644 index 00000000000..71a9cb46c83 --- /dev/null +++ b/ext/standard/tests/bug81727.phpt @@ -0,0 +1,15 @@ +--TEST-- +Bug #81727: $_COOKIE name starting with ..Host/..Secure should be discarded +--COOKIE-- +..Host-test=ignore; __Host-test=correct; . Secure-test=ignore; . Elephpant=Awesome; +--FILE-- + +--EXPECT-- +array(2) { + ["__Host-test"]=> + string(7) "correct" + ["__Elephpant"]=> + string(7) "Awesome" +} diff --git a/main/php_variables.c b/main/php_variables.c index cbdc7cf171f..18f6b65a6c5 100644 --- a/main/php_variables.c +++ b/main/php_variables.c @@ -115,6 +115,20 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars } var_len = p - var; + /* Discard variable if mangling made it start with __Host-, where pre-mangling it did not start with __Host- */ + if (strncmp(var, "__Host-", sizeof("__Host-")-1) == 0 && strncmp(var_name, "__Host-", sizeof("__Host-")-1) != 0) { + zval_ptr_dtor_nogc(val); + free_alloca(var_orig, use_heap); + return; + } + + /* Discard variable if mangling made it start with __Secure-, where pre-mangling it did not start with __Secure- */ + if (strncmp(var, "__Secure-", sizeof("__Secure-")-1) == 0 && strncmp(var_name, "__Secure-", sizeof("__Secure-")-1) != 0) { + zval_ptr_dtor_nogc(val); + free_alloca(var_orig, use_heap); + return; + } + if (var_len==0) { /* empty variable name, or variable name with a space in it */ zval_ptr_dtor_nogc(val); free_alloca(var_orig, use_heap); From 404e8bdb68350931176a5bdc86fc417b34fb583d Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Mon, 25 Jul 2022 15:58:59 +0200 Subject: [PATCH 2/3] Fix #81726: phar wrapper: DOS when using quine gzip file The phar wrapper needs to uncompress the file; the uncompressed file might be compressed, so the wrapper implementation loops. This raises potential DOS issues regarding too deep or even infinite recursion (the latter are called compressed file quines[1]). We avoid that by introducing a recursion limit; we choose the somewhat arbitrary limit `3`. This issue has been reported by real_as3617 and gPayl0ad. [1] --- NEWS | 1 + ext/phar/phar.c | 16 +++++++++++----- ext/phar/tests/bug81726.gz | Bin 0 -> 204 bytes ext/phar/tests/bug81726.phpt | 14 ++++++++++++++ 4 files changed, 26 insertions(+), 5 deletions(-) create mode 100644 ext/phar/tests/bug81726.gz create mode 100644 ext/phar/tests/bug81726.phpt diff --git a/NEWS b/NEWS index 714797a8dd7..2a2a74ae3c7 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,7 @@ PHP NEWS 29 Sep 2022, PHP 7.4.31 - Core: + . Fixed bug #81726: phar wrapper: DOS when using quine gzip file. (cmb) . Fixed bug #81727: Don't mangle HTTP variable names that clash with ones that have a specific semantic meaning. (Derick) diff --git a/ext/phar/phar.c b/ext/phar/phar.c index 7cb1b063638..4a761ef7998 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -1584,7 +1584,8 @@ static int phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char const char zip_magic[] = "PK\x03\x04"; const char gz_magic[] = "\x1f\x8b\x08"; const char bz_magic[] = "BZh"; - char *pos, test = '\0'; + char *pos; + int recursion_count = 3; // arbitrary limit to avoid too deep or even infinite recursion const int window_size = 1024; char buffer[1024 + sizeof(token)]; /* a 1024 byte window + the size of the halt_compiler token (moving window) */ const zend_long readsize = sizeof(buffer) - sizeof(token); @@ -1612,8 +1613,7 @@ static int phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char MAPPHAR_ALLOC_FAIL("internal corruption of phar \"%s\" (truncated entry)") } - if (!test) { - test = '\1'; + if (recursion_count) { pos = buffer+tokenlen; if (!memcmp(pos, gz_magic, 3)) { char err = 0; @@ -1673,7 +1673,10 @@ static int phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char compression = PHAR_FILE_COMPRESSED_GZ; /* now, start over */ - test = '\0'; + if (!--recursion_count) { + MAPPHAR_ALLOC_FAIL("unable to decompress gzipped phar archive \"%s\""); + break; + } continue; } else if (!memcmp(pos, bz_magic, 3)) { php_stream_filter *filter; @@ -1711,7 +1714,10 @@ static int phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char compression = PHAR_FILE_COMPRESSED_BZ2; /* now, start over */ - test = '\0'; + if (!--recursion_count) { + MAPPHAR_ALLOC_FAIL("unable to decompress bzipped phar archive \"%s\""); + break; + } continue; } diff --git a/ext/phar/tests/bug81726.gz b/ext/phar/tests/bug81726.gz new file mode 100644 index 0000000000000000000000000000000000000000..67b41ba3b6567fb242296fbb5db1504dd562c285 GIT binary patch literal 204 zcmb2|=HOref&Yc2nR%&t=~WC25)9A(%i|Dt5_1=0XJBRc^&i0ka~VV!USk*QP&~o_ nktKo!bjW{@YyLCvGJN{)1lEBn)?BbahT(tZ|CMKe>QFcU?_ozX literal 0 HcmV?d00001 diff --git a/ext/phar/tests/bug81726.phpt b/ext/phar/tests/bug81726.phpt new file mode 100644 index 00000000000..11a148c28ea --- /dev/null +++ b/ext/phar/tests/bug81726.phpt @@ -0,0 +1,14 @@ +--TEST-- +Bug #81726 (phar wrapper: DOS when using quine gzip file) +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: fopen(phar://%s): failed to open stream: unable to decompress gzipped phar archive "%s" in %s on line %d +bool(false) From 6f586ef90fcf8fd8a31cfd7592d4df0cb454d212 Mon Sep 17 00:00:00 2001 From: Derick Rethans Date: Tue, 27 Sep 2022 14:10:02 +0100 Subject: [PATCH 3/3] Add CVEs --- NEWS | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 2a2a74ae3c7..cdb694bfa59 100644 --- a/NEWS +++ b/NEWS @@ -3,9 +3,10 @@ PHP NEWS 29 Sep 2022, PHP 7.4.31 - Core: - . Fixed bug #81726: phar wrapper: DOS when using quine gzip file. (cmb) + . Fixed bug #81726: phar wrapper: DOS when using quine gzip file. + (CVE-2022-31628). (cmb) . Fixed bug #81727: Don't mangle HTTP variable names that clash with ones - that have a specific semantic meaning. (Derick) + that have a specific semantic meaning. (CVE-2022-31629). (Derick) 09 Jun 2022, PHP 7.4.30