Call fs_is_directorycomponent() and fs_is_hidden_file() instead of checking manually. Also: Path traversal in Media Manager fixed.

This commit is contained in:
azett 2022-06-24 21:42:48 +02:00
parent 28b7066d82
commit c662bc3590
5 changed files with 257 additions and 230 deletions

View File

@ -286,7 +286,7 @@ function fs_copy($source, $dest) {
* @return boolean <code>true</code> if the file is a directory component; otherwise <code>false</code> * @return boolean <code>true</code> if the file is a directory component; otherwise <code>false</code>
*/ */
function fs_is_directorycomponent($filename) { function fs_is_directorycomponent($filename) {
return strlen($filename) > 0 && ($filename === '.' || $filename === '..'); return $filename === '.' || $filename === '..';
} }
/** /**

View File

@ -120,7 +120,7 @@ function theme_list() {
$dh = opendir($dir); $dh = opendir($dir);
$i = 0; $i = 0;
while (false !== ($filename = readdir($dh))) { while (false !== ($filename = readdir($dh))) {
if (($filename != '.') && ($filename != '..')) { if (!fs_is_directorycomponent($filename)) {
$files [$i++] = $filename; $files [$i++] = $filename;
} }
} }

View File

@ -1,6 +1,8 @@
<?php <?php
/** /**
* Smarty plugin * Smarty plugin
*
* @package Smarty * @package Smarty
* @subpackage plugins * @subpackage plugins
*/ */
@ -16,9 +18,7 @@
*/ */
// $auto_base, $auto_source = null, $auto_id = null, $exp_time = null // $auto_base, $auto_source = null, $auto_id = null, $exp_time = null
function smarty_core_rm_auto($params, &$smarty) {
function smarty_core_rm_auto($params, &$smarty)
{
if (!@is_dir($params ['auto_base'])) if (!@is_dir($params ['auto_base']))
return false; return false;
@ -54,7 +54,7 @@ function smarty_core_rm_auto($params, &$smarty)
$_handle = opendir($params ['auto_base']); $_handle = opendir($params ['auto_base']);
$_res = true; $_res = true;
while (false !== ($_filename = readdir($_handle))) { while (false !== ($_filename = readdir($_handle))) {
if($_filename == '.' || $_filename == '..') { if (fs_is_directorycomponent($_filename)) {
continue; continue;
} elseif (substr($params ['auto_base'] . DIRECTORY_SEPARATOR . $_filename, 0, strlen($_tname)) == $_tname) { } 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']); $_res &= (bool) $smarty->_unlink($params ['auto_base'] . DIRECTORY_SEPARATOR . $_filename, $params ['exp_time']);

View File

@ -1,6 +1,8 @@
<?php <?php
/** /**
* Smarty plugin * Smarty plugin
*
* @package Smarty * @package Smarty
* @subpackage plugins * @subpackage plugins
*/ */
@ -16,16 +18,18 @@
*/ */
// $dirname, $level = 1, $exp_time = null // $dirname, $level = 1, $exp_time = null
function smarty_core_rmdir($params, &$smarty) {
function smarty_core_rmdir($params, &$smarty) if (!isset($params ['level'])) {
{ $params ['level'] = 1;
if(!isset($params['level'])) { $params['level'] = 1; } }
if(!isset($params['exp_time'])) { $params['exp_time'] = null; } if (!isset($params ['exp_time'])) {
$params ['exp_time'] = null;
}
if ($_handle = @opendir($params ['dirname'])) { if ($_handle = @opendir($params ['dirname'])) {
while (false !== ($_entry = readdir($_handle))) { while (false !== ($_entry = readdir($_handle))) {
if ($_entry != '.' && $_entry != '..') { if (!fs_is_directorycomponent($_entry)) {
if (@is_dir($params ['dirname'] . DIRECTORY_SEPARATOR . $_entry)) { if (@is_dir($params ['dirname'] . DIRECTORY_SEPARATOR . $_entry)) {
$_params = array( $_params = array(
'dirname' => $params ['dirname'] . DIRECTORY_SEPARATOR . $_entry, 'dirname' => $params ['dirname'] . DIRECTORY_SEPARATOR . $_entry,
@ -33,8 +37,7 @@ function smarty_core_rmdir($params, &$smarty)
'exp_time' => $params ['exp_time'] 'exp_time' => $params ['exp_time']
); );
smarty_core_rmdir($_params, $smarty); smarty_core_rmdir($_params, $smarty);
} } else {
else {
$smarty->_unlink($params ['dirname'] . DIRECTORY_SEPARATOR . $_entry, $params ['exp_time']); $smarty->_unlink($params ['dirname'] . DIRECTORY_SEPARATOR . $_entry, $params ['exp_time']);
} }
} }
@ -46,7 +49,6 @@ function smarty_core_rmdir($params, &$smarty)
return @rmdir($params ['dirname']); return @rmdir($params ['dirname']);
} }
return (bool) $_handle; return (bool) $_handle;
} }
/* vim: set expandtab: */ /* vim: set expandtab: */

View File

@ -1,10 +1,11 @@
<?php <?php
class admin_uploader_mediamanager extends AdminPanelAction { class admin_uploader_mediamanager extends AdminPanelAction {
var $finfo; var $finfo;
var $conf; var $conf;
var $langres = 'plugin:mediamanager'; var $langres = 'plugin:mediamanager';
function cmpfiles($a, $b) { function cmpfiles($a, $b) {
@ -15,9 +16,14 @@ class admin_uploader_mediamanager extends AdminPanelAction {
return $c; return $c;
} }
function formatBytes($bytes, $precision = 2) { function formatBytes($bytes, $precision = 2) {
$units = array('B', 'KB', 'MB', 'GB', 'TB'); $units = array(
'B',
'KB',
'MB',
'GB',
'TB'
);
$bytes = max($bytes, 0); $bytes = max($bytes, 0);
$pow = floor(($bytes ? log($bytes) : 0) / log(1024)); $pow = floor(($bytes ? log($bytes) : 0) / log(1024));
@ -28,8 +34,6 @@ class admin_uploader_mediamanager extends AdminPanelAction {
return round($bytes, $precision) . ' ' . $units [$pow]; return round($bytes, $precision) . ' ' . $units [$pow];
} }
function getFileInfo($filepath) { function getFileInfo($filepath) {
global $fp_config; global $fp_config;
@ -45,7 +49,6 @@ class admin_uploader_mediamanager extends AdminPanelAction {
$info ['usecount'] = null; $info ['usecount'] = null;
} }
return $info; return $info;
} }
@ -54,14 +57,16 @@ class admin_uploader_mediamanager extends AdminPanelAction {
} }
function deleteFolder($folder, $mmbaseurl) { function deleteFolder($folder, $mmbaseurl) {
if (!file_exists($folder)) return false; if (!file_exists($folder))
return false;
$dir = opendir($folder); $dir = opendir($folder);
while (false !== ($file = readdir($dir))) { while (false !== ($file = readdir($dir))) {
if (!in_array($file, array(".",".."))) { if (!fs_is_directorycomponent($file)) {
if (is_dir($folder . "/" . $file)) { if (is_dir($folder . "/" . $file)) {
$this->deleteFolder($folder . "/" . $file, $mmbaseurl); $this->deleteFolder($folder . "/" . $file, $mmbaseurl);
} else { } else {
if (!unlink($folder."/".$file)) return false; if (!unlink($folder . "/" . $file))
return false;
} }
} }
} }
@ -73,18 +78,32 @@ class admin_uploader_mediamanager extends AdminPanelAction {
if (isset($_GET ['deletefile'])) { if (isset($_GET ['deletefile'])) {
list ($type, $name) = explode("-", $_GET ['deletefile'], 2); list ($type, $name) = explode("-", $_GET ['deletefile'], 2);
switch ($type) { switch ($type) {
case 'attachs': $type=ABS_PATH.ATTACHS_DIR; break; case 'attachs':
case 'images': $type=ABS_PATH.IMAGES_DIR.$folder; break; $type = ABS_PATH . ATTACHS_DIR;
break;
case 'images':
$type = ABS_PATH . IMAGES_DIR . $folder;
break;
case 'gallery': case 'gallery':
if (!$this->deleteFolder(ABS_PATH . IMAGES_DIR . $name, $mmbaseurl)) if (!$this->deleteFolder(ABS_PATH . IMAGES_DIR . $name, $mmbaseurl))
@utils_redirect($mmbaseurl . '&status=-1'); @utils_redirect($mmbaseurl . '&status=-1');
@utils_redirect($mmbaseurl . '&status=1'); @utils_redirect($mmbaseurl . '&status=1');
return true; return true;
break; 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;
} }
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'); @utils_redirect($mmbaseurl . '&status=1');
return true; return true;
} }
@ -94,25 +113,20 @@ class admin_uploader_mediamanager extends AdminPanelAction {
return false; return false;
} }
function main() { function main() {
$mmbaseurl = "admin.php?p=uploader&action=mediamanager"; $mmbaseurl = "admin.php?p=uploader&action=mediamanager";
$folder = ""; $gallery=""; $folder = "";
if (isset($_GET['gallery'])){ $gallery = "";
if (isset($_GET ['gallery']) && !fs_is_directorycomponent($_GET ['gallery'])) {
$mmbaseurl .= "&gallery=" . $_GET ['gallery']; $mmbaseurl .= "&gallery=" . $_GET ['gallery'];
$gallery = str_replace("/", "", $_GET ['gallery']); $gallery = str_replace("/", "", $_GET ['gallery']);
$folder = $gallery . "/"; $folder = $gallery . "/";
} }
$weburl = plugin_geturl('mediamanager'); $weburl = plugin_geturl('mediamanager');
$this->conf = plugin_getoptions('mediamanager'); $this->conf = plugin_getoptions('mediamanager');
if ($this->doItemActions($folder, $mmbaseurl)) return; if ($this->doItemActions($folder, $mmbaseurl))
return;
$files = array(); $files = array();
$galleries = array(); $galleries = array();
@ -125,11 +139,13 @@ class admin_uploader_mediamanager extends AdminPanelAction {
$dir = opendir(ABS_PATH . IMAGES_DIR); $dir = opendir(ABS_PATH . IMAGES_DIR);
while (false !== ($file = readdir($dir))) { while (false !== ($file = readdir($dir))) {
$fullpath = ABS_PATH . IMAGES_DIR . $file; $fullpath = ABS_PATH . IMAGES_DIR . $file;
if (!in_array($file, array(".","..",".thumbs")) && is_dir($fullpath)) { if (!fs_is_directorycomponent($file) && !fs_is_hidden_file($file) && is_dir($fullpath)) {
$info = $this->getFileInfo($fullpath); $info = $this->getFileInfo($fullpath);
$info ['type'] = "gallery"; $info ['type'] = "gallery";
$galleries [$fullpath] = $info; $galleries [$fullpath] = $info;
if (is_null($info['usecount'])) { $galleries_needupdate[]=$fullpath;} if (is_null($info ['usecount'])) {
$galleries_needupdate [] = $fullpath;
}
} }
} }
} }
@ -138,13 +154,15 @@ class admin_uploader_mediamanager extends AdminPanelAction {
if ($folder == "" && file_exists(ABS_PATH . ATTACHS_DIR)) { if ($folder == "" && file_exists(ABS_PATH . ATTACHS_DIR)) {
$dir = opendir(ABS_PATH . ATTACHS_DIR); $dir = opendir(ABS_PATH . ATTACHS_DIR);
while (false !== ($file = readdir($dir))) { while (false !== ($file = readdir($dir))) {
if (!in_array($file, array(".",".."))) { if (!fs_is_directorycomponent($file) && !fs_is_hidden_file($file)) {
$fullpath = ABS_PATH . ATTACHS_DIR . $file; $fullpath = ABS_PATH . ATTACHS_DIR . $file;
$info = $this->getFileInfo($fullpath); $info = $this->getFileInfo($fullpath);
$info ['type'] = "attachs"; $info ['type'] = "attachs";
$info ['url'] = BLOG_ROOT . ATTACHS_DIR . $file; $info ['url'] = BLOG_ROOT . ATTACHS_DIR . $file;
$files [$fullpath] = $info; $files [$fullpath] = $info;
if (is_null($info['usecount'])) { $files_needupdate[]=$fullpath;} if (is_null($info ['usecount'])) {
$files_needupdate [] = $fullpath;
}
} }
} }
} }
@ -153,34 +171,44 @@ class admin_uploader_mediamanager extends AdminPanelAction {
$dir = opendir(ABS_PATH . IMAGES_DIR . $folder); $dir = opendir(ABS_PATH . IMAGES_DIR . $folder);
while (false !== ($file = readdir($dir))) { while (false !== ($file = readdir($dir))) {
$fullpath = ABS_PATH . IMAGES_DIR . $folder . $file; $fullpath = ABS_PATH . IMAGES_DIR . $folder . $file;
if (!in_array($file, array(".","..",".thumbs")) && !is_dir($fullpath)) { if (!fs_is_directorycomponent($file) && !fs_is_hidden_file($file) && !is_dir($fullpath)) {
$info = $this->getFileInfo($fullpath); $info = $this->getFileInfo($fullpath);
$info ['type'] = "images"; $info ['type'] = "images";
$info ['url'] = BLOG_ROOT . IMAGES_DIR . $folder . $file; $info ['url'] = BLOG_ROOT . IMAGES_DIR . $folder . $file;
$files [$fullpath] = $info; $files [$fullpath] = $info;
# NO count for images in galleries # 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($files, $files_needupdate);
mediamanager_updateUseCountArr($galleries, $galleries_needupdate); mediamanager_updateUseCountArr($galleries, $galleries_needupdate);
usort($files, Array("admin_uploader_mediamanager","cmpfiles")); usort($files, Array(
"admin_uploader_mediamanager",
"cmpfiles"
));
$totalfilescount = (string) count($files); $totalfilescount = (string) count($files);
# paginator # paginator
$pages = ceil((count($files) + count($galleries)) / ITEMSPERPAGE); $pages = ceil((count($files) + count($galleries)) / ITEMSPERPAGE);
if ($pages==0) $pages=1; if ($pages == 0)
$pages = 1;
if (isset($_GET ['page'])) { if (isset($_GET ['page'])) {
$page = (int) $_GET ['page']; $page = (int) $_GET ['page'];
} else { } else {
$page = 1; $page = 1;
} }
if ($page<1) $page=1; if ($page < 1)
if ($page>$pages) $page=$pages; $page = 1;
if ($page > $pages)
$page = $pages;
$pagelist = array(); $pagelist = array();
for($k=1; $k<=$pages; $k++ ) $pagelist[]=$k; for($k = 1; $k <= $pages; $k++)
$paginator = array( "total"=>$pages, $pagelist [] = $k;
$paginator = array(
"total" => $pages,
"current" => $page, "current" => $page,
"limit" => ITEMSPERPAGE, "limit" => ITEMSPERPAGE,
"pages" => $pagelist "pages" => $pagelist
@ -220,7 +248,6 @@ class admin_uploader_mediamanager extends AdminPanelAction {
return 2; return 2;
} }
$folder = ""; $folder = "";
if (isset($_GET ['gallery'])) { if (isset($_GET ['gallery'])) {
$mmbaseurl .= "&gallery=" . $_GET ['gallery']; $mmbaseurl .= "&gallery=" . $_GET ['gallery'];
@ -228,7 +255,8 @@ class admin_uploader_mediamanager extends AdminPanelAction {
} }
list ($action, $arg) = explode("-", $_POST ['action'], 2); list ($action, $arg) = explode("-", $_POST ['action'], 2);
if (!isset($_POST['file'])) return 2; if (!isset($_POST ['file']))
return 2;
foreach ($_POST ['file'] as $file => $v) { foreach ($_POST ['file'] as $file => $v) {
list ($type, $name) = explode("-", $file, 2); list ($type, $name) = explode("-", $file, 2);
if ($action == 'atg' && $type == 'images') { if ($action == 'atg' && $type == 'images') {
@ -242,6 +270,3 @@ class admin_uploader_mediamanager extends AdminPanelAction {
} }
admin_addpanelaction('uploader', 'mediamanager', true); admin_addpanelaction('uploader', 'mediamanager', true);
?>