From c840f71524067aa474c00c3eacfb83bd860bfc8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Mon, 23 Jan 2023 21:15:24 +0100 Subject: [PATCH 01/13] crypt: Fix validation of malformed BCrypt hashes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PHP’s implementation of crypt_blowfish differs from the upstream Openwall version by adding a “PHP Hack”, which allows one to cut short the BCrypt salt by including a `$` character within the characters that represent the salt. Hashes that are affected by the “PHP Hack” may erroneously validate any password as valid when used with `password_verify` and when comparing the return value of `crypt()` against the input. The PHP Hack exists since the first version of PHP’s own crypt_blowfish implementation that was added in 1e820eca02dcf322b41fd2fe4ed2a6b8309f8ab5. No clear reason is given for the PHP Hack’s existence. This commit removes it, because BCrypt hashes containing a `$` character in their salt are not valid BCrypt hashes. --- ext/standard/crypt_blowfish.c | 8 -- .../tests/crypt/bcrypt_salt_dollar.phpt | 82 +++++++++++++++++++ 2 files changed, 82 insertions(+), 8 deletions(-) create mode 100644 ext/standard/tests/crypt/bcrypt_salt_dollar.phpt diff --git a/ext/standard/crypt_blowfish.c b/ext/standard/crypt_blowfish.c index 3806a290aee40..351d40308089e 100644 --- a/ext/standard/crypt_blowfish.c +++ b/ext/standard/crypt_blowfish.c @@ -371,7 +371,6 @@ static const unsigned char BF_atoi64[0x60] = { #define BF_safe_atoi64(dst, src) \ { \ tmp = (unsigned char)(src); \ - if (tmp == '$') break; /* PHP hack */ \ if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \ tmp = BF_atoi64[tmp]; \ if (tmp > 63) return -1; \ @@ -399,13 +398,6 @@ static int BF_decode(BF_word *dst, const char *src, int size) *dptr++ = ((c3 & 0x03) << 6) | c4; } while (dptr < end); - if (end - dptr == size) { - return -1; - } - - while (dptr < end) /* PHP hack */ - *dptr++ = 0; - return 0; } diff --git a/ext/standard/tests/crypt/bcrypt_salt_dollar.phpt b/ext/standard/tests/crypt/bcrypt_salt_dollar.phpt new file mode 100644 index 0000000000000..32e335f4b087e --- /dev/null +++ b/ext/standard/tests/crypt/bcrypt_salt_dollar.phpt @@ -0,0 +1,82 @@ +--TEST-- +bcrypt correctly rejects salts containing $ +--FILE-- + +--EXPECT-- +string(8) "$2y$04$$" +string(2) "*0" +bool(false) +string(9) "$2y$04$0$" +string(2) "*0" +bool(false) +string(10) "$2y$04$00$" +string(2) "*0" +bool(false) +string(11) "$2y$04$000$" +string(2) "*0" +bool(false) +string(12) "$2y$04$0000$" +string(2) "*0" +bool(false) +string(13) "$2y$04$00000$" +string(2) "*0" +bool(false) +string(14) "$2y$04$000000$" +string(2) "*0" +bool(false) +string(15) "$2y$04$0000000$" +string(2) "*0" +bool(false) +string(16) "$2y$04$00000000$" +string(2) "*0" +bool(false) +string(17) "$2y$04$000000000$" +string(2) "*0" +bool(false) +string(18) "$2y$04$0000000000$" +string(2) "*0" +bool(false) +string(19) "$2y$04$00000000000$" +string(2) "*0" +bool(false) +string(20) "$2y$04$000000000000$" +string(2) "*0" +bool(false) +string(21) "$2y$04$0000000000000$" +string(2) "*0" +bool(false) +string(22) "$2y$04$00000000000000$" +string(2) "*0" +bool(false) +string(23) "$2y$04$000000000000000$" +string(2) "*0" +bool(false) +string(24) "$2y$04$0000000000000000$" +string(2) "*0" +bool(false) +string(25) "$2y$04$00000000000000000$" +string(2) "*0" +bool(false) +string(26) "$2y$04$000000000000000000$" +string(2) "*0" +bool(false) +string(27) "$2y$04$0000000000000000000$" +string(2) "*0" +bool(false) +string(28) "$2y$04$00000000000000000000$" +string(2) "*0" +bool(false) +string(29) "$2y$04$000000000000000000000$" +string(2) "*0" +bool(false) +string(30) "$2y$04$0000000000000000000000$" +string(60) "$2y$04$000000000000000000000u2a2UpVexIt9k3FMJeAVr3c04F5tcI8K" +bool(false) From a92acbad873a05470af1a47cb785a18eadd827b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Mon, 23 Jan 2023 22:13:57 +0100 Subject: [PATCH 02/13] crypt: Fix possible buffer overread in php_crypt() --- ext/standard/crypt.c | 1 + ext/standard/tests/password/password_bcrypt_short.phpt | 8 ++++++++ 2 files changed, 9 insertions(+) create mode 100644 ext/standard/tests/password/password_bcrypt_short.phpt diff --git a/ext/standard/crypt.c b/ext/standard/crypt.c index 8c105cf910e85..8316c8b960639 100644 --- a/ext/standard/crypt.c +++ b/ext/standard/crypt.c @@ -135,6 +135,7 @@ PHPAPI zend_string *php_crypt(const char *password, const int pass_len, const ch } else if ( salt[0] == '$' && salt[1] == '2' && + salt[2] != 0 && salt[3] == '$') { char output[PHP_MAX_SALT_LEN + 1]; diff --git a/ext/standard/tests/password/password_bcrypt_short.phpt b/ext/standard/tests/password/password_bcrypt_short.phpt new file mode 100644 index 0000000000000..085bc8a239045 --- /dev/null +++ b/ext/standard/tests/password/password_bcrypt_short.phpt @@ -0,0 +1,8 @@ +--TEST-- +Test that password_hash() does not overread buffers when a short hash is passed +--FILE-- + +--EXPECT-- +bool(false) From af2ddc64262216848d2e95108c121967a2b0a8a9 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Sun, 12 Feb 2023 20:53:06 -0700 Subject: [PATCH 03/13] Update NEWS --- NEWS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NEWS b/NEWS index 907a06b90ec97..82d773a3b2a23 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 8.0.28 +- Core: + . Fixed bug #81744 (Password_verify() always return true with some hash). + (CVE-2023-0567). (Tim Düsterhus) 05 Jan 2023, PHP 8.0.27 From ec10b28d64decbc54aa1e585dce580f0bd7a5953 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Fri, 27 Jan 2023 19:28:27 +0100 Subject: [PATCH 04/13] Fix array overrun when appending slash to paths Fix it by extending the array sizes by one character. As the input is limited to the maximum path length, there will always be place to append the slash. As the php_check_specific_open_basedir() simply uses the strings to compare against each other, no new failures related to too long paths are introduced. We'll let the DOM and XML case handle a potentially too long path in the library code. --- ext/dom/document.c | 2 +- ext/xmlreader/php_xmlreader.c | 2 +- main/fopen_wrappers.c | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ext/dom/document.c b/ext/dom/document.c index dbbabb8bffde6..fa6a6377ad5ce 100644 --- a/ext/dom/document.c +++ b/ext/dom/document.c @@ -1174,7 +1174,7 @@ static xmlDocPtr dom_document_parser(zval *id, int mode, char *source, size_t so int validate, recover, resolve_externals, keep_blanks, substitute_ent; int resolved_path_len; int old_error_reporting = 0; - char *directory=NULL, resolved_path[MAXPATHLEN]; + char *directory=NULL, resolved_path[MAXPATHLEN + 1]; if (id != NULL) { intern = Z_DOMOBJ_P(id); diff --git a/ext/xmlreader/php_xmlreader.c b/ext/xmlreader/php_xmlreader.c index ecc52aa1d6f4c..d8f8105010c71 100644 --- a/ext/xmlreader/php_xmlreader.c +++ b/ext/xmlreader/php_xmlreader.c @@ -1024,7 +1024,7 @@ PHP_METHOD(XMLReader, XML) xmlreader_object *intern = NULL; char *source, *uri = NULL, *encoding = NULL; int resolved_path_len, ret = 0; - char *directory=NULL, resolved_path[MAXPATHLEN]; + char *directory=NULL, resolved_path[MAXPATHLEN + 1]; xmlParserInputBufferPtr inputbfr; xmlTextReaderPtr reader; diff --git a/main/fopen_wrappers.c b/main/fopen_wrappers.c index 39a9c82d5984e..5e4a619c8fe70 100644 --- a/main/fopen_wrappers.c +++ b/main/fopen_wrappers.c @@ -129,10 +129,10 @@ PHPAPI ZEND_INI_MH(OnUpdateBaseDir) */ PHPAPI int php_check_specific_open_basedir(const char *basedir, const char *path) { - char resolved_name[MAXPATHLEN]; - char resolved_basedir[MAXPATHLEN]; + char resolved_name[MAXPATHLEN + 1]; + char resolved_basedir[MAXPATHLEN + 1]; char local_open_basedir[MAXPATHLEN]; - char path_tmp[MAXPATHLEN]; + char path_tmp[MAXPATHLEN + 1]; char *path_file; size_t resolved_basedir_len; size_t resolved_name_len; From b5ccaaf613066e3862cca86dbe1f39d3c376649a Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Sun, 12 Feb 2023 21:04:31 -0700 Subject: [PATCH 05/13] Update NEWS --- NEWS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS b/NEWS index 82d773a3b2a23..a6dfbec2629dc 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,8 @@ PHP NEWS - Core: . Fixed bug #81744 (Password_verify() always return true with some hash). (CVE-2023-0567). (Tim Düsterhus) + . Fixed bug #81746 (1-byte array overrun in common path resolve code). + (CVE-2023-0568). (Niels Dossche) 05 Jan 2023, PHP 8.0.27 From e45850c195dcd5534394cf357a3f776d4916b655 Mon Sep 17 00:00:00 2001 From: Jakub Zelenka Date: Thu, 19 Jan 2023 14:11:18 +0000 Subject: [PATCH 06/13] Fix repeated warning for file uploads limit exceeding --- main/rfc1867.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/main/rfc1867.c b/main/rfc1867.c index c2f606c64aa1a..b43cfae5a1e2f 100644 --- a/main/rfc1867.c +++ b/main/rfc1867.c @@ -911,7 +911,10 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ skip_upload = 1; } else if (upload_cnt <= 0) { skip_upload = 1; - sapi_module.sapi_error(E_WARNING, "Maximum number of allowable file uploads has been exceeded"); + if (upload_cnt == 0) { + --upload_cnt; + sapi_module.sapi_error(E_WARNING, "Maximum number of allowable file uploads has been exceeded"); + } } /* Return with an error if the posted data is garbled */ From 716de0cff539f46294ef70fe75d548cd66766370 Mon Sep 17 00:00:00 2001 From: Jakub Zelenka Date: Thu, 19 Jan 2023 14:31:25 +0000 Subject: [PATCH 07/13] Introduce max_multipart_body_parts INI This fixes GHSA-54hq-v5wp-fqgv DOS vulnerabality by limitting number of parsed multipart body parts as currently all parts were always parsed. --- main/main.c | 1 + main/rfc1867.c | 11 ++ ...-54hq-v5wp-fqgv-max-body-parts-custom.phpt | 53 +++++++++ ...54hq-v5wp-fqgv-max-body-parts-default.phpt | 54 +++++++++ .../ghsa-54hq-v5wp-fqgv-max-file-uploads.phpt | 52 +++++++++ sapi/fpm/tests/tester.inc | 106 +++++++++++++++--- 6 files changed, 262 insertions(+), 15 deletions(-) create mode 100644 sapi/fpm/tests/ghsa-54hq-v5wp-fqgv-max-body-parts-custom.phpt create mode 100644 sapi/fpm/tests/ghsa-54hq-v5wp-fqgv-max-body-parts-default.phpt create mode 100644 sapi/fpm/tests/ghsa-54hq-v5wp-fqgv-max-file-uploads.phpt diff --git a/main/main.c b/main/main.c index 40684f32dc146..c58ea58bf5ac7 100644 --- a/main/main.c +++ b/main/main.c @@ -751,6 +751,7 @@ PHP_INI_BEGIN() PHP_INI_ENTRY("disable_functions", "", PHP_INI_SYSTEM, NULL) PHP_INI_ENTRY("disable_classes", "", PHP_INI_SYSTEM, NULL) PHP_INI_ENTRY("max_file_uploads", "20", PHP_INI_SYSTEM|PHP_INI_PERDIR, NULL) + PHP_INI_ENTRY("max_multipart_body_parts", "-1", PHP_INI_SYSTEM|PHP_INI_PERDIR, NULL) STD_PHP_INI_BOOLEAN("allow_url_fopen", "1", PHP_INI_SYSTEM, OnUpdateBool, allow_url_fopen, php_core_globals, core_globals) STD_PHP_INI_BOOLEAN("allow_url_include", "0", PHP_INI_SYSTEM, OnUpdateBool, allow_url_include, php_core_globals, core_globals) diff --git a/main/rfc1867.c b/main/rfc1867.c index b43cfae5a1e2f..3086e8da3dbe7 100644 --- a/main/rfc1867.c +++ b/main/rfc1867.c @@ -687,6 +687,7 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ void *event_extra_data = NULL; unsigned int llen = 0; int upload_cnt = INI_INT("max_file_uploads"); + int body_parts_cnt = INI_INT("max_multipart_body_parts"); const zend_encoding *internal_encoding = zend_multibyte_get_internal_encoding(); php_rfc1867_getword_t getword; php_rfc1867_getword_conf_t getword_conf; @@ -708,6 +709,11 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ return; } + if (body_parts_cnt < 0) { + body_parts_cnt = PG(max_input_vars) + upload_cnt; + } + int body_parts_limit = body_parts_cnt; + /* Get the boundary */ boundary = strstr(content_type_dup, "boundary"); if (!boundary) { @@ -792,6 +798,11 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ char *pair = NULL; int end = 0; + if (--body_parts_cnt < 0) { + php_error_docref(NULL, E_WARNING, "Multipart body parts limit exceeded %d. To increase the limit change max_multipart_body_parts in php.ini.", body_parts_limit); + goto fileupload_done; + } + while (isspace(*cd)) { ++cd; } diff --git a/sapi/fpm/tests/ghsa-54hq-v5wp-fqgv-max-body-parts-custom.phpt b/sapi/fpm/tests/ghsa-54hq-v5wp-fqgv-max-body-parts-custom.phpt new file mode 100644 index 0000000000000..d2239ac3c410b --- /dev/null +++ b/sapi/fpm/tests/ghsa-54hq-v5wp-fqgv-max-body-parts-custom.phpt @@ -0,0 +1,53 @@ +--TEST-- +FPM: GHSA-54hq-v5wp-fqgv - max_multipart_body_parts ini custom value +--SKIPIF-- + +--FILE-- +start(); +$tester->expectLogStartNotices(); +echo $tester + ->request(stdin: [ + 'parts' => [ + 'count' => 30, + ] + ]) + ->getBody(); +$tester->terminate(); +$tester->close(); + +?> +--EXPECT-- +Warning: Unknown: Multipart body parts limit exceeded 10. To increase the limit change max_multipart_body_parts in php.ini. in Unknown on line 0 +int(10) +--CLEAN-- + diff --git a/sapi/fpm/tests/ghsa-54hq-v5wp-fqgv-max-body-parts-default.phpt b/sapi/fpm/tests/ghsa-54hq-v5wp-fqgv-max-body-parts-default.phpt new file mode 100644 index 0000000000000..42b5afbf9ee7d --- /dev/null +++ b/sapi/fpm/tests/ghsa-54hq-v5wp-fqgv-max-body-parts-default.phpt @@ -0,0 +1,54 @@ +--TEST-- +FPM: GHSA-54hq-v5wp-fqgv - max_multipart_body_parts ini default +--SKIPIF-- + +--FILE-- +start(); +$tester->expectLogStartNotices(); +echo $tester + ->request(stdin: [ + 'parts' => [ + 'count' => 30, + ] + ]) + ->getBody(); +$tester->terminate(); +$tester->close(); + +?> +--EXPECT-- +Warning: Unknown: Input variables exceeded 20. To increase the limit change max_input_vars in php.ini. in Unknown on line 0 + +Warning: Unknown: Multipart body parts limit exceeded 25. To increase the limit change max_multipart_body_parts in php.ini. in Unknown on line 0 +int(20) +--CLEAN-- + diff --git a/sapi/fpm/tests/ghsa-54hq-v5wp-fqgv-max-file-uploads.phpt b/sapi/fpm/tests/ghsa-54hq-v5wp-fqgv-max-file-uploads.phpt new file mode 100644 index 0000000000000..da81174c72806 --- /dev/null +++ b/sapi/fpm/tests/ghsa-54hq-v5wp-fqgv-max-file-uploads.phpt @@ -0,0 +1,52 @@ +--TEST-- +FPM: GHSA-54hq-v5wp-fqgv - exceeding max_file_uploads +--SKIPIF-- + +--FILE-- +start(); +$tester->expectLogStartNotices(); +echo $tester + ->request(stdin: [ + 'parts' => [ + 'count' => 10, + 'param' => 'filename' + ] + ]) + ->getBody(); +$tester->terminate(); +$tester->close(); + +?> +--EXPECT-- +Warning: Maximum number of allowable file uploads has been exceeded in Unknown on line 0 +int(5) +--CLEAN-- + diff --git a/sapi/fpm/tests/tester.inc b/sapi/fpm/tests/tester.inc index 6197cdba53f5c..e51aa0f691435 100644 --- a/sapi/fpm/tests/tester.inc +++ b/sapi/fpm/tests/tester.inc @@ -567,13 +567,17 @@ class Tester * @param string $query * @param array $headers * @param string|null $uri + * @param string|null $scriptFilename + * @param string|null $stdin * * @return array */ private function getRequestParams( string $query = '', array $headers = [], - string $uri = null + string $uri = null, + string $scriptFilename = null, + ?string $stdin = null ): array { if (is_null($uri)) { $uri = $this->makeSourceFile(); @@ -582,8 +586,8 @@ class Tester $params = array_merge( [ 'GATEWAY_INTERFACE' => 'FastCGI/1.0', - 'REQUEST_METHOD' => 'GET', - 'SCRIPT_FILENAME' => $uri, + 'REQUEST_METHOD' => is_null($stdin) ? 'GET' : 'POST', + 'SCRIPT_FILENAME' => $scriptFilename ?: $uri, 'SCRIPT_NAME' => $uri, 'QUERY_STRING' => $query, 'REQUEST_URI' => $uri . ($query ? '?' . $query : ""), @@ -597,7 +601,7 @@ class Tester 'SERVER_PROTOCOL' => 'HTTP/1.1', 'DOCUMENT_ROOT' => __DIR__, 'CONTENT_TYPE' => '', - 'CONTENT_LENGTH' => 0 + 'CONTENT_LENGTH' => strlen($stdin ?? "") // Default to 0 ], $headers ); @@ -607,20 +611,86 @@ class Tester }); } + /** + * Parse stdin and generate data for multipart config. + * + * @param array $stdin + * @param array $headers + * + * @return void + * @throws \Exception + */ + private function parseStdin(array $stdin, array &$headers) + { + $parts = $stdin['parts'] ?? null; + if (empty($parts)) { + throw new \Exception('The stdin array needs to contain parts'); + } + $boundary = $stdin['boundary'] ?? 'AaB03x'; + if ( ! isset($headers['CONTENT_TYPE'])) { + $headers['CONTENT_TYPE'] = 'multipart/form-data; boundary=' . $boundary; + } + $count = $parts['count'] ?? null; + if ( ! is_null($count)) { + $dispositionType = $parts['disposition'] ?? 'form-data'; + $dispositionParam = $parts['param'] ?? 'name'; + $namePrefix = $parts['prefix'] ?? 'f'; + $nameSuffix = $parts['suffix'] ?? ''; + $value = $parts['value'] ?? 'test'; + $parts = []; + for ($i = 0; $i < $count; $i++) { + $parts[] = [ + 'disposition' => $dispositionType, + 'param' => $dispositionParam, + 'name' => "$namePrefix$i$nameSuffix", + 'value' => $value + ]; + } + } + $out = ''; + $nl = "\r\n"; + foreach ($parts as $part) { + if (!is_array($part)) { + $part = ['name' => $part]; + } elseif ( ! isset($part['name'])) { + throw new \Exception('Each part has to have a name'); + } + $name = $part['name']; + $dispositionType = $part['disposition'] ?? 'form-data'; + $dispositionParam = $part['param'] ?? 'name'; + $value = $part['value'] ?? 'test'; + $partHeaders = $part['headers'] ?? []; + + $out .= "--$boundary$nl"; + $out .= "Content-disposition: $dispositionType; $dispositionParam=\"$name\"$nl"; + foreach ($partHeaders as $headerName => $headerValue) { + $out .= "$headerName: $headerValue$nl"; + } + $out .= $nl; + $out .= "$value$nl"; + } + $out .= "--$boundary--$nl"; + + return $out; + } + /** * Execute request. * - * @param string $query - * @param array $headers - * @param string|null $uri - * @param string|null $address - * @param string|null $successMessage - * @param string|null $errorMessage - * @param bool $connKeepAlive - * @param bool $expectError - * @param int $readLimit + * @param string $query + * @param array $headers + * @param string|null $uri + * @param string|null $address + * @param string|null $successMessage + * @param string|null $errorMessage + * @param bool $connKeepAlive + * @param string|null $scriptFilename = null + * @param string|array|null $stdin = null + * @param bool $expectError + * @param int $readLimit * * @return Response + * @throws \Exception */ public function request( string $query = '', @@ -630,6 +700,8 @@ class Tester string $successMessage = null, string $errorMessage = null, bool $connKeepAlive = false, + string $scriptFilename = null, + string|array $stdin = null, bool $expectError = false, int $readLimit = -1, ): Response { @@ -637,12 +709,16 @@ class Tester return new Response(null, true); } - $params = $this->getRequestParams($query, $headers, $uri); + if (is_array($stdin)) { + $stdin = $this->parseStdin($stdin, $headers); + } + + $params = $this->getRequestParams($query, $headers, $uri, $scriptFilename, $stdin); $this->trace('Request params', $params); try { $this->response = new Response( - $this->getClient($address, $connKeepAlive)->request_data($params, false, $readLimit) + $this->getClient($address, $connKeepAlive)->request_data($params, $stdin, $readLimit) ); if ($expectError) { $this->error('Expected request error but the request was successful'); From 054c7b09f91946c0618171072fc650af2ff61f0a Mon Sep 17 00:00:00 2001 From: Jakub Zelenka Date: Tue, 14 Feb 2023 10:23:59 +0000 Subject: [PATCH 08/13] Update NEWS --- NEWS | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NEWS b/NEWS index a6dfbec2629dc..f14370becbdb0 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,10 @@ PHP NEWS . Fixed bug #81746 (1-byte array overrun in common path resolve code). (CVE-2023-0568). (Niels Dossche) +- FPM + . Fixed bug GHSA-54hq-v5wp-fqgv (DOS vulnerability when parsing multipart + request body). (CVE-2023-0662) (Jakub Zelenka) + 05 Jan 2023, PHP 8.0.27 - PDO/SQLite: From caaaf759908a7366c877399273cafdd246c5402c Mon Sep 17 00:00:00 2001 From: Jakub Zelenka Date: Tue, 14 Feb 2023 10:33:56 +0000 Subject: [PATCH 09/13] Fix incorrect character in NEWS --- NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS b/NEWS index f14370becbdb0..d0a31784b0141 100644 --- a/NEWS +++ b/NEWS @@ -10,7 +10,7 @@ PHP NEWS - FPM . Fixed bug GHSA-54hq-v5wp-fqgv (DOS vulnerability when parsing multipart - request body). (CVE-2023-0662) (Jakub Zelenka) + request body). (CVE-2023-0662) (Jakub Zelenka) 05 Jan 2023, PHP 8.0.27 From eef29d434a302904dc0310032c38980b0dfaded0 Mon Sep 17 00:00:00 2001 From: Jakub Zelenka Date: Tue, 14 Feb 2023 10:42:36 +0000 Subject: [PATCH 10/13] Change NEWS for GHSA-54hq-v5wp-fqgv as it is for all SAPIs --- NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS b/NEWS index d0a31784b0141..25a6a6e5d031a 100644 --- a/NEWS +++ b/NEWS @@ -8,7 +8,7 @@ PHP NEWS . Fixed bug #81746 (1-byte array overrun in common path resolve code). (CVE-2023-0568). (Niels Dossche) -- FPM +- SAPI . Fixed bug GHSA-54hq-v5wp-fqgv (DOS vulnerability when parsing multipart request body). (CVE-2023-0662) (Jakub Zelenka) From 937b1e38e2677cdc07ddc93e228765469f647e73 Mon Sep 17 00:00:00 2001 From: Jakub Zelenka Date: Tue, 14 Feb 2023 10:46:48 +0000 Subject: [PATCH 11/13] Fix missing colon in NEWS --- NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 25a6a6e5d031a..ed5df77edfc82 100644 --- a/NEWS +++ b/NEWS @@ -8,7 +8,7 @@ PHP NEWS . Fixed bug #81746 (1-byte array overrun in common path resolve code). (CVE-2023-0568). (Niels Dossche) -- SAPI +- SAPI: . Fixed bug GHSA-54hq-v5wp-fqgv (DOS vulnerability when parsing multipart request body). (CVE-2023-0662) (Jakub Zelenka) From a48e064a22a59b6f1af51b51e401c57093df9c25 Mon Sep 17 00:00:00 2001 From: Gabriel Caruso Date: Tue, 14 Feb 2023 11:03:17 +0000 Subject: [PATCH 12/13] Update NEWS for PHP 8.0.28 --- NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS b/NEWS index ed5df77edfc82..7e4035eafe131 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,6 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -?? ??? ????, PHP 8.0.28 +14 Feb 2023, PHP 8.0.28 - Core: . Fixed bug #81744 (Password_verify() always return true with some hash). From 12b5ba0b1d87d2dfdb4ee213cb5d122c921f3f2f Mon Sep 17 00:00:00 2001 From: Gabriel Caruso Date: Tue, 14 Feb 2023 11:03:21 +0000 Subject: [PATCH 13/13] Update versions for PHP 8.0.28 --- Zend/zend.h | 2 +- configure.ac | 2 +- main/php_version.h | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Zend/zend.h b/Zend/zend.h index 11bf4fc29f1af..4595ea86eeab4 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -20,7 +20,7 @@ #ifndef ZEND_H #define ZEND_H -#define ZEND_VERSION "4.0.27-dev" +#define ZEND_VERSION "4.0.28" #define ZEND_ENGINE_3 diff --git a/configure.ac b/configure.ac index 23d46ae8d10a6..316c0ec46bcf7 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ dnl Basic autoconf initialization, generation of config.nice. dnl ---------------------------------------------------------------------------- AC_PREREQ([2.68]) -AC_INIT([PHP],[8.0.27-dev],[https://bugs.php.net],[php],[https://www.php.net]) +AC_INIT([PHP],[8.0.28],[https://bugs.php.net],[php],[https://www.php.net]) AC_CONFIG_SRCDIR([main/php_version.h]) AC_CONFIG_AUX_DIR([build]) AC_PRESERVE_HELP_ORDER diff --git a/main/php_version.h b/main/php_version.h index 22111976ccb97..4f53739144d43 100644 --- a/main/php_version.h +++ b/main/php_version.h @@ -2,7 +2,7 @@ /* edit configure.ac to change version number */ #define PHP_MAJOR_VERSION 8 #define PHP_MINOR_VERSION 0 -#define PHP_RELEASE_VERSION 27 -#define PHP_EXTRA_VERSION "-dev" -#define PHP_VERSION "8.0.27-dev" -#define PHP_VERSION_ID 80027 +#define PHP_RELEASE_VERSION 28 +#define PHP_EXTRA_VERSION "" +#define PHP_VERSION "8.0.28" +#define PHP_VERSION_ID 80028