fixes #506, additional checks before deleting files

During upgrade of theme/plugin/language, we add some more test to prevent
transversal path
This commit is contained in:
plegall 2017-03-31 14:45:30 +02:00
parent 9783a61490
commit 2ea5a359fe
3 changed files with 89 additions and 0 deletions

View file

@ -558,6 +558,8 @@ DELETE FROM '. PLUGINS_TABLE .'
*/
function extract_plugin_files($action, $revision, $dest, &$plugin_id=null)
{
global $logger;
if ($archive = tempnam( PHPWG_PLUGINS_PATH, 'zip'))
{
$url = PEM_URL . '/download.php';
@ -583,6 +585,9 @@ DELETE FROM '. PLUGINS_TABLE .'
$main_filepath = $file['filename'];
}
}
$logger->debug(__FUNCTION__.', $main_filepath = '.$main_filepath);
if (isset($main_filepath))
{
$root = dirname($main_filepath); // main.inc.php path in archive
@ -595,6 +600,7 @@ DELETE FROM '. PLUGINS_TABLE .'
$plugin_id = ($root == '.' ? 'extension_' . $dest : basename($root));
}
$extract_path = PHPWG_PLUGINS_PATH . $plugin_id;
$logger->debug(__FUNCTION__.', $extract_path = '.$extract_path);
if($result = $zip->extract(PCLZIP_OPT_PATH, $extract_path,
PCLZIP_OPT_REMOVE_PATH, $root,
@ -613,9 +619,31 @@ DELETE FROM '. PLUGINS_TABLE .'
and !empty($old_files))
{
$old_files[] = 'obsolete.list';
$logger->debug(__FUNCTION__.', $old_files = {'.join('},{', $old_files).'}');
$extract_path_realpath = realpath($extract_path);
foreach($old_files as $old_file)
{
$old_file = trim($old_file);
$old_file = trim($old_file, '/'); // prevent path starting with a "/"
if (empty($old_file)) // empty here means the extension itself
{
continue;
}
$path = $extract_path.'/'.$old_file;
// make sure the obsolete file is withing the extension directory, prevent traversal path
$realpath = realpath($path);
if ($realpath === false or strpos($realpath, $extract_path_realpath) !== 0)
{
continue;
}
$logger->debug(__FUNCTION__.', to delete = '.$path);
if (is_file($path))
{
@unlink($path);