From 163016ff34464c2369fb9d7c7c527a891d0bab8d Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Thu, 23 Mar 2023 14:35:50 +0100 Subject: [PATCH] Disallow parent dir components (..) in open_basedir() at runtime Fix GH-10469 --- Zend/tests/gh10469.phpt | 23 +++++++++++++++++++++++ main/fopen_wrappers.c | 26 ++++++++++++++++++++++---- 2 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 Zend/tests/gh10469.phpt diff --git a/Zend/tests/gh10469.phpt b/Zend/tests/gh10469.phpt new file mode 100644 index 0000000000000..dd5c0fcd71a3e --- /dev/null +++ b/Zend/tests/gh10469.phpt @@ -0,0 +1,23 @@ +--TEST-- +GH-10469: Disallow open_basedir() with parent dir components (..) +--FILE-- + +--CLEAN-- + +--EXPECTF-- +string(%d) "%stests" diff --git a/main/fopen_wrappers.c b/main/fopen_wrappers.c index efb110171b148..ef08d8dc73ecb 100644 --- a/main/fopen_wrappers.c +++ b/main/fopen_wrappers.c @@ -101,11 +101,29 @@ PHPAPI ZEND_INI_MH(OnUpdateBaseDir) *end = '\0'; end++; } - if (ptr[0] == '.' && ptr[1] == '.' && (ptr[2] == '\0' || IS_SLASH(ptr[2]))) { - /* Don't allow paths with a leading .. path component to be set at runtime */ - efree(pathbuf); - return FAILURE; + /* Don't allow paths with a parent dir component (..) to be set at runtime */ + char *substr_pos = ptr; + while (true) { + // Check if we have a .. path component + if (substr_pos[0] == '.' + && substr_pos[1] == '.' + && (substr_pos[2] == '\0' || IS_SLASH(substr_pos[2]))) { + efree(pathbuf); + return FAILURE; + } + // Skip to the next path component + while (true) { + substr_pos++; + if (*substr_pos == '\0' || *substr_pos == DEFAULT_DIR_SEPARATOR) { + goto no_parent_dir_component; + } else if (IS_SLASH(*substr_pos)) { + // Also skip the slash + substr_pos++; + break; + } + } } +no_parent_dir_component: if (php_check_open_basedir_ex(ptr, 0) != 0) { /* At least one portion of this open_basedir is less restrictive than the prior one, FAIL */ efree(pathbuf);