From f5aae3361f769e7728f55f67fb12833e084eb0b6 Mon Sep 17 00:00:00 2001 From: slawkens Date: Mon, 8 Jan 2018 17:19:56 +0100 Subject: [PATCH] * uninstall: do not allow directories outside BASE * uninstall: do not allow absolute paths --- system/libs/plugins.php | 55 +++++++++++++++++++++++++++++----- system/pages/admin/plugins.php | 2 +- 2 files changed, 49 insertions(+), 8 deletions(-) diff --git a/system/libs/plugins.php b/system/libs/plugins.php index 13b84ab0..0906d277 100644 --- a/system/libs/plugins.php +++ b/system/libs/plugins.php @@ -10,6 +10,34 @@ */ defined('MYAAC') or die('Direct access not allowed!'); +function is_sub_dir($path = NULL, $parent_folder = SITE_PATH) { + + //Get directory path minus last folder + $dir = dirname($path); + $folder = substr($path, strlen($dir)); + + //Check the the base dir is valid + $dir = realpath($dir); + + //Only allow valid filename characters + $folder = preg_replace('/[^a-z0-9\.\-_]/i', '', $folder); + + //If this is a bad path or a bad end folder name + if( !$dir OR !$folder OR $folder === '.') { + return FALSE; + } + + //Rebuild path + $path = $dir. '/' . $folder; + + //If this path is higher than the parent folder + if( strcasecmp($path, $parent_folder) > 0 ) { + return $path; + } + + return FALSE; +} + class Plugins { private static $warnings = array(); private static $error = null; @@ -160,16 +188,32 @@ class Plugins { else { $success = true; foreach($plugin_info['uninstall'] as $file) { - $file = BASE . $file; - if(!deleteDirectory($file)) { + if(strpos($file, '/') === 0) { $success = false; + self::$error = "You cannot use absolute paths (starting with slash - '/'): " . $file; + break; + } + + $file = BASE . $file; + if(!is_sub_dir($file, BASE) || realpath(dirname($file)) != dirname($file)) { + $success = false; + self::$error = "You don't have rights to delete: " . $file; + break; } } - + + if($success) { + foreach($plugin_info['uninstall'] as $file) { + if(!deleteDirectory(BASE . $file)) { + self::$warnings[] = 'Cannot delete: ' . $$file; + } + } + } + if (isset($plugin_info['hooks'])) { foreach ($plugin_info['hooks'] as $_name => $info) { if (defined('HOOK_'. $info['type'])) { - $hook = constant('HOOK_'. $info['type']); + //$hook = constant('HOOK_'. $info['type']); $query = $db->query('SELECT `id` FROM `' . TABLE_PREFIX . 'hooks` WHERE `name` = ' . $db->quote($_name) . ';'); if ($query->rowCount() == 1) { // found something $query = $query->fetch(); @@ -187,9 +231,6 @@ class Plugins { return true; } - else { - self::$error = error_get_last(); - } } } } diff --git a/system/pages/admin/plugins.php b/system/pages/admin/plugins.php index b32061c2..424bf06f 100644 --- a/system/pages/admin/plugins.php +++ b/system/pages/admin/plugins.php @@ -22,7 +22,7 @@ if(isset($_REQUEST['uninstall'])){ success('Successfully uninstalled plugin ' . $uninstall); } else { - error('Error while uninstalling plugin ' . $plugin_name . ': ' . Plugins::getError()); + error('Error while uninstalling plugin ' . $uninstall . ': ' . Plugins::getError()); } } else if(isset($_FILES["plugin"]["name"]))