mirror of
https://github.com/phpbb/phpbb.git
synced 2025-07-30 21:40:43 +02:00
Merge pull request #35 from phpbb/ticket/security-203-rhea
[ticket/security-203] Fully validate version check data in version helper -- Rhea
This commit is contained in:
@@ -2815,6 +2815,11 @@ function get_preg_expression($mode)
|
||||
case 'path_remove_dot_trailing_slash':
|
||||
return '#^(?:(\.)?)+(?:(.+)?)+(?:([\\/\\\])$)#';
|
||||
break;
|
||||
|
||||
case 'semantic_version':
|
||||
// Regular expression to match semantic versions by http://rgxdb.com/
|
||||
return '/(?<=^[Vv]|^)(?:(?<major>(?:0|[1-9](?:(?:0|[1-9])+)*))[.](?<minor>(?:0|[1-9](?:(?:0|[1-9])+)*))[.](?<patch>(?:0|[1-9](?:(?:0|[1-9])+)*))(?:-(?<prerelease>(?:(?:(?:[A-Za-z]|-)(?:(?:(?:0|[1-9])|(?:[A-Za-z]|-))+)?|(?:(?:(?:0|[1-9])|(?:[A-Za-z]|-))+)(?:[A-Za-z]|-)(?:(?:(?:0|[1-9])|(?:[A-Za-z]|-))+)?)|(?:0|[1-9](?:(?:0|[1-9])+)*))(?:[.](?:(?:(?:[A-Za-z]|-)(?:(?:(?:0|[1-9])|(?:[A-Za-z]|-))+)?|(?:(?:(?:0|[1-9])|(?:[A-Za-z]|-))+)(?:[A-Za-z]|-)(?:(?:(?:0|[1-9])|(?:[A-Za-z]|-))+)?)|(?:0|[1-9](?:(?:0|[1-9])+)*)))*))?(?:[+](?<build>(?:(?:(?:[A-Za-z]|-)(?:(?:(?:0|[1-9])|(?:[A-Za-z]|-))+)?|(?:(?:(?:0|[1-9])|(?:[A-Za-z]|-))+)(?:[A-Za-z]|-)(?:(?:(?:0|[1-9])|(?:[A-Za-z]|-))+)?)|(?:(?:0|[1-9])+))(?:[.](?:(?:(?:[A-Za-z]|-)(?:(?:(?:0|[1-9])|(?:[A-Za-z]|-))+)?|(?:(?:(?:0|[1-9])|(?:[A-Za-z]|-))+)(?:[A-Za-z]|-)(?:(?:(?:0|[1-9])|(?:[A-Za-z]|-))+)?)|(?:(?:0|[1-9])+)))*))?)$/';
|
||||
break;
|
||||
}
|
||||
|
||||
return '';
|
||||
|
@@ -440,16 +440,19 @@ $lang = array_merge($lang, array(
|
||||
'UPLOAD_DIR_SIZE' => 'Size of posted attachments',
|
||||
'USERS_PER_DAY' => 'Users per day',
|
||||
|
||||
'VALUE' => 'Value',
|
||||
'VERSIONCHECK_FAIL' => 'Failed to obtain latest version information.',
|
||||
'VERSIONCHECK_FORCE_UPDATE' => 'Re-Check version',
|
||||
'VERSION_CHECK' => 'Version check',
|
||||
'VERSION_CHECK_EXPLAIN' => 'Checks to see if your phpBB installation is up to date.',
|
||||
'VALUE' => 'Value',
|
||||
'VERSIONCHECK_FAIL' => 'Failed to obtain latest version information.',
|
||||
'VERSIONCHECK_FORCE_UPDATE' => 'Re-Check version',
|
||||
'VERSION_CHECK' => 'Version check',
|
||||
'VERSION_CHECK_EXPLAIN' => 'Checks to see if your phpBB installation is up to date.',
|
||||
'VERSIONCHECK_INVALID_ENTRY' => 'Latest version information contains an unsupported entry.',
|
||||
'VERSIONCHECK_INVALID_URL' => 'Latest version information contains invalid URL.',
|
||||
'VERSIONCHECK_INVALID_VERSION' => 'Latest version information contains an invalid version.',
|
||||
'VERSION_NOT_UP_TO_DATE_ACP' => 'Your phpBB installation is not up to date.<br />Below is a link to the release announcement, which contains more information as well as instructions on updating.',
|
||||
'VERSION_NOT_UP_TO_DATE_TITLE' => 'Your phpBB installation is not up to date.',
|
||||
'VERSION_UP_TO_DATE_ACP' => 'Your phpBB installation is up to date. There are no updates available at this time.',
|
||||
'VIEW_ADMIN_LOG' => 'View administrator log',
|
||||
'VIEW_INACTIVE_USERS' => 'View inactive users',
|
||||
'VERSION_UP_TO_DATE_ACP' => 'Your phpBB installation is up to date. There are no updates available at this time.',
|
||||
'VIEW_ADMIN_LOG' => 'View administrator log',
|
||||
'VIEW_INACTIVE_USERS' => 'View inactive users',
|
||||
|
||||
'WELCOME_PHPBB' => 'Welcome to phpBB',
|
||||
'WRITABLE_CONFIG' => 'Your config file (config.php) is currently world-writable. We strongly encourage you to change the permissions to 640 or at least to 644 (for example: <a href="http://en.wikipedia.org/wiki/Chmod" rel="external">chmod</a> 640 config.php).',
|
||||
|
@@ -60,6 +60,23 @@ class version_helper
|
||||
/** @var \phpbb\file_downloader */
|
||||
protected $file_downloader;
|
||||
|
||||
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
|
||||
*
|
||||
@@ -392,9 +409,101 @@ class version_helper
|
||||
$info['stable'] = (empty($info['stable'])) ? array() : $info['stable'];
|
||||
$info['unstable'] = (empty($info['unstable'])) ? $info['stable'] : $info['unstable'];
|
||||
|
||||
$info = $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
|
||||
*
|
||||
* @return array Versions info array
|
||||
* @throws version_check_exception
|
||||
*/
|
||||
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-9a-z\-\.]+$/i', $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]))
|
||||
{
|
||||
$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 version_check_exception('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))
|
||||
{
|
||||
throw new version_check_exception('VERSIONCHECK_INVALID_URL');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'version':
|
||||
if (!empty($value) && !preg_match(get_preg_expression('semantic_version'), $value))
|
||||
{
|
||||
throw new version_check_exception('VERSIONCHECK_INVALID_VERSION');
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// Shouldn't be possible to trigger this
|
||||
throw new version_check_exception('VERSIONCHECK_INVALID_ENTRY');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $versions_info;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user