From c662bc3590a8b2410799d6a0c9b437615c1b7138 Mon Sep 17 00:00:00 2001 From: azett Date: Fri, 24 Jun 2022 21:42:48 +0200 Subject: [PATCH] Call fs_is_directorycomponent() and fs_is_hidden_file() instead of checking manually. Also: Path traversal in Media Manager fixed. --- fp-includes/core/core.filesystem.php | 2 +- fp-includes/core/core.theme.php | 2 +- fp-includes/smarty/internals/core.rm_auto.php | 90 ++--- fp-includes/smarty/internals/core.rmdir.php | 60 ++-- .../panels/panel.mediamanager.file.php | 333 ++++++++++-------- 5 files changed, 257 insertions(+), 230 deletions(-) diff --git a/fp-includes/core/core.filesystem.php b/fp-includes/core/core.filesystem.php index 31f99cf..3df52b4 100755 --- a/fp-includes/core/core.filesystem.php +++ b/fp-includes/core/core.filesystem.php @@ -286,7 +286,7 @@ function fs_copy($source, $dest) { * @return boolean true if the file is a directory component; otherwise false */ function fs_is_directorycomponent($filename) { - return strlen($filename) > 0 && ($filename === '.' || $filename === '..'); + return $filename === '.' || $filename === '..'; } /** diff --git a/fp-includes/core/core.theme.php b/fp-includes/core/core.theme.php index a835e27..2c64c17 100644 --- a/fp-includes/core/core.theme.php +++ b/fp-includes/core/core.theme.php @@ -120,7 +120,7 @@ function theme_list() { $dh = opendir($dir); $i = 0; while (false !== ($filename = readdir($dh))) { - if (($filename != '.') && ($filename != '..')) { + if (!fs_is_directorycomponent($filename)) { $files [$i++] = $filename; } } diff --git a/fp-includes/smarty/internals/core.rm_auto.php b/fp-includes/smarty/internals/core.rm_auto.php index b251f64..aca23a1 100644 --- a/fp-includes/smarty/internals/core.rm_auto.php +++ b/fp-includes/smarty/internals/core.rm_auto.php @@ -1,6 +1,8 @@ $params ['auto_base'], + 'level' => 0, + 'exp_time' => $params ['exp_time'] + ); + require_once (SMARTY_CORE_DIR . 'core.rmdir.php'); + $_res = smarty_core_rmdir($_params, $smarty); + } else { + $_tname = $smarty->_get_auto_filename($params ['auto_base'], $params ['auto_source'], $params ['auto_id']); - if(!isset($params['auto_id']) && !isset($params['auto_source'])) { - $_params = array( - 'dirname' => $params['auto_base'], - 'level' => 0, - 'exp_time' => $params['exp_time'] - ); - require_once(SMARTY_CORE_DIR . 'core.rmdir.php'); - $_res = smarty_core_rmdir($_params, $smarty); - } else { - $_tname = $smarty->_get_auto_filename($params['auto_base'], $params['auto_source'], $params['auto_id']); + if (isset($params ['auto_source'])) { + if (isset($params ['extensions'])) { + $_res = false; + foreach ((array) $params ['extensions'] as $_extension) + $_res |= $smarty->_unlink($_tname . $_extension, $params ['exp_time']); + } else { + $_res = $smarty->_unlink($_tname, $params ['exp_time']); + } + } elseif ($smarty->use_sub_dirs) { + $_params = array( + 'dirname' => $_tname, + 'level' => 1, + 'exp_time' => $params ['exp_time'] + ); + require_once (SMARTY_CORE_DIR . 'core.rmdir.php'); + $_res = smarty_core_rmdir($_params, $smarty); + } else { + // remove matching file names + $_handle = opendir($params ['auto_base']); + $_res = true; + while (false !== ($_filename = readdir($_handle))) { + if (fs_is_directorycomponent($_filename)) { + continue; + } elseif (substr($params ['auto_base'] . DIRECTORY_SEPARATOR . $_filename, 0, strlen($_tname)) == $_tname) { + $_res &= (bool) $smarty->_unlink($params ['auto_base'] . DIRECTORY_SEPARATOR . $_filename, $params ['exp_time']); + } + } + } + } - if(isset($params['auto_source'])) { - if (isset($params['extensions'])) { - $_res = false; - foreach ((array)$params['extensions'] as $_extension) - $_res |= $smarty->_unlink($_tname.$_extension, $params['exp_time']); - } else { - $_res = $smarty->_unlink($_tname, $params['exp_time']); - } - } elseif ($smarty->use_sub_dirs) { - $_params = array( - 'dirname' => $_tname, - 'level' => 1, - 'exp_time' => $params['exp_time'] - ); - require_once(SMARTY_CORE_DIR . 'core.rmdir.php'); - $_res = smarty_core_rmdir($_params, $smarty); - } else { - // remove matching file names - $_handle = opendir($params['auto_base']); - $_res = true; - while (false !== ($_filename = readdir($_handle))) { - if($_filename == '.' || $_filename == '..') { - continue; - } elseif (substr($params['auto_base'] . DIRECTORY_SEPARATOR . $_filename, 0, strlen($_tname)) == $_tname) { - $_res &= (bool)$smarty->_unlink($params['auto_base'] . DIRECTORY_SEPARATOR . $_filename, $params['exp_time']); - } - } - } - } - - return $_res; + return $_res; } /* vim: set expandtab: */ diff --git a/fp-includes/smarty/internals/core.rmdir.php b/fp-includes/smarty/internals/core.rmdir.php index 2166c44..7408317 100644 --- a/fp-includes/smarty/internals/core.rmdir.php +++ b/fp-includes/smarty/internals/core.rmdir.php @@ -1,6 +1,8 @@ $params['dirname'] . DIRECTORY_SEPARATOR . $_entry, - 'level' => $params['level'] + 1, - 'exp_time' => $params['exp_time'] - ); - smarty_core_rmdir($_params, $smarty); - } - else { - $smarty->_unlink($params['dirname'] . DIRECTORY_SEPARATOR . $_entry, $params['exp_time']); - } - } - } - closedir($_handle); - } - - if ($params['level']) { - return @rmdir($params['dirname']); - } - return (bool)$_handle; + while (false !== ($_entry = readdir($_handle))) { + if (!fs_is_directorycomponent($_entry)) { + if (@is_dir($params ['dirname'] . DIRECTORY_SEPARATOR . $_entry)) { + $_params = array( + 'dirname' => $params ['dirname'] . DIRECTORY_SEPARATOR . $_entry, + 'level' => $params ['level'] + 1, + 'exp_time' => $params ['exp_time'] + ); + smarty_core_rmdir($_params, $smarty); + } else { + $smarty->_unlink($params ['dirname'] . DIRECTORY_SEPARATOR . $_entry, $params ['exp_time']); + } + } + } + closedir($_handle); + } + if ($params ['level']) { + return @rmdir($params ['dirname']); + } + return (bool) $_handle; } /* vim: set expandtab: */ diff --git a/fp-plugins/mediamanager/panels/panel.mediamanager.file.php b/fp-plugins/mediamanager/panels/panel.mediamanager.file.php index 397cd7e..ac0e429 100644 --- a/fp-plugins/mediamanager/panels/panel.mediamanager.file.php +++ b/fp-plugins/mediamanager/panels/panel.mediamanager.file.php @@ -1,197 +1,225 @@ basename($filepath), - "size"=>$this->formatBytes(filesize($filepath)), - "mtime"=>date_strformat($fp_config['locale']['dateformatshort'], filemtime($filepath)) + "name" => basename($filepath), + "size" => $this->formatBytes(filesize($filepath)), + "mtime" => date_strformat($fp_config ['locale'] ['dateformatshort'], filemtime($filepath)) ); - - if (isset($this->conf['usecount'][basename($filepath)])){ - $info['usecount']=$this->conf['usecount'][basename($filepath)]; + + if (isset($this->conf ['usecount'] [basename($filepath)])) { + $info ['usecount'] = $this->conf ['usecount'] [basename($filepath)]; } else { - $info['usecount'] = null; + $info ['usecount'] = null; } - return $info; - } - - function setup() { - $this->smarty->assign('admin_resource', "plugin:mediamanager/admin.plugin.mediamanager.files"); - } - - function deleteFolder($folder, $mmbaseurl){ - if (!file_exists($folder)) return false; + } + + function setup() { + $this->smarty->assign('admin_resource', "plugin:mediamanager/admin.plugin.mediamanager.files"); + } + + function deleteFolder($folder, $mmbaseurl) { + if (!file_exists($folder)) + return false; $dir = opendir($folder); while (false !== ($file = readdir($dir))) { - if (!in_array($file, array(".",".."))) { - if (is_dir($folder."/".$file)){ - $this->deleteFolder($folder."/".$file, $mmbaseurl); + if (!fs_is_directorycomponent($file)) { + if (is_dir($folder . "/" . $file)) { + $this->deleteFolder($folder . "/" . $file, $mmbaseurl); } else { - if (!unlink($folder."/".$file)) return false; + if (!unlink($folder . "/" . $file)) + return false; } } } return rmdir($folder); } - function doItemActions($folder, $mmbaseurl){ - /* delete file*/ - if (isset($_GET['deletefile'])){ - list($type, $name) = explode("-", $_GET['deletefile'],2); - switch($type){ - case 'attachs': $type=ABS_PATH.ATTACHS_DIR; break; - case 'images': $type=ABS_PATH.IMAGES_DIR.$folder; break; + function doItemActions($folder, $mmbaseurl) { + /* delete file */ + if (isset($_GET ['deletefile'])) { + list ($type, $name) = explode("-", $_GET ['deletefile'], 2); + switch ($type) { + case 'attachs': + $type = ABS_PATH . ATTACHS_DIR; + break; + case 'images': + $type = ABS_PATH . IMAGES_DIR . $folder; + break; case 'gallery': - if ( !$this->deleteFolder(ABS_PATH.IMAGES_DIR.$name, $mmbaseurl)) - @utils_redirect($mmbaseurl.'&status=-1'); - @utils_redirect($mmbaseurl.'&status=1'); + if (!$this->deleteFolder(ABS_PATH . IMAGES_DIR . $name, $mmbaseurl)) + @utils_redirect($mmbaseurl . '&status=-1'); + @utils_redirect($mmbaseurl . '&status=1'); return true; break; - default: { @utils_redirect($mmbaseurl.'&status=-1'); return true; } + default: + { + @utils_redirect($mmbaseurl . '&status=-1'); + return true; + } } - if (!file_exists($type.$name)) { @utils_redirect($mmbaseurl.'&status=-1'); return true; } - if (!unlink($type.$name)) { @utils_redirect($mmbaseurl.'&status=-1'); return true; } - @utils_redirect($mmbaseurl.'&status=1'); + if (!file_exists($type . $name)) { + @utils_redirect($mmbaseurl . '&status=-1'); + return true; + } + if (!unlink($type . $name)) { + @utils_redirect($mmbaseurl . '&status=-1'); + return true; + } + @utils_redirect($mmbaseurl . '&status=1'); return true; } - if (isset($_GET['status'])){ - $this->smarty->assign('success', $_GET['status']); + if (isset($_GET ['status'])) { + $this->smarty->assign('success', $_GET ['status']); } return false; } - - function main() { - $mmbaseurl="admin.php?p=uploader&action=mediamanager"; - $folder = ""; $gallery=""; - if (isset($_GET['gallery'])){ - $mmbaseurl .= "&gallery=".$_GET['gallery']; - $gallery = str_replace("/","",$_GET['gallery']); - $folder = $gallery."/"; + $mmbaseurl = "admin.php?p=uploader&action=mediamanager"; + $folder = ""; + $gallery = ""; + if (isset($_GET ['gallery']) && !fs_is_directorycomponent($_GET ['gallery'])) { + $mmbaseurl .= "&gallery=" . $_GET ['gallery']; + $gallery = str_replace("/", "", $_GET ['gallery']); + $folder = $gallery . "/"; } - - + $weburl = plugin_geturl('mediamanager'); $this->conf = plugin_getoptions('mediamanager'); - if ($this->doItemActions($folder, $mmbaseurl)) return; - - - - - + if ($this->doItemActions($folder, $mmbaseurl)) + return; + $files = array(); $galleries = array(); - - $files_needupdate=array(); - $galleries_needupdate=array(); - + + $files_needupdate = array(); + $galleries_needupdate = array(); + # galleries (alwais from IMAGES_DIR) - if (file_exists(ABS_PATH.IMAGES_DIR)){ - $dir = opendir(ABS_PATH.IMAGES_DIR); - while (false !== ($file = readdir($dir))){ - $fullpath=ABS_PATH.IMAGES_DIR.$file; - if (!in_array($file, array(".","..",".thumbs")) && is_dir($fullpath)) { + if (file_exists(ABS_PATH . IMAGES_DIR)) { + $dir = opendir(ABS_PATH . IMAGES_DIR); + while (false !== ($file = readdir($dir))) { + $fullpath = ABS_PATH . IMAGES_DIR . $file; + if (!fs_is_directorycomponent($file) && !fs_is_hidden_file($file) && is_dir($fullpath)) { $info = $this->getFileInfo($fullpath); - $info['type'] = "gallery"; - $galleries[$fullpath] = $info; - if (is_null($info['usecount'])) { $galleries_needupdate[]=$fullpath;} + $info ['type'] = "gallery"; + $galleries [$fullpath] = $info; + if (is_null($info ['usecount'])) { + $galleries_needupdate [] = $fullpath; + } } } } - + # attachs (NO attachs in galleries) - if ($folder=="" && file_exists(ABS_PATH.ATTACHS_DIR)){ - $dir = opendir(ABS_PATH.ATTACHS_DIR); + if ($folder == "" && file_exists(ABS_PATH . ATTACHS_DIR)) { + $dir = opendir(ABS_PATH . ATTACHS_DIR); while (false !== ($file = readdir($dir))) { - if (!in_array($file, array(".",".."))) { - $fullpath = ABS_PATH.ATTACHS_DIR.$file; - $info=$this->getFileInfo($fullpath); - $info['type']="attachs"; - $info['url']=BLOG_ROOT.ATTACHS_DIR.$file; - $files[$fullpath]=$info; - if (is_null($info['usecount'])) { $files_needupdate[]=$fullpath;} + if (!fs_is_directorycomponent($file) && !fs_is_hidden_file($file)) { + $fullpath = ABS_PATH . ATTACHS_DIR . $file; + $info = $this->getFileInfo($fullpath); + $info ['type'] = "attachs"; + $info ['url'] = BLOG_ROOT . ATTACHS_DIR . $file; + $files [$fullpath] = $info; + if (is_null($info ['usecount'])) { + $files_needupdate [] = $fullpath; + } } } } # images - if (file_exists(ABS_PATH.IMAGES_DIR.$folder)){ - $dir = opendir(ABS_PATH.IMAGES_DIR.$folder); - while (false !== ($file = readdir($dir))){ - $fullpath=ABS_PATH.IMAGES_DIR.$folder.$file; - if (!in_array($file, array(".","..",".thumbs")) && !is_dir($fullpath)) { - $info=$this->getFileInfo($fullpath); - $info['type']="images"; - $info['url']=BLOG_ROOT.IMAGES_DIR.$folder.$file; - $files[$fullpath]=$info; + if (file_exists(ABS_PATH . IMAGES_DIR . $folder)) { + $dir = opendir(ABS_PATH . IMAGES_DIR . $folder); + while (false !== ($file = readdir($dir))) { + $fullpath = ABS_PATH . IMAGES_DIR . $folder . $file; + if (!fs_is_directorycomponent($file) && !fs_is_hidden_file($file) && !is_dir($fullpath)) { + $info = $this->getFileInfo($fullpath); + $info ['type'] = "images"; + $info ['url'] = BLOG_ROOT . IMAGES_DIR . $folder . $file; + $files [$fullpath] = $info; # NO count for images in galleries - if ($folder=="" && is_null($info['usecount'])) { $files_needupdate[]=$fullpath; } + if ($folder == "" && is_null($info ['usecount'])) { + $files_needupdate [] = $fullpath; + } } } } - mediamanager_updateUseCountArr($files,$files_needupdate); - mediamanager_updateUseCountArr($galleries,$galleries_needupdate); - - usort($files, Array("admin_uploader_mediamanager","cmpfiles")); - $totalfilescount = (string) count($files); - #paginator - $pages = ceil((count($files)+count($galleries))/ ITEMSPERPAGE); - if ($pages==0) $pages=1; - if (isset($_GET['page'])){ - $page = (int) $_GET['page']; - } else { - $page=1; - } - if ($page<1) $page=1; - if ($page>$pages) $page=$pages; - $pagelist = array(); - for($k=1; $k<=$pages; $k++ ) $pagelist[]=$k; - $paginator = array( "total"=>$pages, - "current"=>$page, - "limit" => ITEMSPERPAGE, - "pages" => $pagelist - ); + mediamanager_updateUseCountArr($files, $files_needupdate); + mediamanager_updateUseCountArr($galleries, $galleries_needupdate); - $startfrom = ($page-1)*ITEMSPERPAGE; - $galleriesout = count(array_slice($galleries,0, $startfrom)); - $dropdowngalleries=$galleries; + usort($files, Array( + "admin_uploader_mediamanager", + "cmpfiles" + )); + $totalfilescount = (string) count($files); + # paginator + $pages = ceil((count($files) + count($galleries)) / ITEMSPERPAGE); + if ($pages == 0) + $pages = 1; + if (isset($_GET ['page'])) { + $page = (int) $_GET ['page']; + } else { + $page = 1; + } + if ($page < 1) + $page = 1; + if ($page > $pages) + $page = $pages; + $pagelist = array(); + for($k = 1; $k <= $pages; $k++) + $pagelist [] = $k; + $paginator = array( + "total" => $pages, + "current" => $page, + "limit" => ITEMSPERPAGE, + "pages" => $pagelist + ); + + $startfrom = ($page - 1) * ITEMSPERPAGE; + $galleriesout = count(array_slice($galleries, 0, $startfrom)); + $dropdowngalleries = $galleries; $galleries = array_slice($galleries, $startfrom, ITEMSPERPAGE); - - $files = array_slice($files, $startfrom-$galleriesout, ITEMSPERPAGE- count($galleries)); + + $files = array_slice($files, $startfrom - $galleriesout, ITEMSPERPAGE - count($galleries)); $this->smarty->assign('paginator', $paginator); $this->smarty->assign('files', $files); @@ -202,17 +230,17 @@ class admin_uploader_mediamanager extends AdminPanelAction { $this->smarty->assign('currentgallery', $gallery); $this->smarty->assign('totalfilescount', $totalfilescount); } - + function onsubmit($data = NULL) { - if (isset($_POST['mm-newgallery'])){ - $newgallery=$_POST['mm-newgallery-name']; - if ($newgallery==""){ + if (isset($_POST ['mm-newgallery'])) { + $newgallery = $_POST ['mm-newgallery-name']; + if ($newgallery == "") { $this->smarty->assign('success', -3); return 2; } - $newgallery = str_replace("/","", $newgallery); - $newgallery = str_replace(".","", $newgallery); - if (mkdir(ABS_PATH.IMAGES_DIR.$newgallery) ) { + $newgallery = str_replace("/", "", $newgallery); + $newgallery = str_replace(".", "", $newgallery); + if (mkdir(ABS_PATH . IMAGES_DIR . $newgallery)) { $this->smarty->assign('success', 3); } else { $this->smarty->assign('success', -2); @@ -220,28 +248,25 @@ class admin_uploader_mediamanager extends AdminPanelAction { return 2; } - $folder = ""; - if (isset($_GET['gallery'])){ - $mmbaseurl .= "&gallery=".$_GET['gallery']; - $folder = str_replace("/","",$_GET['gallery'])."/"; + if (isset($_GET ['gallery'])) { + $mmbaseurl .= "&gallery=" . $_GET ['gallery']; + $folder = str_replace("/", "", $_GET ['gallery']) . "/"; + } + + list ($action, $arg) = explode("-", $_POST ['action'], 2); + if (!isset($_POST ['file'])) + return 2; + foreach ($_POST ['file'] as $file => $v) { + list ($type, $name) = explode("-", $file, 2); + if ($action == 'atg' && $type == 'images') { + copy(ABS_PATH . IMAGES_DIR . $folder . $name, ABS_PATH . IMAGES_DIR . $arg . '/' . $name); + $this->smarty->assign('success', 2); + } } - - list($action,$arg) = explode("-",$_POST['action'],2); - if (!isset($_POST['file'])) return 2; - foreach($_POST['file'] as $file=>$v){ - list($type,$name) = explode("-",$file,2); - if ($action=='atg' && $type=='images'){ - copy( ABS_PATH.IMAGES_DIR.$folder.$name, ABS_PATH.IMAGES_DIR.$arg.'/'.$name); - $this->smarty->assign('success', 2); - } - } return 2; - } - + } + } -admin_addpanelaction('uploader', 'mediamanager', true); - - -?> +admin_addpanelaction('uploader', 'mediamanager', true); \ No newline at end of file