Fix vulnerability

This commit is contained in:
Jose Gonzalez 2021-09-03 13:30:15 +02:00
parent a2ef804cec
commit fa101db3b6
4 changed files with 58 additions and 73 deletions

View File

@ -219,34 +219,15 @@ if ($filemanager) {
$id_plugin = (int) get_parameter('id_plugin', 0);
// Add custom directories here
// Add custom directories here.
$fallback_directory = 'attachment/plugin';
$directory = (string) get_parameter('directory', $fallback_directory);
// Get directory.
$directory = (string) get_parameter('directory');
if (empty($directory) === true) {
$directory = $fallback_directory;
} else {
$directory = str_replace('\\', '/', $directory);
// A miminal security check to avoid directory traversal
if (preg_match('/\.\./', $directory)) {
$directory = $fallback_directory;
}
if (preg_match('/^\//', $directory)) {
$directory = $fallback_directory;
}
if (preg_match('/^manager/', $directory)) {
$directory = $fallback_directory;
}
$banned_directories['include'] = true;
$banned_directories['godmode'] = true;
$banned_directories['operation'] = true;
$banned_directories['reporting'] = true;
$banned_directories['general'] = true;
$banned_directories[ENTERPRISE_DIR] = true;
if (isset($banned_directories[$directory])) {
$directory = $fallback_directory;
$directory = filemanager_safe_directory($directory, $fallback_directory);
}
$real_directory = realpath($config['homedir'].'/'.$directory);
@ -263,12 +244,12 @@ if ($filemanager) {
$default_real_directory = realpath($config['homedir'].'/'.$fallback_directory);
if ($upload_file_or_zip) {
upload_file($upload_file_or_zip, $default_real_directory);
if ($upload_file_or_zip === true) {
upload_file($upload_file_or_zip, $default_real_directory, $real_directory);
}
if ($create_text_file) {
create_text_file($default_real_directory);
if ($create_text_file === true) {
create_text_file($default_real_directory, $real_directory);
}
filemanager_file_explorer(

View File

@ -58,18 +58,6 @@ if (empty($directory) === true) {
$directory = filemanager_safe_directory($directory, $fallback_directory);
}
// Banned directories.
$banned_directories['include'] = true;
$banned_directories['godmode'] = true;
$banned_directories['operation'] = true;
$banned_directories['reporting'] = true;
$banned_directories['general'] = true;
$banned_directories[ENTERPRISE_DIR] = true;
if (isset($banned_directories[$directory]) === true) {
$directory = $fallback_directory;
}
$real_directory = realpath($config['homedir'].'/'.$directory);
echo '<h4>'.__('Index of %s', $directory).'</h4>';
@ -80,11 +68,11 @@ $create_text_file = (bool) get_parameter('create_text_file');
$default_real_directory = realpath($config['homedir'].'/');
if ($upload_file_or_zip === true) {
upload_file($upload_file_or_zip, $default_real_directory);
upload_file($upload_file_or_zip, $default_real_directory, $real_directory);
}
if ($create_text_file === true) {
create_text_file($default_real_directory);
create_text_file($default_real_directory, $real_directory);
}
filemanager_file_explorer(

View File

@ -128,15 +128,16 @@ require_once $config['homedir'].'/vendor/autoload.php';
*
* @param boolean $upload_file_or_zip Upload file or zip.
* @param string $default_real_directory String with default directory.
* @param string $destination_directory String with destination directory.
*
* @return void
*/
function upload_file($upload_file_or_zip, $default_real_directory)
function upload_file($upload_file_or_zip, $default_real_directory, $destination_directory)
{
global $config;
$config['filemanager'] = [];
$config['filemanager']['correct_upload_file'] = 0;
$config['filemanager']['message'] = null;
$config['filemanager']['message'] = '';
check_login();
@ -164,7 +165,7 @@ function upload_file($upload_file_or_zip, $default_real_directory)
if ($upload_file === true) {
if (isset($_FILES['file']) === true && empty($_FILES['file']['name']) === false) {
$filename = $_FILES['file']['name'];
$real_directory = filemanager_safe_directory((string) get_parameter('real_directory'));
$real_directory = filemanager_safe_directory($destination_directory);
$umask = io_safe_output((string) get_parameter('umask'));
if (strpos($real_directory, $default_real_directory) !== 0) {
@ -173,23 +174,34 @@ function upload_file($upload_file_or_zip, $default_real_directory)
// user is not trying to access an external path (avoid
// execution of PHP files in directories that are not explicitly
// controlled by corresponding .htaccess).
ui_print_error_message(__('Security error'));
$config['filemanager']['message'] = ui_print_error_message(__('Security error'));
} else {
// Copy file to directory and change name.
$nombre_archivo = $real_directory.'/'.$filename;
$nombre_archivo = sprintf('%s/%s', $real_directory, $filename);
if (! @copy($_FILES['file']['tmp_name'], $nombre_archivo)) {
$config['filemanager']['message'] = ui_print_error_message(__('Upload error'));
} else {
if (empty($umask) === false) {
chmod($nombre_archivo, $umask);
try {
$result = copy($_FILES['file']['tmp_name'], $nombre_archivo);
} catch (Exception $ex) {
$result = false;
}
$config['filemanager']['correct_upload_file'] = 1;
ui_print_success_message(__('Upload correct'));
if ($result === true) {
// If umask is provided, set.
if (empty($umask) === false) {
try {
chmod($nombre_archivo, $umask);
} catch (Exception $ex) {
$config['filemanager']['message'] = ui_print_error_message(__('Issue setting umask: %s', $ex->getMessage()));
}
}
// Upload performed properly.
$config['filemanager']['message'] .= ui_print_success_message(__('Upload correct'));
$config['filemanager']['correct_upload_file'] = 1;
// Delete temporal file.
unlink($_FILES['file']['tmp_name']);
} else {
$config['filemanager']['message'] = ui_print_error_message(__('Upload error'));
}
}
}
@ -202,7 +214,7 @@ function upload_file($upload_file_or_zip, $default_real_directory)
) {
$filename = $_FILES['file']['name'];
$filepath = $_FILES['file']['tmp_name'];
$real_directory = filemanager_safe_directory((string) get_parameter('real_directory'));
$real_directory = filemanager_safe_directory($destination_directory);
if (strpos($real_directory, $default_real_directory) !== 0) {
// Perform security check to determine whether received upload
@ -213,10 +225,10 @@ function upload_file($upload_file_or_zip, $default_real_directory)
ui_print_error_message(__('Security error'));
} else {
if (PandoraFMS\Tools\Files::unzip($filepath, $real_directory) === false) {
ui_print_error_message(__('It was impossible to uncompress your file'));
$config['filemanager']['message'] = ui_print_error_message(__('It was impossible to uncompress your file'));
} else {
unlink($_FILES['file']['tmp_name']);
ui_print_success_message(__('Upload correct'));
$config['filemanager']['message'] = ui_print_success_message(__('Upload correct'));
$config['filemanager']['correct_upload_file'] = 1;
}
}
@ -234,7 +246,7 @@ if (isset($_SERVER['CONTENT_LENGTH']) === true) {
}
function create_text_file($default_real_directory)
function create_text_file($default_real_directory, $destination_directory)
{
global $config;
@ -253,7 +265,7 @@ function create_text_file($default_real_directory)
$filename = filemanager_safe_directory((string) get_parameter('name_file'));
if (empty($filename) === false) {
$real_directory = filemanager_safe_directory((string) get_parameter('real_directory'));
$real_directory = filemanager_safe_directory($destination_directory);
$umask = (string) get_parameter('umask');
if (strpos($real_directory, $default_real_directory) !== 0) {
@ -980,6 +992,15 @@ function filemanager_safe_directory(
// Safe output.
$directory = io_safe_output($directory);
$forbiddenAttempting = false;
// Banned directories.
$bannedDirectory = [
'include',
'godmode',
'operation',
'reporting',
'general',
ENTERPRISE_DIR,
];
if ((bool) preg_match('/(\.){2}/', $directory) !== false) {
$directory = preg_replace('/(\.){2}/', '', (empty($safedDirectory) === true) ? $directory : $safedDirectory);
@ -991,6 +1012,12 @@ function filemanager_safe_directory(
$forbiddenAttempting = true;
}
if (in_array($directory, $bannedDirectory) === true) {
// Setted images for default (usually in file manager).
$directory = (empty($safedDirectory) === false) ? $safedDirectory : 'images';
$forbiddenAttempting = true;
}
if ($forbiddenAttempting === true) {
db_pandora_audit('File manager', 'Attempting to use a forbidden file or directory name');
}

View File

@ -78,17 +78,6 @@ if (empty($directory) === true) {
$directory = filemanager_safe_directory($directory, $fallback_directory);
}
$banned_directories['include'] = true;
$banned_directories['godmode'] = true;
$banned_directories['operation'] = true;
$banned_directories['reporting'] = true;
$banned_directories['general'] = true;
$banned_directories[ENTERPRISE_DIR] = true;
if (isset($banned_directories[$directory]) === true) {
$directory = $fallback_directory;
}
$real_directory = realpath($config['homedir'].'/'.$directory);
ui_print_info_message(__('MIB files will be installed on the system. Please note that a MIB may depend on other MIB. To customize trap definitions use the SNMP trap editor.'));
@ -99,11 +88,11 @@ $create_text_file = (bool) get_parameter('create_text_file');
$default_real_directory = realpath($config['homedir'].'/'.$fallback_directory);
if ($upload_file_or_zip === true) {
upload_file($upload_file_or_zip, $default_real_directory);
upload_file($upload_file_or_zip, $default_real_directory, $real_directory);
}
if ($create_text_file === true) {
create_text_file($default_real_directory);
create_text_file($default_real_directory, $real_directory);
}
filemanager_file_explorer(