From 658820654f5789a786a5537c1b43991744b83d2c Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 26 Dec 2016 22:01:51 +0100 Subject: [ticket/security-203] Fully validate version check data in version helper This will also take care of SECURITY-204 as it's the same underlying issue. Admins still need to ensure they don't visit malicious sites for URLs provided by extensions. SECURITY-203 --- phpBB/phpbb/version_helper.php | 107 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/version_helper.php b/phpBB/phpbb/version_helper.php index a1e66ba8fe..dc95f6d001 100644 --- a/phpBB/phpbb/version_helper.php +++ b/phpBB/phpbb/version_helper.php @@ -61,6 +61,23 @@ class version_helper /** @var \phpbb\user */ protected $user; + protected $version_schema = array( + 'stable' => array( + 'current' => 'version', + 'download' => 'url', + 'announcement' => 'url', + 'eol' => 'url', + 'security' => 'bool', + ), + 'unstable' => array( + 'current' => 'version', + 'download' => 'url', + 'announcement' => 'url', + 'eol' => 'url', + 'security' => 'bool', + ), + ); + /** * Constructor * @@ -298,9 +315,99 @@ class version_helper $info['stable'] = (empty($info['stable'])) ? array() : $info['stable']; $info['unstable'] = (empty($info['unstable'])) ? $info['stable'] : $info['unstable']; + $this->validate_versions($info); + $this->cache->put($cache_file, $info, 86400); // 24 hours } return $info; } + + /** + * Validate versions info input + * + * @param array $versions_info Decoded json data array. Will be modified + * and cleaned by this method + */ + public function validate_versions(&$versions_info) + { + $array_diff = array_diff_key($versions_info, array($this->version_schema)); + + // Remove excessive data + if (count($array_diff) > 0) + { + $old_versions_info = $versions_info; + $versions_info = array( + 'stable' => !empty($old_versions_info['stable']) ? $old_versions_info['stable'] : array(), + 'unstable' => !empty($old_versions_info['unstable']) ? $old_versions_info['unstable'] : array(), + ); + unset($old_versions_info); + } + + foreach ($versions_info as $stability_type => &$versions_data) + { + foreach ($versions_data as $branch => &$version_data) + { + if (!preg_match('/^[0-9]+\.[0-9]+$/', $branch)) + { + unset($versions_data[$branch]); + continue; + } + + $stability_diff = array_diff_key($version_data, $this->version_schema[$stability_type]); + + if (count($stability_diff) > 0) + { + $old_version_data = $version_data; + $version_data = array(); + foreach ($this->version_schema[$stability_type] as $key => $value) + { + if (isset($old_version_data[$key]) || $old_version_data[$key] === null) + { + $version_data[$key] = $old_version_data[$key]; + } + } + unset($old_version_data); + } + + foreach ($version_data as $key => &$value) + { + if (!isset($this->version_schema[$stability_type][$key])) + { + unset($version_data[$key]); + throw new \RuntimeException($this->user->lang('VERSIONCHECK_INVALID_ENTRY')); + } + + switch ($this->version_schema[$stability_type][$key]) + { + case 'bool': + $value = (bool) $value; + break; + + case 'url': + if (!empty($value) && !preg_match('#^' . get_preg_expression('url') . '$#iu', $value) && + !preg_match('#^' . get_preg_expression('www_url') . '$#iu', $value)) + { + $value = ''; + throw new \RuntimeException($this->user->lang('VERSIONCHECK_INVALID_URL')); + } + break; + + case 'version': + $value = $value ?: ''; + if (!preg_match(get_preg_expression('semantic_version'), $value)) + { + $value = ''; + throw new \RuntimeException($this->user->lang('VERSIONCHECK_INVALID_VERSION')); + } + break; + + default: + // Shouldn't be possible to trigger this + throw new \RuntimeException($this->user->lang('VERSIONCHECK_INVALID_ENTRY')); + } + } + } + } + } } -- cgit v1.2.1 From ad251e4590744b0927019ae935c92c7101aa7678 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Tue, 27 Dec 2016 18:11:31 +0100 Subject: [ticket/security-203] Do not add null values to versions info Also stopped using reference for validate_versions() method argument. SECURTIY-203 --- phpBB/phpbb/version_helper.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/version_helper.php b/phpBB/phpbb/version_helper.php index dc95f6d001..e2d90af04a 100644 --- a/phpBB/phpbb/version_helper.php +++ b/phpBB/phpbb/version_helper.php @@ -315,7 +315,7 @@ class version_helper $info['stable'] = (empty($info['stable'])) ? array() : $info['stable']; $info['unstable'] = (empty($info['unstable'])) ? $info['stable'] : $info['unstable']; - $this->validate_versions($info); + $info = $this->validate_versions($info); $this->cache->put($cache_file, $info, 86400); // 24 hours } @@ -328,8 +328,10 @@ class version_helper * * @param array $versions_info Decoded json data array. Will be modified * and cleaned by this method + * + * @return array Versions info array */ - public function validate_versions(&$versions_info) + public function validate_versions($versions_info) { $array_diff = array_diff_key($versions_info, array($this->version_schema)); @@ -362,7 +364,7 @@ class version_helper $version_data = array(); foreach ($this->version_schema[$stability_type] as $key => $value) { - if (isset($old_version_data[$key]) || $old_version_data[$key] === null) + if (isset($old_version_data[$key])) { $version_data[$key] = $old_version_data[$key]; } @@ -388,16 +390,13 @@ class version_helper if (!empty($value) && !preg_match('#^' . get_preg_expression('url') . '$#iu', $value) && !preg_match('#^' . get_preg_expression('www_url') . '$#iu', $value)) { - $value = ''; throw new \RuntimeException($this->user->lang('VERSIONCHECK_INVALID_URL')); } break; case 'version': - $value = $value ?: ''; - if (!preg_match(get_preg_expression('semantic_version'), $value)) + if (!empty($value) && !preg_match(get_preg_expression('semantic_version'), $value)) { - $value = ''; throw new \RuntimeException($this->user->lang('VERSIONCHECK_INVALID_VERSION')); } break; @@ -409,5 +408,7 @@ class version_helper } } } + + return $versions_info; } } -- cgit v1.2.1 From 90a77ba9d3e97718e9da7d1ee95ece4e756d26b7 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Tue, 27 Dec 2016 18:18:20 +0100 Subject: [ticket/security-203] Allow more characters for branch names SECURITY-203 --- phpBB/phpbb/version_helper.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB/phpbb') diff --git a/phpBB/phpbb/version_helper.php b/phpBB/phpbb/version_helper.php index e2d90af04a..70a009ed3d 100644 --- a/phpBB/phpbb/version_helper.php +++ b/phpBB/phpbb/version_helper.php @@ -243,7 +243,7 @@ class version_helper * * @param bool $force_update Ignores cached data. Defaults to false. * @param bool $force_cache Force the use of the cache. Override $force_update. - * @return string Version info + * @return array Version info * @throws \RuntimeException */ public function get_versions_matching_stability($force_update = false, $force_cache = false) @@ -350,7 +350,7 @@ class version_helper { foreach ($versions_data as $branch => &$version_data) { - if (!preg_match('/^[0-9]+\.[0-9]+$/', $branch)) + if (!preg_match('/^[0-9a-z\-\.]+$/i', $branch)) { unset($versions_data[$branch]); continue; -- cgit v1.2.1