mirror of
https://github.com/phpbb/phpbb.git
synced 2025-08-08 17:56:52 +02:00
[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
This commit is contained in:
@@ -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'));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user