From 365769366b8127aab730ce0f6eaa00e16c4dbcd1 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Tue, 12 Oct 2021 15:34:25 +0200 Subject: [PATCH] Fix #81518: Header injection via default_mimetype / default_charset We forbid setting these INI options to values containing NUL bytes, CR or LF. Closes GH-7574. --- NEWS | 4 ++++ main/main.c | 18 +++++++++++++++++- sapi/cgi/tests/bug81518a.phpt | 14 ++++++++++++++ sapi/cgi/tests/bug81518b.phpt | 11 +++++++++++ 4 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 sapi/cgi/tests/bug81518a.phpt create mode 100644 sapi/cgi/tests/bug81518b.phpt diff --git a/NEWS b/NEWS index 39b652f56f9..95cd2539fb8 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,10 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 7.4.26 +- Core: + . Fixed bug #81518 (Header injection via default_mimetype / default_charset). + (cmb) + - MySQLi: . Fixed bug #81494 (Stopped unbuffered query does not throw error). (Nikita) diff --git a/main/main.c b/main/main.c index 533417a5693..0b33b2b56c9 100644 --- a/main/main.c +++ b/main/main.c @@ -614,6 +614,10 @@ PHPAPI void (*php_internal_encoding_changed)(void) = NULL; */ static PHP_INI_MH(OnUpdateDefaultCharset) { + if (memchr(ZSTR_VAL(new_value), '\0', ZSTR_LEN(new_value)) + || strpbrk(ZSTR_VAL(new_value), "\r\n")) { + return FAILURE; + } OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); if (php_internal_encoding_changed) { php_internal_encoding_changed(); @@ -627,6 +631,18 @@ static PHP_INI_MH(OnUpdateDefaultCharset) } /* }}} */ +/* {{{ PHP_INI_MH + */ +static PHP_INI_MH(OnUpdateDefaultMimeTye) +{ + if (memchr(ZSTR_VAL(new_value), '\0', ZSTR_LEN(new_value)) + || strpbrk(ZSTR_VAL(new_value), "\r\n")) { + return FAILURE; + } + return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); +} +/* }}} */ + /* {{{ PHP_INI_MH */ static PHP_INI_MH(OnUpdateInternalEncoding) @@ -782,7 +798,7 @@ PHP_INI_BEGIN() STD_PHP_INI_ENTRY("auto_prepend_file", NULL, PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateString, auto_prepend_file, php_core_globals, core_globals) STD_PHP_INI_ENTRY("doc_root", NULL, PHP_INI_SYSTEM, OnUpdateStringUnempty, doc_root, php_core_globals, core_globals) STD_PHP_INI_ENTRY("default_charset", PHP_DEFAULT_CHARSET, PHP_INI_ALL, OnUpdateDefaultCharset, default_charset, sapi_globals_struct, sapi_globals) - STD_PHP_INI_ENTRY("default_mimetype", SAPI_DEFAULT_MIMETYPE, PHP_INI_ALL, OnUpdateString, default_mimetype, sapi_globals_struct, sapi_globals) + STD_PHP_INI_ENTRY("default_mimetype", SAPI_DEFAULT_MIMETYPE, PHP_INI_ALL, OnUpdateDefaultMimeTye, default_mimetype, sapi_globals_struct, sapi_globals) STD_PHP_INI_ENTRY("internal_encoding", NULL, PHP_INI_ALL, OnUpdateInternalEncoding, internal_encoding, php_core_globals, core_globals) STD_PHP_INI_ENTRY("input_encoding", NULL, PHP_INI_ALL, OnUpdateInputEncoding, input_encoding, php_core_globals, core_globals) STD_PHP_INI_ENTRY("output_encoding", NULL, PHP_INI_ALL, OnUpdateOutputEncoding, output_encoding, php_core_globals, core_globals) diff --git a/sapi/cgi/tests/bug81518a.phpt b/sapi/cgi/tests/bug81518a.phpt new file mode 100644 index 00000000000..8e48056df5e --- /dev/null +++ b/sapi/cgi/tests/bug81518a.phpt @@ -0,0 +1,14 @@ +--TEST-- +Bug #81518 (Header injection via default_mimetype / default_charset) +--CGI-- +--FILE-- + +--EXPECTHEADERS-- +Content-type: text/html; charset=UTF-8 +--EXPECT-- diff --git a/sapi/cgi/tests/bug81518b.phpt b/sapi/cgi/tests/bug81518b.phpt new file mode 100644 index 00000000000..75bbf7c8c08 --- /dev/null +++ b/sapi/cgi/tests/bug81518b.phpt @@ -0,0 +1,11 @@ +--TEST-- +Bug #81518 (Header injection via default_mimetype / default_charset) +--CGI-- +--FILE-- + +--EXPECTHEADERS-- +Content-type: text/html;charset=UTF-8 +--EXPECT--